Skip to content

rc.12: imported Markdown source artifact is not replicated to peers for public/open CGs #872

@branarakic

Description

@branarakic

Summary

When a Markdown file is imported into a public, open Context Graph (accessPolicy:0, publishPolicy:1) and promoted to Shared Memory, peer nodes correctly replicate the structural triples (sections, names, content hashes) but cannot fetch the original Markdown source bytes. The daemon route that would return them (/api/assertion/import-artifact/read-markdown) is gated by a 403 owner-guard: only the agent that owns the assertion can read its source artifact.

For a curated CG that's reasonable. For an open, public CG it's a UX gap — peers see references to urn:dkg:file:keccak256:… in SWM but the bytes are nowhere fetchable on the network.

How this surfaced

A peer node (Hermes, separate operator) joined our public CG `0x983587836e8F8C1831b5051582689851aE86A802/experimental-music-public`, replicated 53 SWM triples successfully, and reported:

I attempted to read the referenced Markdown artifact for full text, but the node rejected it because imported artifact Markdown can only be read from imported assertions owned by the requesting agent. So this report is based on the SWM triples I can query, not the private/owned artifact payload.

Code references

  • packages/cli/src/daemon/routes/assertion.ts:778assertImportedArtifactOwnerAddress throws 403 if assertionAgentAddress !== requestAgentAddress.
  • packages/cli/src/daemon/routes/assertion.ts:1058-1098POST /api/assertion/import-artifact/read-markdown invokes the owner-guard unconditionally.
  • The route reads bytes from the local content-addressed fileStore (`fileStore.get(markdownHash)`). There is no peer-fetch fallback — even if the owner-guard were lifted, peers wouldn't have the bytes locally because they aren't gossiped.

Two related gaps

  1. Owner-guard is policy-agnostic: The 403 fires regardless of whether the CG is curated or public. For a public CG, peers (esp. members) arguably should be able to read source artifacts.
  2. Source bytes aren't gossiped: Even removing the owner-guard would only let peers read artifacts that happen to be in their local store. For public CGs, the source-file bytes should probably be optionally replicated alongside the SWM triples (or fetchable via the same peer-skill substrate used for SWM sync).

Possible design directions

  • Minimal: when CG `accessPolicy=0` (public) AND publishPolicy=1 (open), drop the owner-guard so any peer with the bytes locally can serve them.
  • Fuller: add an opt-in "replicate source artifacts" flag at import time; gossip the file bytes to CG members when set.
  • Most explicit: introduce a peer-skill (cf. `docs/messenger-add-protocol.md`) that lets peers fetch a content-hash from the owning agent on demand, with a public-CG ACL bypass.

Severity / priority

Low priority — replication of structural triples covers the core "knowledge sharing" use case. But this gap is surprising for users who explicitly opt into a public CG and expect "publicly readable" to extend to imported source files, not just extracted triples.

Metadata

Metadata

Assignees

No one assigned

    Labels

    post-mainnetCan ship after mainnetpriority:mediumReal defect or gap; fix planned but not release-gating on its own

    Type

    No type
    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