Context
Descoped from CannObserv/archiver#44 (now closed). The Archiver side shipped in archiver v3.6.0 (2026-05-29):
- `GET /api/v1/info-items/{id}?include_deactivated=true` returns deactivated `InfoItemSource` bindings (previous primaries) annotated with `is_active: false` and `deactivated_at`.
- New `info_item_primary_changed` bus event on `info.changes` carries `old_info_source_id` / `new_info_source_id` whenever a NULL-role binding is created. `old_info_source_id` is `null` on first assignment.
- SDK 3.3.0: `get_info_item(include_deactivated=True)`, `deactivate_info_source_binding(info_item_id, info_source_id)`.
The gap
`WatchedInfoItem` currently models one URL per item (the current primary). After URL succession, Watcher has no mechanism to continue watching the previous primary URL — exactly the scenario where an unexpected content change on a retired-but-still-accessible URL should be surfaced.
Work
What does NOT change
- Archiver DB constraint (one active primary per InfoItem) is unchanged.
- Fetch group invariant (one URL fetched per tick for the current primary) remains valid.
- Fragment bindings (`cross_check`, `sub_aspect`) do not auto-transfer when a primary is replaced — they remain anchored to the InfoSource they were bound against.
References
Context
Descoped from CannObserv/archiver#44 (now closed). The Archiver side shipped in archiver v3.6.0 (2026-05-29):
The gap
`WatchedInfoItem` currently models one URL per item (the current primary). After URL succession, Watcher has no mechanism to continue watching the previous primary URL — exactly the scenario where an unexpected content change on a retired-but-still-accessible URL should be surfaced.
Work
What does NOT change
References