Repository navigation
Promotion: next → main for 0.9.0 - #649
Merged
Merged
Conversation
The four files that record the last published stable, bumped together as CONTRIBUTING describes. They cannot be written before the release exists: the formula pins the binaries by sha256, and .mcp.json pins the npm version the plugin runs. Formula regenerated from the v0.8.13 release's own .sha256 assets, not by hand. Verified: update-homebrew-formula.test.sh passes, the release-sync posture check reports all four agreeing on 0.8.13 with a CHANGELOG section to match, and [email protected] is live on npm so the pin is not a 404. Signed-off-by: Sota Shimozono <[email protected]>
…ctory with 6 updates Bumps the actions-minor-and-patch group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.9` | `4.38.1` | | [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.37.9` | `4.38.1` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.9` | `4.38.1` | | [taiki-e/install-action](https://github.com/taiki-e/install-action) | `2.87.0` | `2.87.15` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `7.0.0` | `7.1.1` | | [crate-ci/typos](https://github.com/crate-ci/typos) | `1.50.0` | `1.50.2` | Updates `github/codeql-action/init` from 4.37.9 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...1c5b675) Updates `github/codeql-action/autobuild` from 4.37.9 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...1c5b675) Updates `github/codeql-action/analyze` from 4.37.9 to 4.38.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@cdf488f...1c5b675) Updates `taiki-e/install-action` from 2.87.0 to 2.87.15 - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](taiki-e/install-action@37f7c57...4076c08) Updates `codecov/codecov-action` from 7.0.0 to 7.1.1 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](codecov/codecov-action@fb8b358...303a32d) Updates `crate-ci/typos` from 1.50.0 to 1.50.2 - [Release notes](https://github.com/crate-ci/typos/releases) - [Changelog](https://github.com/crate-ci/typos/blob/main/CHANGELOG.md) - [Commits](crate-ci/typos@4d9c206...512fc24) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor-and-patch - dependency-name: github/codeql-action/autobuild dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor-and-patch - dependency-name: github/codeql-action/analyze dependency-version: 4.38.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor-and-patch - dependency-name: taiki-e/install-action dependency-version: 2.87.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-minor-and-patch - dependency-name: codecov/codecov-action dependency-version: 7.1.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor-and-patch - dependency-name: crate-ci/typos dependency-version: 1.50.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-minor-and-patch ... Signed-off-by: dependabot[bot] <[email protected]>
…ctory with 9 updates Bumps the cargo-minor-and-patch group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [clap](https://github.com/clap-rs/clap) | `4.6.6` | `4.6.7` | | [thiserror](https://github.com/dtolnay/thiserror) | `2.0.20` | `2.0.21` | | [reqwest](https://github.com/seanmonstar/reqwest) | `0.13.4` | `0.13.5` | | [rustls](https://github.com/rustls/rustls) | `0.23.43` | `0.23.45` | | [camino](https://github.com/camino-rs/camino) | `1.2.5` | `1.2.6` | | [serde](https://github.com/serde-rs/serde) | `1.0.228` | `1.0.229` | | [uuid](https://github.com/uuid-rs/uuid) | `1.26.0` | `1.26.1` | | [futures-util](https://github.com/rust-lang/futures-rs) | `0.3.32` | `0.3.34` | | [rmcp](https://github.com/modelcontextprotocol/rust-sdk) | `3.1.4` | `3.4.1` | Updates `clap` from 4.6.6 to 4.6.7 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/main/CHANGELOG.md) - [Commits](clap-rs/clap@clap_complete-v4.6.6...clap_complete-v4.6.7) Updates `thiserror` from 2.0.20 to 2.0.21 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](dtolnay/thiserror@2.0.20...2.0.21) Updates `reqwest` from 0.13.4 to 0.13.5 - [Release notes](https://github.com/seanmonstar/reqwest/releases) - [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md) - [Commits](seanmonstar/reqwest@v0.13.4...v0.13.5) Updates `rustls` from 0.23.43 to 0.23.45 - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](rustls/rustls@v/0.23.43...v/0.23.45) Updates `camino` from 1.2.5 to 1.2.6 - [Release notes](https://github.com/camino-rs/camino/releases) - [Changelog](https://github.com/camino-rs/camino/blob/main/CHANGELOG.md) - [Commits](camino-rs/camino@camino-1.2.5...camino-1.2.6) Updates `serde` from 1.0.228 to 1.0.229 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](serde-rs/serde@v1.0.228...v1.0.229) Updates `uuid` from 1.26.0 to 1.26.1 - [Release notes](https://github.com/uuid-rs/uuid/releases) - [Commits](uuid-rs/uuid@v1.26.0...v1.26.1) Updates `futures-util` from 0.3.32 to 0.3.34 - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/main/CHANGELOG.md) - [Commits](rust-lang/futures-rs@0.3.32...0.3.34) Updates `rmcp` from 3.1.4 to 3.4.1 - [Release notes](https://github.com/modelcontextprotocol/rust-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/rust-sdk/blob/main/release-plz.toml) - [Commits](modelcontextprotocol/rust-sdk@rmcp-v3.1.4...rmcp-v3.4.1) --- updated-dependencies: - dependency-name: clap dependency-version: 4.6.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: thiserror dependency-version: 2.0.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: reqwest dependency-version: 0.13.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: rustls dependency-version: 0.23.45 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: camino dependency-version: 1.2.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: serde dependency-version: 1.0.229 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: uuid dependency-version: 1.26.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: futures-util dependency-version: 0.3.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: rmcp dependency-version: 3.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo-minor-and-patch ... Signed-off-by: dependabot[bot] <[email protected]>
chore: back-merge main into next after 0.8.13
chore(release): tracking files for 0.8.13
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
…ctions-minor-and-patch-7e761db225' into chore/pending-dependency-bumps-0.8.14
…r-and-patch-af8bd5da41' into chore/pending-dependency-bumps-0.8.14
…p to 0.8.14-beta.2 rmcp 3.4 deprecates the ServerInfo alias in favour of ServerConfig (same type, InitializeResult); under -D warnings that failed every clippy, test, rustdoc and msrv job on #602. Raise the rmcp floor to 3.4, where the new name first exists. supply-chain: bump the existing exemptions to the new versions and add base64 0.23.1 (new, via rmcp) and serde/serde_core/serde_derive 1.0.229 (previously covered by imported audits only). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
chore: retarget next to 0.8.14-beta.1 after the 0.8.13 promotion
…-0.8.14 chore(deps): the two pending Dependabot bumps, with the rmcp ServerConfig migration
…resolve `codes.sota-shimozono.com` resolves to `sinkhole.paloaltonetworks.com` (198.135.184.22) and answers nothing — not a 404, no connection at all. The documentation is served from GitHub Pages at `qatlashub.github.io`, and has been all along. Both targets resolve: `qatlashub.github.io/doiget/` and `/doiget/dev/` return 200. Tracked org-wide in QAtlasHub/.github#23. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: sotashimozono <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
…holed-host docs: the README's documentation links point at a host that does not resolve
This cycle adds new subcommands (add, missing, coverage, sources), which under the 0.x policy warrants a minor step (ADR-0033 D4 precedent). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
…ored (#613) An exported-but-empty DOIGET_STORE_ROOT (export X=${X:-} in a script) is already treated as unset since #369, on both the CLI and MCP resolvers. What was left: the CLI resolver had no test pinning that, and config doctor reported the fallback exactly as if nothing had been set, so a script author could not tell their export had been dropped. Extract usable_store_root_env() in the CLI resolver, test it, and have doctor print a note naming the ignored value. Closes #613 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
chore: retarget next to 0.9.0-beta.1
- --store-root rejects whitespace-only and ${...} values at parse time,
as it already rejected "". The resolver treats them as unset, so a
typed flag was silently dropped for the cwd default -- and because the
flag is applied by writing DOIGET_STORE_ROOT, doctor's note blamed the
environment for the flag's value. Rejected here, an ignored store root
can only have come from the environment, which is what the note says.
- config show --mode json carries store_root_env_ignored, so a script
can tell an export that was dropped from a variable never set.
- Tests: the resolver itself (not only the helper) under "", " " and
a placeholder; config doctor e2e with and without the empty export;
--store-root rejecting both new shapes.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Signed-off-by: sotashimozono <[email protected]>
…e author wrote (#609) AIP and others deposit inline JATS / MathML onto lines of their own, so Crossref serves 'the P\n <scp>y</scp>\n SCF program package'. The render-time tag scrubber dropped the tags but kept the indentation, and BibTeX printed 'P y SCF'. Stripping tags is not enough: the pretty-printer's line-break runs say nothing about whether the author wrote a space there (P<scp>y</scp>SCF is one word, 'in <i>γ</i>-InSe' is two). New doiget_core::markup:: plain_title decides each run from its neighbours -- a word inside the element is spaced from a neighbouring word, a symbol is joined unless the neighbour is a lower-case word, sentence punctuation or an operator -- pinned against 14 real 10.1063 deposits. It also decodes entities (including Crossref's double-escaped &gt;), and replaces the old scrubber, which deleted everything between any '<' and the next '>' (so 'a < b and c > d' lost ' b and c '). Applied when metadata is built, so the store holds the clean title, and again at BibTeX / CSL render, so entries already stored come out clean. doiget lint gains a title_markup warning for .bib files pasted from an older cite. $...$ is untouched. A re-fetch also replaces a title / venue stored with raw markup, but only with its own cleaned form: STORE.md §6 still preserves any value that differs in content. Closes #609 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix(config): config doctor says when DOIGET_STORE_ROOT is set but ignored (#613)
- markup::tag_len took '<' + a letter up to the NEXT '>' anywhere as a tag, so 'T<Tc in samples with applied field H>Hc2' became 'THc2' -- and since #609 cleans titles at store time, that corrupted persisted metadata for titles with no markup at all. A tag now has to parse: a name, then only name="value" attributes before '>'; an opening tag must also be a known inline element, namespaced (mml:, jats:), or have its </name later. 'x<y>z' and 'a<b and c>d' stay text. - The store merge exception applied whenever incoming == plain_title( existing); it now also requires existing to carry markup, so the cleaning rule can never be why a markup-free stored title is replaced. - Tests: the reviewer's inequality titles through plain_title, BibTeX and the merge; CSL title/container cleaning (was untested); the venue half of the merge's preserve branch; and a store-level test that a pretty-printed Crossref title is written to the TOML as plain text, which render-time cleaning could not mask. - is_cleaned_form had been inserted between merge_metadata's doc comment and its fn, so rustdoc gave that comment to the wrong function. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
…bled source, flag the rest (#608) Some Crossref records carry U+FFFD where the publisher's deposit lost its umlauts ('Zeitschrift f\u{FFFD}r Physik'). cite passed them through silently; the entry compiles, so the damage showed only in the rendered bibliography. New doiget_core::metadata_quality: - detects U+FFFD in title, authors, venue, publisher and abstract; - repairs title and venue from Semantic Scholar / OpenAlex, and ONLY when that source is already enabled (DOIGET_ENABLE_S2 / DOIGET_ENABLE_OPENALEX) -- no new network by default; - accepts a candidate only when it matches with each U+FFFD standing for one or two characters and every other character equal. OpenAlex ingests Crossref and carries the same loss, and its venue for these papers is the journal's later name ('The European Physical Journal A'); the guard refuses both rather than swapping in a different fact. Measured 2026-09-29: S2 has 'Näherungsmethode zur Lösung...' for 10.1007/BF01340294; - records repairs as [doiget].repaired_fields = { title = "semantic_scholar" }. Surfaces: cite prints a note per repair and a warning naming what is left (and the switch that would let it try); fetch_paper (CLI and MCP) repairs before the store write and the MCP envelope gains metadata_quality ['replacement_char:venue'] and repaired_fields; the metadata-only store path repairs too; verify adds metadata_quality to a valid record (informational, never an exit-code failure); lint gains a replacement_char warning for .bib files checked offline. Closes #608 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix(cite): reduce pretty-printed JATS markup in titles to the text the author wrote (#609)
- A later repair never reached the store. Fetched once with no repair source, the damaged title was stored; fetched again with S2 enabled, the repair succeeded in memory and merge_metadata kept the stored value (STORE.md 6) -- while repaired_fields, in the doiget-owned table, said it had been applied. is_cleaned_form now also accepts an incoming value that restores() the stored one; a different fact is still preserved. - metadata_only_to_store repaired the file but told its caller nothing: its outcome carries the raw resolver payload and the only signal was a tracing warning on stderr, which the MCP stdio transport never shows an agent. MetadataOnlyOutcome gains metadata_quality / repaired_fields (serde-defaulted, so cached outcomes still read) and the MCP metadata-only envelope emits them; docs/MCP_TOOLS.md 11 says so. - Tests for the surfaces that had none: the MCP fetch envelope (keys always present; flagged for a damaged title), the metadata-only store path, and through the real binary the fetch warning and verify's metadata_quality on a valid row. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
Store does synchronous filesystem I/O -- a write can poll the advisory lock for up to 5 s in 50 ms std::thread::sleep steps, then fsync, which on a Dropbox / OneDrive / SMB store root costs hundreds of milliseconds uncontended. Ten call sites made those calls straight from an async fn (the orchestrator's store write and nine MCP handlers), each holding a tokio worker for the whole duration and delaying the rate limiter's timers and every other in-flight tool call on it. New doiget_core::store::blocking_section runs the call under tokio::task::block_in_place on a multi-thread runtime (doiget serve, the CLI), which hands the worker's other tasks to another thread first, and inline elsewhere (no runtime, or current-thread, where block_in_place would panic). block_in_place rather than spawn_blocking because the orchestrator holds the store as &dyn Store: moving it into a 'static closure would change fetch_paper's public signature, the same cost the issue ruled out for an async trait. Tests: on a one-worker runtime a 300 ms blocking call inside the helper lets a ticking task run (>= 20 ticks) while the same call made directly starves it (<= 3, the control that proves the test can fail); and a source scan in each crate fails if any store.read / write / write_user_authored / list_recent / search in non-test code is not wrapped. docs/STORE.md 7a states the convention the trait cannot. Closes #590 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
feat(cite): detect U+FFFD in resolver metadata, repair it from an enabled source, flag the rest (#608)
- Async CLI code still called the store directly: cite's store fallback (bib_from_store, reached from the async run after a failed resolve) and search's local path (run_local, from the async search::run). Both now go through blocking_section. - The source scans covered only orchestrator.rs and the MCP server, and matched whitespace-collapsed text, so a method chain split across lines (store\n .read() -- exactly how both CLI calls were written -- slipped through. They now strip whitespace entirely, include search_by_tag, and a new doiget-cli scan walks src/commands/ at test time, requiring every store call in a file with async code to be wrapped; a new command file is covered without being listed. - The responsiveness test asserted >= 20 ticks of a 5 ms ticker in 300 ms, above what Windows' ~15.6 ms timer granularity allows. Now >= 8 in 500 ms; the direct-blocking control (<= 3) is what gives the bound its meaning. - docs/STORE.md 7a says which call sites the scans cover. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
posture-lint forbids any `.matches(&` under crates/ so host adjudication can only go through permits(); the #590 source-scan tests counted substrings with str::matches(&format!(..)) and failed network-purity. The count is the same through match_indices(&*format!(..)). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
- metadata_quality: a public doc linked the private CHECKED_FIELDS (rustdoc -D warnings), and a test's deliberately damaged word read as a typo. Both were merged with #608. - site/content/ regenerated by scripts/sync_docs_to_site.sh for the docs/STORE.md and docs/MCP_TOOLS.md edits this stack made. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix(store): no Store call from async code holds a tokio worker (#590)
feat(fetch): INSPIRE-HEP as a preprint finder -- a closed DOI's arXiv id (#642, ADR-0064)
…644, ADR-0065) Part of #474, Gap 2. ADS holds a published DOI's arXiv id among a record's identifiers. - A fifth ADR-0062 finder, after INSPIRE and before the arXiv title search: /v1/search/query?q=doi:"<doi>"&fl=identifier&rows=1, reading the arXiv:<id> identifier only (found_by: ads). - The user's own token is the opt-in: DOIGET_ADS_TOKEN, sent only as Authorization: Bearer (preprint::logged_get_with -- header values go on the wire, never into the provenance row). No token, no request. - Within ADS's API terms: one lookup per closed DOI the user fetches, nothing stored or redistributed but the arXiv id for that fetch, no ADS full-text link followed, one request a second (5,000/day quota). - Primary sources quoted in #644 / ADR-0065, read from ADS's own published help and API sources (the web pages answer scripts 202 + empty body). - Docs: ADR-0065, LEGAL 2a (a-ii), SOURCES, PRIVACY, CAPABILITY, REDIRECT_ALLOWLIST 4; doiget_capability_profile lists ads. Closes #644 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
A 401/403 from ADS fell through to the next finder at info level, so a bad DOIGET_ADS_TOKEN failed silently. It is now a warn that says the token was refused and to check it; the fetch still continues with the next finder. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
…its OA PDFs, doiget blocked them (#646, ADR-0066) Part of #474, Gap 3. Six of eight J-STAGE DOIs sampled from J-STAGE's search API have an Unpaywall gold/bronze location on www.jstage.jst.go.jp, which J-STAGE serves to a scripted client -- and doiget refused every one: the host was on no allowlist. - www.jstage.jst.go.jp joins the opt-in trust_oa_registries set, not the default oa-publisher list. J-STAGE's terms permit private use and prohibit 'downloading a large amount of the Registered Data using mechanical or equivalent means'; the opt-in keeps a large batch the user's explicit choice, and CONFIG.md quotes the provision. - The set's rule is widened in the open (ADR-0066): registries and repositories, or a national open-access platform whose default is free access -- never a commercial publisher platform. Only locations Unpaywall reports as open are followed, and a restricted J-STAGE article's login page fails the %PDF- check. - Live row: 10.3327/jaesjb.66.4_185 fetches with trust_oa_registries. Closes #646 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
feat(fetch): NASA ADS as a preprint finder, on the user's own token (#644, ADR-0065)
… passes again Every PR this cycle has failed the advisory version-check at G5: the CHANGELOG had no section for 0.9.0 and no Unreleased one. This adds the Unreleased notes for betas 1-27 -- preprint discovery (#636, #640, #642, #644), PubMed ids (#500, #638), @software citations (#614), citekeys and short journals (#610, #611), missing / coverage / add (#607, #605, #606), repeat suppression (#507), install staleness (#594), binstall and Nix (#501), J-STAGE (#646), the live suite (#462), the fixes and the ADRs. scripts/release-version-gate.sh passes for v0.9.0-beta.27 locally. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
feat(allowlist): J-STAGE on trust_oa_registries (#646, ADR-0066)
docs(changelog): the 0.9.0 cycle under Unreleased
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…tags, a real MSRV job - doiget add stops on an unreadable store entry instead of writing over it; --from-dir and missing report one rather than dropping it silently. - add's exit codes follow docs/ERRORS.md §4 (they were swapped). - A GitHub tag with .., %, ?, # or whitespace is refused, from the URL and from the latest-release answer. - PdfLegStatus found_by is the FoundBy enum (with Unpaywall), not a String. - Declared MSRV 1.86 -> 1.88: rmcp 3.x already needed it, and the msrv job never saw it because rust-toolchain.toml overrode its toolchain. Both MSRV jobs now pin with RUSTUP_TOOLCHAIN. - preprint_allowlist's doc names each finder's own gate. - Tests: failed arXiv fallback keeps the block (404 / not a PDF), add's misuse / unreadable-entry / unresolved exits, coverage's error path. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix: #649 review round 1 -- add's store reads and exit codes, GitHub tags, a real MSRV job
…e tool/doc text - doiget batch: one lock per ref, so two copies of a DOI in the same concurrent window run in turn and the second is a repeat-suppression replay; the regression test fails without it. - doiget_paper_pdf_path's tool description lists origin and license. - ERRORS.md §4: exit 255 also caps add --from-dir --apply. - PROVENANCE_LOG.md: `source` is a string naming the source key, including the lookups this cycle added. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix: #649 review round 2 -- batch fetched a duplicate ref twice, stale tool/doc text
…BLIC_API scope - RepeatIndex sweeps entries past REPLAY_WINDOW when a new one lands, so doiget serve no longer keeps one per refused ref for its lifetime. - config_fingerprint's config.toml read is a blocking_section. - metadata_quality::restores refuses strings over 2,000 chars and lengths the U+FFFDs cannot explain, and reuses its two buffers. - PUBLIC_API.md §1a: orchestrator / preprint / pubmed / software / user_pdf / repeat / metadata_quality are public for the binaries, not semver-locked; CHANGELOG notes the found_by type change. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix: #649 review round 3 -- bounded repeat index and repair match, PUBLIC_API scope
Review findings: - cite / metadata_only never asked DataCite: metadata_only_doi went from Crossref straight to Unpaywall, so #614's Zenodo concept-DOI choice and --zenodo-version could not run. An enabled DataCite is asked when Crossref has no record; found by the new zenodo_cite_e2e test. - Types keep what they checked: PreprintDoiFallback.preprint_doi is a Doi, PubmedId holds pubmed::Digits, GithubRef's fields are private. - RepeatIndex sweeps only once the map has doubled (amortised O(1)). - add --from-dir names unreadable / non-UTF-8 directory entries. - Simplifications: GithubRef::repo_path, one landing_url in commands/mod, one has_pdf in add, missing::run split into row helpers. - Tests: Zenodo cite (concept by default, --zenodo-version, DataCite off is not asked), INSPIRE asked before ADS, trust_oa_registries alone admits J-STAGE offline. Cut: 0.9.0-beta.30 -> 0.9.0; [Unreleased] -> [0.9.0] - 2026-09-29. release-version-gate.sh v0.9.0: G1-G6 PASS, G7 skipped (no tag yet). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: sotashimozono <[email protected]>
fix: close the #649 review round 4, and cut 0.9.0
github-actions Bot
added a commit
that referenced
this pull request
Sep 29, 2026
Promotion: next → main for 0.9.0 ec4c5e9
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.
Promotion of everything on
nextsince 0.8.13, for review. Updated after four review rounds (#650, #651, #652, #653).This PR ships 0.9.0.
nextcarries the clean0.9.0, cut in #653. That turns## [Unreleased]into## [0.9.0] - 2026-09-29, andrelease-version-gate.sh v0.9.0passes G1–G6. Merging this makesmainthe 0.9.0 tree. The release itself is the signedv0.9.0tag pushed afterwards (ADR-0025). The tracking files (.claude-plugin/*.json,.mcp.json, and the Homebrew formula) follow once the release exists.The full list is in
CHANGELOG.md, under## [Unreleased](#648).What is in it
New commands and ref kinds
doiget missing(feat: a missing-PDF report for a bibliography file, with landing URLs and the path to save each download under #607),coverage/sources(feat: say which source (if any) can deliver a DOI's PDF before fetching — per-DOI coverage and a per-publisher source list #605) andadd(feat: add a hand-downloaded PDF to the store (doiget add), verified against the metadata, with DOI matching for a downloads folder #606).@softwarecitations for GitHub repos andCITATION.cff(feat(cite): cite software without a DOI (GitHub release / CITATION.cff) as @software #614, ADR-0058).Preprint discovery for closed DOIs (#636, #640, #642, #644; ADR-0062–0065)
Sources tried:
has-preprintpubsThe resulting PDF-leg statuses are
preprint_fallbackandpreprint_doi_fallback.Sources
trust_oa_registries(feat(allowlist): J-STAGE on trust_oa_registries -- Unpaywall already reports its OA PDFs, doiget blocks them (#474, Gap 3) #646, ADR-0066).landing_page_urlis an author-listing page, so the #461 fall-through has nothing to follow #547).Citation output
filefield pointing at the local PDF #610).shortjournal(feat(cite): ISO 4 journal abbreviations (--journal-abbrev iso4/ shortjournal) #611).Robustness
*_BASEoverride no longer resets the other sources (A single DOIGET_*_BASE override silently rebuilds the HTTP client from six source keys, dropping the rest #587).DOIGET_STORE_ROOTis treated as unset (bug(config): an empty DOIGET_STORE_ROOT is taken as the store root "" instead of unset #613).--refetch/forcefor intentional retries (The rate cap bounds throughput but not persistence, so a retrying agent can bulk-scrape without ever exceeding 5/sec #507, ADR-0057).Distribution
--features live-tests(test: an end-to-end use-case suite driven through the real entry points, because every "unreachable source" bug passed its unit tests #462).Decisions (ADR only)
Fixes from the four review rounds of this PR
fix: #649 review round 1 -- add's store reads and exit codes, GitHub tags, a real MSRV job #650 (round 1):
doiget addstops on an unreadable store entry instead of writing over it.add's exit codes now followdocs/ERRORS.md§4 (they had been swapped).found_byis typed asFoundBy.msrvjob had silently built on stable becauserust-toolchain.tomloverrode it. The job now pins 1.88 withRUSTUP_TOOLCHAIN.add/coverageerrors.fix: #649 review round 2 -- batch fetched a duplicate ref twice, stale tool/doc text #651 (round 2):
doiget batchfetched a DOI listed twice in the same concurrent window twice. Entries for the same ref now run in turn, so the second is a replay.paper_pdf_path, ERRORS exit 255, PROVENANCE_LOGsource.fix: #649 review round 3 -- bounded repeat index and repair match, PUBLIC_API scope #652 (round 3):
config.tomlread runs as a blocking section.PUBLIC_API.md§1a: the orchestrator and preprint types are public for the binaries and not semver-locked.fix: close the #649 review round 4, and cut 0.9.0 #653 (round 4, and the cut):
doiget citeof a DataCite DOI never asked DataCite, so the feat(cite): cite software without a DOI (GitHub release / CITATION.cff) as @software #614 Zenodo concept-DOI choice could not run. An enabled DataCite is now asked when Crossref has no record.preprint_doiis aDoi,PubmedIdholdsDigits, andGithubRef's fields are private.add --from-dirnames directory entries it could not read.trust_oa_registriesoffline.The security and LEGAL review found nothing.
Issues this closes on merge
Closes #500, closes #501, closes #507, closes #547, closes #587, closes #590, closes #594, closes #605, closes #606, closes #607, closes #608, closes #609, closes #610, closes #611, closes #613, closes #614, closes #636, closes #638, closes #640, closes #642, closes #644, closes #646, closes #462
Not closed by this PR:
Known gaps
nexthave no DCOSigned-off-by.🤖 Generated with Claude Code