Skip to content

Supersede terms re-submitted under their current thing URI (fixes #10) - #11

Merged
GertjanBisschop merged 1 commit into
eu-parc:mainfrom
knowledgepixels:fix/supersede-current-id
Jul 9, 2026
Merged

Supersede terms re-submitted under their current thing URI (fixes #10)#11
GertjanBisschop merged 1 commit into
eu-parc:mainfrom
knowledgepixels:fix/supersede-current-id

Conversation

@tkuhn

@tkuhn tkuhn commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #10.

Problem

publish_incremental keyed its new/unchanged/drifted decision on the id-map's old_id alone. As @GertjanBisschop reports in #10, re-submitting an existing term under its current identifier (its trusty thing URI, …/biochementities/RA…) therefore missed the lookup and fell into the "new" branch: a duplicate term was minted with a fresh identity and no npx:supersedes link. A supersede only happened when the term was submitted under its old temporary id.

While fixing this, a latent companion bug surfaced on the supersede path: resolve_references drops namespaced object URIs it can't find in its thing_uris map as "dangling" — and that map was keyed by old ids only. So a re-submitted assertion whose cross-references used thing URIs would have those links silently dropped from the superseding nanopub.

Fix

  • IdMap.resolve(term_id) — returns the entry whose old_id or thing_uri matches (thing URIs are unique across entries, so this is well-defined); None means genuinely new.
  • IdMap.resolution_map — superset of thing_uri_map in which each thing URI also maps to itself; used on the supersede path so references in either identifier form resolve instead of being dropped.
  • publish_incremental — uses resolve() for the three-way decision and canonicalizes all bookkeeping (backfill, skip list, superseded id-map row, MintedSupersession.term_id) to entry.old_id. Whichever form was submitted, a term keeps exactly one id-map row keyed by its original old id — stable redirect table, linear supersedes chain. A match via thing URI is logged.

Tests

Five new tests: the exact #10 scenario both ways (resubmit under thing URI, unchanged → skipped / drifted → superseded with no duplicate mint and a single id-map row), thing-URI reference preservation on supersede, and resolve/resolution_map units. Full suite: 127 passed.

Deliberately out of scope

The drift fingerprint is computed over the assertion's references as given. A source that switches its cross-references from old ids to thing URIs will fingerprint differently and trigger one semantically-empty supersede (a harmless one-time re-issue, not an identity fork). Normalizing references before fingerprinting changes the fingerprint domain and needs an FP_SCHEME bump plus a baseline-migration story — better handled as a separate issue if it matters in practice.

🤖 Generated with Claude Code

Fixes eu-parc#10: publish_incremental keyed its new/unchanged/
drifted decision on the id-map's old_id alone, so re-submitting a term
under its current trusty thing URI minted a duplicate term (new identity,
no npx:supersedes) instead of superseding. IdMap.resolve() now matches
either identifier, and all bookkeeping is canonicalized to entry.old_id
so a term keeps a single id-map row and a linear supersedes chain
whichever form was submitted.

Also fixes a latent companion bug on the supersede path: references
given as thing URIs were dropped as dangling by resolve_references
(its map was keyed by old_id only); IdMap.resolution_map now accepts
both identifier forms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@GertjanBisschop
GertjanBisschop merged commit e347e88 into eu-parc:main Jul 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

supersedes condition publish-mint

2 participants