Damus
nobody, allegedly profile picture
nobody, allegedly
@nobody

Traceable Collaboration Core (Nostr)

A Nostr primitive for traceable collaboration

#Nostr#Proposal

Traceable Collaboration Core (Nostr)

A medium-agnostic framework for signed, content-addressed, forkable creative work — with verifiable provenance built in. Audio is the first profile; see the companion document NAPI.

Contributors & disclaimer

  • npub1gek0f5s300jzqg4av4e7l4hfejrrkhzf8km2pkuquhfmja6gwdcqw4qqp7 — originator and lead. The concept and all the directional calls: the song-tree / derivation-graph model, the fork / pull / merge flags, studio-over-protocol, the “traceable collaboration framework, audio as a profile” reframe, and the two-document split.
  • Claude (Anthropic — Claude Opus 4.8) — research and technical drafting under that direction: Nostr and audio-ecosystem research, the schema and tag proposals, editing of the final document.

This is an AI-assisted working draft, shared for discussion — exploratory, not authoritative. Kind numbers are provisional and unregistered; external standards and NIP references should be verified independently; nothing here is legal advice. (Fittingly for a spec about traceable provenance, it declares its own.)

Status: working draft · v0.1 · all kind numbers are provisional (see §8) · first profile: NAPI (audio)


Stemstr is dead. Long live Stemstr. The Github of music making, a space for colaborative creations. It raised more questions than it provided solutions. This document attempts to explore some of these questions and some of the potential solutions they inspired.

Abstract

The Core is a Nostr-native primitive for traceable collaboration on creative work of any medium. A work is a public tree of signed, immutable Nodes; each Node composes content-addressed Assets through versioned Transforms and declares what it derives from. Three properties stack into traceability:

  • content-addressing makes the artifact bytes verifiable,
  • signatures make authorship verifiable,
  • lineage pointers make derivation verifiable.

Together, every node’s full history — who made it, and from what — is reconstructable and attributable. The Core defines everything that does not depend on the medium: assets, nodes, the derivation tree, growth flags, contributions, graceful degradation. A profile fills three open slots — asset metadata, composition format, transform runtime — to make it concrete. The first profile, NAPI, does this for audio (companion document); the same Core can carry video, design, 3D, or writing.


0. The idea

A traceable derivation graph for creative work. Most tools store a work as a file with local references (/path/to/thing, SomeTool v2) — opaque, unportable, and silent about where it came from. The Core replaces every internal reference with a verifiable address (a content hash for bytes, a signed identity for tools), and records each work’s parent and root. The result is that any node can be (a) resolved and rebuilt anywhere, and (b) traced — its authorship and full lineage proven, not asserted.

That is the product. Everything below is the vocabulary for doing it consistently across media.


1. Principles

  1. Separation of concerns. Artifacts, composition, and tools are distinct objects with distinct lifetimes. Fork the arrangement without re-uploading the media.
  2. Addressed references, never paths. Every reference inside a composition is a content address (Blossom SHA-256) or an identity address (a signed Transform). This single rule is what makes a work portable and verifiable.
  3. Small events, heavy blobs. Nostr events carry references and queryable metadata. The composition document and the artifacts are blobs, fetched on open.
  4. Traceability is the point. Bytes + authorship + derivation are all verifiable, so provenance is structural, not bolted on — and not economic. An incentive layer is a separate thing that reads this graph; it is out of scope here.
  5. Immutable snapshots, not live state. A Node is a hashed, immutable snapshot. Editing produces a new node pointing at its parent. No shared mutable state, no real-time co-editing — the tree is just snapshots pointing at snapshots. (This keeps plain document blobs viable and avoids CRDT machinery.)
  6. Reproducible by pinning, degradable via cached output. Pin every dependency by hash/version so a node is a lockfile; always publish a rendered output so the node can be consumed even without the toolchain.
  7. Core vs profile. Keep the medium-agnostic seam clean so any medium can write its own profile without changing the Core.

2. Object model

Lowest to highest. Each layer references the one below by hash or address.

Asset        a content-addressed artifact + metadata           (immutable)
Transform    a signed, versioned processing unit                (referenced by compositions)
  Composition   a document arranging Assets through Transforms  (the format is profile-defined → a blob)
    Node          a signed, immutable snapshot: composition + manifests + lineage + flags + render
      Tree        Nodes linked by parent/root = the derivation graph
Render       a cached output of a Node (consume without the toolchain)   (content-addressed)
Core termRoleProfile fills it with
Assetthe raw artifacta metadata schema (e.g. audio: sample rate, BPM)
Compositionhow artifacts are arrangeda format (e.g. audio: DAWproject session)
Transforma processing unita runtime contract (e.g. audio: Web Audio Modules)
Rendera consumable outputan output format (e.g. audio: a mixdown)

3. How a medium plugs in (profiles)

The Core leaves exactly three slots open. A profile is the document that fills them:

  1. Asset metadata — the fields that describe an artifact in this medium.
  2. Composition format — the document format that arranges artifacts and transforms. A profile SHOULD wrap an existing open interchange format (§5) rather than invent one.
  3. Transform runtime — the contract a Transform’s bundle conforms to, so any host can load it.

Optional profile choices: a role vocabulary for artifacts, and the Render/output format.

The first profile is NAPI (audio): it fills these slots with audio asset metadata, the DAWproject session format, and the Web Audio Modules runtime. See the companion document. Other media (an NLE timeline for video, a layer stack for design, a manuscript for writing) can be written against this same Core.


4. Per-object spec

4.1 Asset (NIP-94 profile, kind 1063)

A content-addressed artifact, keyed by blob hash. Core-required tags:

  • ["url", "<blossom url>"]
  • ["x", "<sha256>"] — the content address
  • ["m", "<mime type>"]
  • ["size", "<bytes>"]

A profile adds its medium’s metadata tags (and MAY add a ["role", "<free string>"]).

4.2 Transform (addressable) — a signed processing unit

A versioned device referenced by Compositions. Signed by its developer’s npub. This is what makes third-party tool authors first-class.

  • ["d", "<transform-id>"]
  • ["name", "..."], ["transform_type", "<profile-defined>"]
  • ["version", "1.0.0"]
  • ["bundle", "<sha256>", "<url>"] — the runnable bundle
  • ["api", "<runtime-contract-id>"] — the contract it conforms to (profile-defined)
  • ["param_schema", "<sha256>", "<url>"] — declared parameters/ranges, so hosts validate state and render UI

A preset is parameter state for a Transform: a small event tagged ["preset_of", "<transform-address>"], or inline state inside a Composition.

4.3 Node (addressable) — the forkable unit

Small event; the heavy composition lives in the referenced blob.

  • ["d", "<node-id>"], ["title", "..."], ["alt", "<description>"]
  • ["composition", "<sha256>", "<url>", "<format-id>"] — the composition document blob
  • ["render", "<sha256>", "<url>"] — a cached, consumable output (§6)

Lineage (reuse NIP-34’s grouping idea):

  • ["e", "<parent node id>", "<relay>", "reply"] — direct parent
  • ["e", "<root node id>", "<relay>", "root"] — the family root
  • ["r", "<root-id>", "euc"] — earliest-unique id; groups the whole tree across forks
  • ["p", "<ancestor pubkey>"] per contributor in the chain (provenance)

Growth flags — how this node lets the tree grow from it. Combinable (and/or); UI-enforced intent, not DRM (blobs are public regardless):

["flags", "fork", "pull", "merge"]

  • fork — others may branch a copy into a new node of their own (the open, default posture).
  • pull — others may submit a Contribution back for the maintainer to consider (§4.4).
  • merge — the maintainer is willing to incorporate accepted Contributions into this node’s canonical line.
  • (no flags / ["flags", "locked"]) — no derivatives requested.

The set is the statement: fork = “branch, but don’t send anything back”; fork+pull+merge = fully open. Clients render affordances straight from the flags.

Dependency manifest (so an opener knows what it needs before loading):

  • ["requires_transform", "<transform-address>", "<version>", "<bundle-hash>"]
  • ["requires_asset", "<sha256>"]

4.4 Contribution (regular) + Status

For nodes carrying pull (and ideally merge): a collaborator forks, then proposes their version back.

  • ["e", "<target node id>", "<relay>", "root"] — the node being contributed to
  • ["proposed", "<contributor's node address>"] — their fork
  • ["p", "<target maintainer>"]
  • content: a human note

The maintainer resolves it with a Status event (reuse NIP-34 status kinds): merged / declined / open. “Merge” is a human act — the maintainer opens the fork, takes what they want, and publishes a successor node. There is no automatic merge; the protocol records intent and outcome, and the result is a new node in the tree.

4.5 Render (regular) — cached output

A content-addressed output of a Node, so the work is consumable without its toolchain.

  • ["e", "<node id>"] — what it renders
  • ["x", "<sha256>"], ["url", "<url>"], ["m", "<mime>"]
  • environment: ["used_transform", "<address>", "<version>", "<bundle-hash>"] per Transform, for verifiability

5. Wrap, don’t invent

A profile’s composition slot SHOULD wrap an existing open interchange format and rewrite its references, not define a new format. The rewrite is always the same two substitutions:

  1. every media reference → a Blossom content hash;
  2. every tool/device reference → a {transform-address, version, bundle-hash} triple.

Then store the rewritten document as a blob and point a Node’s composition tag at it. This is the single biggest lever for adoption: a developer who already parses the wrapped format is most of the way to parsing the profile.


6. Reproducibility & graceful degradation

A fork is worthless if it can’t be rebuilt or consumed elsewhere.

  1. Pin everything. Assets by hash, Transforms by version + bundle-hash. A Composition is a lockfile.
  2. Always publish a Render. Every Node SHOULD reference a cached output so anyone — including apps with none of the Transforms — can consume the result immediately.
  3. Cache partial outputs (“freezing”). A Composition MAY carry pre-rendered output for individual parts, so a missing Transform degrades gracefully instead of breaking the work. Profiles define where this is mandatory (e.g. audio requires it for instrument tracks).
  4. Declare tool latency / determinism caveats the profile needs for a faithful rebuild.

7. Reused NIPs

  • NIP-94 / NIP-92 (imeta) — artifact metadata.
  • Blossom (NIP-B7 lists) — content-addressed artifacts + bundles.
  • NIP-34 — the fork-grouping pattern (euc) and the patch/issue/status workflow, repurposed for nodes/contributions.
  • NIP-89 — app handlers, so the right client opens a Node / Asset / Transform kind.
  • NIP-65 — relay lists, including where a work’s contributions are collected.

8. Open questions (help wanted)

  1. Node diffing. A readable “what changed in this fork.” The general structure (added/removed/modified composition elements) is Core; the leaf semantics are profile-specific. This is the credit/merge surface and nothing standard exists.
  2. Transform sandboxing. Running untrusted third-party transform code safely in a host. The gnarliest, most valuable problem.
  3. Kind-number registration. Everything below needs real assignments via the NIPs repo.

9. Profiles & NIP split

Split along the Core/profile seam so the reusable parts stand alone:

Core NIPs (medium-agnostic):

  • Core-1 — Asset, Transform & Node. Content-addressed artifact, signed transform, signed snapshot with lineage. The minimal traceable unit.
  • Core-2 — Tree, contributions & growth flags. §3 (tree), §4.3 (flags), §4.4. The collaboration and branching workflow.

Ship the Core first — it is the reusable standard and the bigger prize.

Known profiles:

  • NAPI (audio) — companion document. Fills the three slots with audio metadata, DAWproject, and Web Audio Modules.
  • Open invitation: video, design, 3D, and text profiles can be written against this same Core.