Skip to content

fix(resource): reconcile global discovery anchor when a spec's scope changes - #151

Merged
Soushi888 merged 2 commits into
devfrom
fix/issue-144-spec-scope-anchor
Oct 27, 2026
Merged

Soushi888 merged 2 commits into
devfrom
fix/issue-144-spec-scope-anchor

Conversation

@Soushi888

@Soushi888 Soushi888 commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

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

Intent

ResourceSpecification.scope is mutable and decides one thing: whether the spec is linked from the global resource_specifications anchor. update_resource_specification wrote the new scope into the entry and never touched that anchor, so widening Project to Public kept the spec invisible in get_all_resource_specifications, and narrowing Public to Project kept it listed. This fixes the first half of #144.

Changes

  • Coordinator: update_resource_specification now calls a new private helper, reconcile_global_discovery_link, after the update link is written. The helper reads the anchor's AllResourceSpecifications links targeting the spec's original action hash. If the new scope is listed globally and no link exists, it creates one; if the new scope is Project, it deletes every such link. The anchor keeps targeting the original create hash, as on create.

  • Sweettests in dnas/nondominium/tests/src/resource/mod.rs, both on a Commons NDO (the regime where scope is genuinely the author's choice). Every listing check waits for consistency and reads get_all_resource_specifications from both the author and a second agent, so the anchor change is shown to reach a peer:

    • widening_spec_scope_to_public_adds_global_discovery_link: Project spec absent from the global list, update to Public, present exactly once, a second Public edit still lists it exactly once.
    • narrowing_spec_scope_to_project_removes_global_discovery_link: Public spec listed once, update to Project, absent.

No integrity change: deleting an AllResourceSpecifications link was already valid, and check_scope_coherence still pins Nondominium and Public regimes to Public scope on update.

Decisions

The helper reconciles against the anchor's actual state instead of comparing the old scope with the new one.

Option Rejected because
Compare original_spec.scope with the incoming scope (the shape the issue sketches) original_spec is the create-time entry, not the chain head. After Project to Public to Public, the second edit still sees Project as the old scope and would create a duplicate link.
Compare the previous_action_hash entry's scope with the incoming scope Correct for new edits, but leaves specs whose scope was already changed before this fix permanently out of sync. Reading the anchor repairs them on their next edit.

The cost is one get_links on the global anchor per update, the same pattern update_lifecycle_stage and update_operational_state already use for their categorisation anchors.

How to test

Run inside nix develop, from the repo root:

RUSTFLAGS='--cfg getrandom_backend="custom"' cargo build --release --target wasm32-unknown-unknown
hc dna pack dnas/nondominium/workdir
CARGO_TARGET_DIR=target/native-tests cargo test -p nondominium_sweettest --test resource -- --test-threads=4

Results on this branch (2026-10-06, local):

  • wasm build: exit 0. hc dna pack dnas/nondominium/workdir: exit 0.
  • cargo test -p nondominium_sweettest --test resource -- --test-threads=4: exit 0, 17 passed; 0 failed.
  • Red before the fix: with resource_specification.rs restored to origin/dev and the DNA rebuilt, cargo test ... --test resource -- spec_scope exits 101 with both new tests failing on their scope assertions ("widening to Public must add the spec to global discovery", "narrowing to Project must remove the spec from global discovery").
  • cargo check -p nondominium_sweettest --tests: exit 0. cargo check --release --target wasm32-unknown-unknown -p zome_resource_coordinator: exit 0.

Follow-up commit f981e54 (2026-10-06 19:59, local), after review:

  • The two scope tests now assert the listing from both agents after await_consistency_20_s. Red: with the reconcile_global_discovery_link call replaced by a no-op and the DNA rebuilt, cargo test ... --test resource -- spec_scope --test-threads=2 exits 101, both tests failing ("widening to Public must add the spec to global discovery", "narrowing to Project must remove the spec from global discovery"). Green with the call restored and the DNA rebuilt: cargo test ... --test resource -- --test-threads=4 exits 0, 17 passed; 0 failed.
  • wasm build exit 0, hc dna pack exit 0, cargo check -p nondominium_sweettest --tests exit 0, RUSTFLAGS='--cfg getrandom_backend="custom"' cargo check --release --target wasm32-unknown-unknown -p zome_resource_coordinator exit 0 (without that RUSTFLAGS the check exits 101 on getrandom, as for any wasm build in this repo).
  • Docs corrected: reconciliation runs on every update, unchanged scope included, which is how a drifted anchor gets repaired.

Note: the full resource suite run with the default thread count (17 tests, 34 conductors at once) failed 14 tests at app install with DatabaseError(Timeout) on this machine; with --test-threads=4 all 17 pass. That is a local resource limit, not this change: the failures are in setup_two_agents, before any zome call.

What was not verified

  • The delete branch removes every matching anchor link, but no test seeds two links to the same spec: only create_resource_specification and this helper create them, and a duplicate needs two concurrent edits by the author (for instance from two devices), which Sweettest cannot produce deterministically. Covering it needs a test-only extern or a decision on how to seed it.

  • The hREA DNA and the full hApp (bun run build:happ) were not rebuilt; only the nondominium DNA, which is all the resource Sweettests load.

  • Other Sweettest binaries (person, governance, nondominium, misc) and the UI were not run. The UI calls update_resource_specification with an unchanged signature.

  • rustfmt --check on resource_specification.rs reports diffs, all in lines already on dev; the added lines produce none. I did not reformat the file to keep the diff surgical.

Still open from #144

The issue's second-order point stays open and needs a call: get_all_resource_specifications and get_specifications_for_ndo resolve each link to the original action hash and get() it, so both lists render pre-update content for any edited spec, including the old scope. Resolving the latest record through get_latest_resource_specification_record is a small change, but it alters what both list endpoints return, so it is left for a separate PR once decided.

Documentation

  • documentation/zomes/resource_zome.md: update_resource_specification now documents scope reconciliation.
  • documentation/API_REFERENCE.md: side effects of update_resource_specification list the anchor reconciliation.

Related

Related issues:

Pre-open review

Run 2026-10-27 through PRReview after the fact (the PR predates the pre-open gate), at 9add740, rebased onto dev after #157.

  • Description: passes; Refs #144 corrected to Related #144. Opens with ## Intent, which predates the Summary-and-folds rule (suggestion, not a blocker).
  • Merge state: rebased onto dev (808fcd7), no conflicts.
  • Code findings: none critical or high. The helper is idempotent, acts only on the caller's own spec, and repairs a drifted anchor as well as a fresh scope change.
  • Documentation: passes (resource_zome.md, API_REFERENCE.md).
  • Tests: passes; two Sweettests assert the listing from the author and from a peer, both directions of the scope change.
  • Test exhaustivity: covered at the breaking layer (anchor state on the DHT, seen from a second agent). No UI path calls update_resource_specification.
  • Left open: per-LinkType validation of AllResourceSpecifications links (existing integrity TODO), the stale list read from bug(resource): changing a specification's scope never reconciles the global discovery anchor #144, and a dedup guard against a missed get_links read.

…changes

update_resource_specification accepted a new scope but never touched the
resource_specifications anchor, so widening Project to Public left the spec
out of global discovery and narrowing Public to Project left it listed.

The update now reads the anchor and makes it agree with the new scope:
one AllResourceSpecifications link to the original action hash when listed,
none when Project-scoped. Reading the anchor instead of diffing old and new
scope keeps repeated edits idempotent and repairs specs edited before this fix.

Refs #144
…ect its docs

The scope-change Sweettests now wait for consistency and read the global
listing from both the author and a second agent, so they prove the anchor
change propagates rather than only showing the author's local view.

The docs said a change away from Project adds the anchor link; the code
reconciles on every update, unchanged scope included, which is how it
repairs a drifted anchor. Both pages now say so.

Refs #144
@Soushi888
Soushi888 force-pushed the fix/issue-144-spec-scope-anchor branch from f981e54 to 9add740 Compare October 27, 2026 17:44
@Soushi888
Soushi888 marked this pull request as ready for review October 27, 2026 18:34
@Soushi888
Soushi888 merged commit 38d234a into dev Oct 27, 2026
7 checks passed
@Soushi888
Soushi888 deleted the fix/issue-144-spec-scope-anchor branch October 27, 2026 18:35
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.

1 participant