Skip to content

bug(resource): changing a specification's scope never reconciles the global discovery anchor #144

Description

@Soushi888

SoushAI analysis. Drafted by Soushi's AI assistant, reviewed and posted by @Soushi888.

What happens

ResourceSpecification.scope is mutable and decides one thing: whether the spec is linked from the resource_specifications anchor that get_all_resource_specifications reads. create_resource_specification honours that at creation. update_resource_specification accepts a new scope, writes it into the updated entry, and never touches the anchor.

Both directions are wrong, in opposite ways:

  • Project → Public: the author widens the scope and the spec stays absent from global discovery. It is public in the entry and invisible in the list.
  • Public → Project: the author narrows the scope and the spec stays listed globally. The narrowing has no effect on the only thing scope controls.
// dnas/nondominium/zomes/coordinator/zome_resource/src/resource_specification.rs
let updated_spec = ResourceSpecification { /* … */ scope: input.updated_specification.scope, /* … */ };
let updated_spec_hash = update_entry(input.previous_action_hash, &updated_spec)?;
create_link(input.original_action_hash, updated_spec_hash.clone(), LinkTypes::ResourceSpecificationUpdates, ())?;
// no AllResourceSpecifications create_link / delete_link anywhere in this function

What this does not affect

Not a capture-resistance hole. Nondominium and Public regimes are pinned to Public scope by check_scope_coherence, enforced on create and update in zome_resource integrity (PR #132, f57ef43), so a spec on an uncapturable NDO cannot be narrowed out of discovery by this path. The bug bites the regimes where scope is genuinely the author's choice.

Second-order: the anchor read is stale anyway

While fixing this, get_all_resource_specifications deserves a look. It resolves each anchor link to the original action hash and calls get() on it, which returns the original record, not the head of the update chain. So the global list renders pre-update content for every spec that has ever been edited, independently of scope. get_specifications_for_ndo has the same shape. get_latest_resource_specification exists and walks ResourceSpecificationUpdates; the list paths do not use it.

Fix

In update_resource_specification, compare original_spec.scope against the incoming scope and reconcile:

  • narrowing to Project: delete_link the AllResourceSpecifications link
  • widening from Project: create_link it

Then decide whether the two list functions should resolve the latest record rather than the original. That is the larger of the two and can be split.

Accepts on

A Sweettest that creates a Project-scoped spec on a Commons NDO, confirms it is absent from get_all_resource_specifications, updates it to Public, and confirms it appears; plus the reverse. Both halves must be red before the fix.

Provenance

Found reviewing #132 (R4). Not introduced by that PR: scope is new there, so the field and the defect arrive together, but the reconciliation was never written rather than removed.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions