Skip to content

Ref-update feeds over-drop distinct-owner remote rows because the wire slug is method-lossy #144

Description

@beardthelion

The cross-repo ref-update feeds (refUpdates GraphQL #112, GET /api/v1/events/ref-updates REST #114) drop a genuinely-remote row for anonymous callers when a local private repo shares both the repo name and the owner's trailing DID segment.

Root cause is the wire slug. publish_ref_update (crates/gitlawb-node/src/api/repos.rs) broadcasts the slug as {owner_did.split(':').last}/{name}, discarding the DID method/host. did:web:host:alice and did:gitlawb:alice both emit alice/widget. The feed gate (ref_update_row_visible) therefore cannot tell a remote public repo's row from a local private repo's row when their names and trailing segments collide, so it fails closed and drops the row.

This is fail-safe (it never serves a private repo's row) and negligible for full did:key ids, but for did:web / truncated handles it silently hides legitimate remote activity from the anonymous feed.

Reproduction (by execution)

Local private did:web:host:alice/widget; a remote row for the different owner did:gitlawb:alice, same name, is dropped for anon in both slug forms:

ref_update_row_visible(private did:web:host:alice/widget, anon, "did:gitlawb:alice/widget") -> false
ref_update_row_visible(private did:web:host:alice/widget, anon, "alice/widget")             -> false

Fix direction

Carry the full owner DID on the ref-update wire slug (and align the mirror-row bare-key storage) so the gate compares methods instead of a lossy trailing segment. The feed gate could then reuse the did:key-aware normalization used elsewhere (did_matches / DEDUP_CTE) without the fail-open the current short-slug scheme would cause. This is a cross-peer format change, so it needs a compatibility path for older peers.

Context: raised during review of #143 (P1). The gate there is intentionally strict to stay fail-closed given today's lossy slug; this issue tracks the format fix that removes the over-drop without reopening the #112 / #114 leak.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:nodegitlawb-node — the serving node and REST APIkind:bugDefect fix — wrong or unsafe behaviorsev:lowCosmetic, cleanup, or nice-to-havesubsystem:visibilityPath-scoped visibility and content withholding

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions