Invalidate the composed index when a registration changes (REUSE-WP-0020-T09)
Enabling a federation source left /v1/federated serving its cached compose and reporting stale: false while doing it, so a repo could be correctly registered and silently invisible for as long as its cached index survived. That is how evidence-binder stayed missing after re-enabling until a manual POST /v1/federated/compose was issued. Registration writes now mark the composed index stale, and a plain GET recomposes when the flag is set. Clearing it there is not a silent clear: that pass really did refetch. A PATCH touching only a description does not invalidate anything. This changes a contract documented in specs/FederationHubAPI.md, so the staleness section is rewritten rather than left to drift, including the two triggers that now set the flag. The first two tests written for this were worthless -- they passed with the fix removed, because a newly registered repo has no cache entry and gets fetched regardless. The real failure needs a populated cache holding stale content inside its 24h TTL. test_re_enabled_source_refetches_a_stale_cache models that and fails on pre-fix code; verified by reverting the mark_stale calls. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
d1de320743
commit
6cbc862371
5 changed files with 235 additions and 26 deletions
|
|
@ -199,14 +199,28 @@ composed_at: "2026-07-07T16:22:09+00:00" # REUSE-WP-0019-T02
|
|||
stale: false # REUSE-WP-0019-T02
|
||||
```
|
||||
|
||||
`composed_at`/`stale` (added REUSE-WP-0019-T02) track *forced* recomposes
|
||||
only (`refresh=true`, the webhook, or the scheduled fallback) — a plain
|
||||
`GET` still serves current best-effort data (per-source `cache_ttl_seconds`
|
||||
still applies) but never silently clears a staleness signal nothing
|
||||
actually refreshed. `composed_at` is `null` until the first forced
|
||||
recompose since the hub process's SQLite DB was created. `stale: true`
|
||||
means a `registry/indexes/` change was pushed (via webhook) since the last
|
||||
forced recompose completed.
|
||||
`composed_at`/`stale` (added REUSE-WP-0019-T02) track recomposes that
|
||||
actually refetched — `refresh=true`, the webhook, the scheduled fallback, or
|
||||
a plain `GET` that found the index marked stale. A plain `GET` on a
|
||||
non-stale index still serves current best-effort data (per-source
|
||||
`cache_ttl_seconds` still applies) and never clears a staleness signal
|
||||
nothing acted on. `composed_at` is `null` until the first such recompose
|
||||
since the hub process's SQLite DB was created.
|
||||
|
||||
`stale: true` means the composed index no longer reflects its inputs, set by
|
||||
either of two triggers:
|
||||
|
||||
- a `registry/indexes/` change pushed by a member repo (via webhook), or
|
||||
- a **registration change through this API** (REUSE-WP-0020-T09) — `POST
|
||||
/v1/repos`, `DELETE /v1/repos/{repo}`, or a `PATCH /v1/repos/{repo}` that
|
||||
touches `enabled`, `url`, `index`, `required`, or `domain`.
|
||||
|
||||
The second trigger closes a silent failure: before it, enabling a source left
|
||||
the composed index untouched and still reporting `stale: false`, so a repo
|
||||
could be correctly registered and yet invisible in `/v1/federated` for as long
|
||||
as its cached index survived. The next `GET` now recomposes and clears the
|
||||
flag — which is not a silent clear, because that pass really did refetch. A
|
||||
recompose that *fails* leaves `stale: true` set.
|
||||
|
||||
Query parameters:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue