Skip to content

fix(spaces): honor owl:sameAs space aliases in /repo/spaces materializer (#113)#115

Merged
tkuhn merged 1 commit into
mainfrom
fix/issue-113-sameas-alias
May 27, 2026
Merged

fix(spaces): honor owl:sameAs space aliases in /repo/spaces materializer (#113)#115
tkuhn merged 1 commit into
mainfrom
fix/issue-113-sameas-alias

Conversation

@tkuhn
Copy link
Copy Markdown
Contributor

@tkuhn tkuhn commented May 27, 2026

Fixes #113.

Problem

A role/member nanopub attached to a space's owl:sameAs alias IRI is silently dropped by the /repo/spaces materializer. The materializer keys assignments on the alias IRI, but admins live only on the canonical IRI, so the attachment never validates and the role — with all its members — vanishes from the materialized state with no error.

The subtle part: the alias (e.g. beetles) typically has no live admin closure — its gen:Space definition was superseded when the canonical space (carabid-beetles) was created. So a sub-space-style "publisher must be admin of both sides" gate would not fix this (there are no alias admins to match). Authority has to flow canonical→alias.

Approach — honor owl:sameAs via authority-expansion

  • Extraction — embedded <canonical> owl:sameAs <alias> triples in gen:Space nanopubs are emitted as npa:SpaceAliasDeclaration (with provenance). Self-aliases rejected.

  • Materialization — a new aliasAdmitUpdate tier (runs after the admin closure, before attachment; also in the late-arrival sweep) validates an alias edge iff both:

    1. the declaration's publisher is a validated admin of the canonical space, and
    2. anti-hijack: admins(alias) ⊆ admins(canonical) — the defunct-alias case () passes; <evil> owl:sameAs <activeSpace> is rejected because the active space has admins not in evil's set.

    It emits <alias> npa:sameAsSpace <canonical> into the state graph.

  • Authority lookupsattachmentValidationUpdate, PUBLISHER_IS_ADMIN, and publisherIsTieredRole gain a UNION accepting admin of a canonical the space is a sameAsSpace alias of.

  • Invalidation — alias-declaration invalidation is structural (flips needsFullRebuild); the sameAsSpace edge is sticky until the next periodic rebuild (same policy as sub-space declarations).

Keying is authority-expansion, no row rewrite: assignments stay keyed on the alias IRI (so ?space=<alias> queries work directly); the canonical view resolves via the alt-ids Nanodash forwards from the space's owl:sameAs. Single alias hop; standalone owl:sameAs nanopubs out of scope.

Design write-up: new "Space aliases (owl:sameAs)" section in doc/design-space-repositories.md.

Verification

  • Full unit suite green (224 tests); 9 new tests (extraction emit/self-alias/subject-binding; alias admit gate + anti-hijack; alias-aware UNIONs; alias invalidation).
  • All affected/new SPARQL UPDATE templates parse through RDF4J's SPARQLParser.
  • Live, on a fresh full local sync:
    • get-space-roles?space=carabid-beetles&space=beetles now returns the member role (was 0 rows).
    • <beetles> npa:sameAsSpace <carabid-beetles> materialized; the 4 P463 members admitted.
    • Total RoleAssignments in current state: 138 → 139 — exactly the single genuine recovery Role assignments attached to a space's owl:sameAs alias are not materialized in /repo/spaces #113 predicted, no over-admission.
    • 62 extracted alias declarations → 39 validated edges; rejections are legitimate (canonical has no admin closure, or anti-hijack triggered).

🤖 Generated with Claude Code

…zer (#113)

A role/member attached to a space's owl:sameAs alias was silently dropped. The
materializer keys assignments on the alias IRI, which has no admin closure (its
definition was superseded when the canonical space was created), so the
attachment never validated — admins live only on the canonical IRI. A
sub-space-style "admin of both sides" gate would not fix this, since the alias
has no admins; authority must flow canonical->alias.

Honor owl:sameAs via authority-expansion (no row rewrite):

- Extract embedded owl:sameAs from gen:Space nanopubs as npa:SpaceAliasDeclaration.
- New aliasAdmitUpdate tier validates an alias edge iff the declaration's
  publisher is a validated admin of the canonical space AND
  admins(alias) is a subset of admins(canonical) (anti-hijack: blocks
  <evil> owl:sameAs <activeSpace>); emits <alias> npa:sameAsSpace <canonical>.
- Admin-authority lookups (attachment, PUBLISHER_IS_ADMIN, publisherIsTieredRole)
  gain a UNION accepting admin of a canonical the space is an alias of.
- Alias-declaration invalidation is structural (flips needsFullRebuild).

Assignments stay keyed on the alias IRI; the canonical view resolves via the
alt-ids Nanodash forwards from the space's owl:sameAs.

Verified on a local full sync: get-space-roles returns the previously-dropped
member role for carabid-beetles/beetles, the 4 members are admitted, and total
RoleAssignments go 138->139 (the single predicted recovery, no over-admission).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tkuhn tkuhn merged commit 687c19f into main May 27, 2026
8 checks passed
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 1.14.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Role assignments attached to a space's owl:sameAs alias are not materialized in /repo/spaces

1 participant