Collaborative Dependency Graphs

Thu Mar 12 2026

We do not mostly need better allocators for the last step of public goods funding. We need better coordination around what depends on what. A good dependency graph should be a shared pool of contestable, versioned, provenance-rich claims that many groups can turn into their own trusted views.

Current dependency graphs usually fail in the same way. One actor publishes a graph, it goes stale, it mostly captures code, and nobody can tell which edges are well-supported, disputed, or simply missing. If the source graph is bad, better allocation mechanisms downstream will not save us.

Claims, not facts

Instead of storing “project A depends on project B” as a fact, store it as an assertion.

A minimal claim might look like this:

{
  "relation": "depends_on",
  "source": "github.com/acme/app",
  "target": "pkg:npm/react",
  "scope": "app@v1.4.0"
}

And an attestation on top of it:

{
  "claim": "claim:123",
  "stance": "challenge",
  "issuer": "did:plc:bob"
}

The point is simple: the edge and the disagreement are separate objects. A maintainer can publish a claim, a bot can extract one, and other people can support, narrow, or challenge it without overwriting anything. That is a better default for resolving disagreement.

Claims and attestations are separate objects A repository node points to a package node with a dependsOn claim, while a separate challenge attestation points to that claim. acme/app repo pkg:npm react claim: dependsOn challenge
The edge is one object, support or challenge lives next to it, not inside it.

Borrow what already works

We do not need to invent this from scratch.

The components exist. We mostly need to compose them.

A shared claim graph, many curated views

The important thing is not to build one canonical dependency graph. Build a shared knowledge graph of claims, then let different communities derive different views from it.

A dependency graph is not the database. It is a query plus a trust policy.

In that model, the base object is a claim, and agreement or disagreement lives in separate attestations. You do not overwrite an edge; you add signed context around it.

Imagine a repository that uses a library, implements a standard, and was heavily shaped by a paper:

A maintainer-focused view may only include self-declared and reviewed software dependencies. A researcher-focused view may also include papers and standards. A funder may want a stricter view that only includes edges with multiple attestations. Same underlying claim pool, different derived graphs.

That is a more plural design. It avoids turning one imperfect graph into a single source of truth for everyone.

How it stays current

The graph should be maintained locally, claim by claim, not globally. That is as much a governance problem as a technical one, and it only works if entities have stable identifiers with explicit merge and split rules.

A simple loop could be:

  1. Maintainers self-declare important edges.
  2. Bots scan manifests, citations, references, issue trackers, and release notes to suggest candidate claims.
  3. Reviewers publish attestations that support, refine, or challenge claims.
  4. New versions create new claims instead of overwriting history.
  5. Curators publish trust overlays and ranked views for their communities, more like a decentralized protocol than a single database.

Humans are good at ambiguity, incentives, and boundary cases. Machines are good at harvesting candidate edges. That division of labor seems much more realistic than expecting either side to do everything.

A challenge process matters too. If self-declaration is enough to move money, people will game it. Claims should be easy to propose, but also easy to contest. A good default is soft schema plus strong validation: keep the core vocabulary small, let messy claims in, and publish constraint violations, public diffs, and bot behavior instead of pretending bad data will disappear on its own. Whether that contest process uses review queues, reputation, staking, or markets is an incentives question, not the foundation.

Why this matters for funding

Overall, funding should be downstream as there are really three layers here:

  1. Graph layer: claims about relationships.
  2. Policy layer: which issuers, evidence types, and scopes you trust.
  3. Funding layer: the formula that turns a chosen view into allocations.

That separation is useful. It prevents “the graph says so, therefore money flows so”. Communities can argue about whether an edge is supported without collapsing that argument into one hard binding allocation rule, and any downstream score should be traceable back to cited claims and recomputable from a public snapshot.

With this approach we are not forcing one final answer, but helping groups find legible areas of agreement and disagreement.

Open questions

A few hard problems remain:

Conclusion

We do not need a perfect canonical map of interdependence. We need a shared, contestable substrate of claims about dependencies, with good provenance, durable identifiers, and versioning. Then different communities can derive their own views, trust their own curators, and plug those views into funding or coordination mechanisms.

Better coordination starts upstream, with better legible artifacts.


How could a POC look like? Keep the graph as a derived view and store only a few append-only record types in Git — entity, claim, attestation, evidence, and optional label — as small YAML files. Make claim the core unit (subject, relation, object, qualifiers, evidence, issuer, createdAt, status, supersedes), let attestation support, refine, or challenge claims, keep the relation set tiny (dependsOn, uses, cites, implements, derivedFrom, maintainedBy, funds), and generate each dependency graph by filtering those records through a trust policy and query. A first repo could just be directories of YAML plus a simple script that materializes a view.

← Back to home