You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs/LEGAL.md §6a safeguard 5 claims the hard-coded rate limit
prevents bulk-scraping patterns and cannot be overridden by configuration
It bounds 5 requests per second. It does not bound how many times the same request is made.
An agent that retries 500 failed DOIs ten times each emits 5,000 requests while never once exceeding 5/sec. That is a bulk pattern, produced entirely within the safeguard, by a caller behaving exactly as LLM callers behave when a failure looks retryable. The sibling issue on disposition (#506) covers why so many of them look retryable; this issue is about the fact that even a correct disposition is only advice, and advice is not a safeguard.
This is the same class as #493: a NORMATIVE claim that is broader than the mechanism behind it.
doiget is the only tool that can close this
Every fetch is already recorded. docs/PROVENANCE_LOG.md / ADR-0006 define a fail-closed, hash-chained JSON Lines log, and a fetch that cannot be logged does not proceed. So the data needed to answer "has this exact request already been made, and what happened?" is on disk before the network is touched.
That is worth stating plainly because it is not a portable idea: a fetcher that does not record its attempts cannot implement this at all. It turns safeguard 5 from "bounds rate" into "bounds rate and persistence", which is a materially stronger claim and one that can be demonstrated rather than asserted.
Proposed shape
Before the network leg, consult the provenance log for prior attempts on the same (ref, source) within a short window. Then:
prior outcome was terminal → do not re-fetch. Return the prior outcome, marked as replayed, with the original error and its denial_context.
prior outcome was needs_config → do not re-fetch, and return the remediation again. Nothing has changed unless the config changed, and whether it changed is checkable.
prior outcome was retry_after → enforce the wait rather than refuse. If the caller returns early, sleep the remainder or return RATE_LIMITED with the true remaining time.
Depends on #506: "the prior outcome was terminal" has to be a fact the code carries before it can be acted on.
Design constraints worth deciding up front
Staleness. A negative result is not permanent in the real world — a paper can become OA, an embargo can lift, a config can change. The window must be short (minutes, not days), and there must be an explicit way to force a real fetch. The point is to stop a loop inside one agent session, not to cache a "no" forever.
Config changes must invalidate. A needs_config replay is wrong the moment the user actually applies the remediation. Keying the decision on the capability profile / config fingerprint alongside the ref would handle it.
Do not make it configurable off. Safeguard 5's stated property is that it cannot be overridden by configuration. Anything added under that heading inherits the constraint, or the heading has to change.
docs/LEGAL.md§6a safeguard 5 claims the hard-coded rate limitIt bounds 5 requests per second. It does not bound how many times the same request is made.
An agent that retries 500 failed DOIs ten times each emits 5,000 requests while never once exceeding 5/sec. That is a bulk pattern, produced entirely within the safeguard, by a caller behaving exactly as LLM callers behave when a failure looks retryable. The sibling issue on disposition (#506) covers why so many of them look retryable; this issue is about the fact that even a correct disposition is only advice, and advice is not a safeguard.
This is the same class as #493: a NORMATIVE claim that is broader than the mechanism behind it.
doiget is the only tool that can close this
Every fetch is already recorded.
docs/PROVENANCE_LOG.md/ ADR-0006 define a fail-closed, hash-chained JSON Lines log, and a fetch that cannot be logged does not proceed. So the data needed to answer "has this exact request already been made, and what happened?" is on disk before the network is touched.That is worth stating plainly because it is not a portable idea: a fetcher that does not record its attempts cannot implement this at all. It turns safeguard 5 from "bounds rate" into "bounds rate and persistence", which is a materially stronger claim and one that can be demonstrated rather than asserted.
Proposed shape
Before the network leg, consult the provenance log for prior attempts on the same
(ref, source)within a short window. Then:terminal→ do not re-fetch. Return the prior outcome, marked as replayed, with the original error and itsdenial_context.needs_config→ do not re-fetch, and return theremediationagain. Nothing has changed unless the config changed, and whether it changed is checkable.retry_after→ enforce the wait rather than refuse. If the caller returns early, sleep the remainder or returnRATE_LIMITEDwith the true remaining time.Depends on #506: "the prior outcome was terminal" has to be a fact the code carries before it can be acted on.
Design constraints worth deciding up front
needs_configreplay is wrong the moment the user actually applies the remediation. Keying the decision on the capability profile / config fingerprint alongside the ref would handle it.config pathandconfig showprint nothing and exit 0 when not on a TTY — the #219/#220 deadlock, still open for config #476,[store] rootin config.toml is ignored (env and flag work) — while[network]from the same file is honoured, andconfig init/doctorboth recommend the setting that does nothing #441, bug(tdm): the Tier-3 chain is skipped whenever Crossref answers, so a TDM source can never close the fetch gap it was added for #458, text: silent empty output (exit 0, 0 bytes) when ar5iv text is unavailable — callers misdiagnose as a wrong DOI #302). The envelope should say the answer was replayed and why, and the CLI should say so too.Notes
docs/LEGAL.mdisStatus: NORMATIVEand safeguard 5's wording would be amended by this, so ADR-0014 requires an ADR. LEGAL.md under-declares the default binary's network surface and does not know tdm-ieee exists #494 is already correcting other parts of §6a — this should land after it rather than conflict with it.Refs #506, #493, #494, ADR-0006, ADR-0014.