Tangled: Knot-Stored Cob Proposal

jeremyjh1 pts0 comments

Tangled: Knot-stored COB proposal

Tangled: Knot-stored COB proposal<br>Proposal to accomplish full decentralization of Tangled.<br>boltless

May 21, 2026

9 3

In this article, I will propose a new architecture to make Tangled fully decentralized, mainly about collaborative objects (COBs). I will explain what we are lacking today, how can we solve it, and what are the limitations of my own proposal.<br>DISCLAIMER: All future directions introduced in this article are just my personal proposal and not an official plan. We haven't fully settled down our plan yet and there is high possibility for us to choose completely different approach. We just thought it is interesting to share publicly to gather more opinions from users, so keep in mind that I'm not representing the Tangled in any sense from this article.

NOTE: This article is pretty long explaining all the backgrounds, what we've tried and how that fails, and all the big and small reasonings behind my choice. If you are ready to face the new architecture and don't have time to read all this, go straight to the summary.<br>How Tangled handles COBs today<br>Currently, author of the issue owns the issue record. The record content is stored in author's PDS. Maintainers cannot control anything about those issue records. To allow maintainers collaboratively modify the issue state, Tangled had to make issue/PR states as dedicated records like sh.tangled.repo.issue.state and sh.tangled.repo.pull.status where last ingested one overrides the old state.<br>For more complicated collaborative objects like issue/PR labels... we basically implemented a CRUD system on top of existing atproto CRUD system. We have sh.tangled.label.op record which represents add/update/delete operations. These records represent a modification instead of specific state and appview is expected to ingest everything in correct order, then amend everything to the final state. Here, we just assume label operation records to not be deleted or modified and always ingested in correct order and nothing will ever be deleted.

Even when initial label adding label:duplicate is deleted from the network, appview just remembers it to preserve current state.<br>This current architecture becomes way more complicated when we consider collaborators can also be removed.<br>1.<br>Alice adds Bob as collaborator.

2.<br>Bob close or label some issues. These new states are stored in bob's PDS.

3.<br>Bob is removed from the collaborator.

4.<br>How can new appview restore final state of issue states or labels? What if bob remove issue.state or label.op records for the repository bob isn't belonged to?

Our current solution is to just... not allow removing a collaborator.<br>Even that doesn't fully work. What if Bob nukes his account? Suddenly all bob's work to that repo will disappear from entire network. This should not happen and obviously not an expected behavior in collaboration platform. For example, we don't expect old contributor to be able to nuke all their codes and commits from the project without permission just because they want to. Current Tangled appview is working fine because we use our own DB as a source of truth collecting all events in real-time since the very beginning, validating them just as we received them.<br>Because appview is collecting distributed issues for each repositories, the issue/PR ids are appview-local and doesn't work universally.<br>This situation is not good both for feature-wise and architecture-wise. We want full decentralization while acting as a working contribution platform. Maintainers should be able to restore the collaborated state from scratch without depending on centralized service holding all the cache.<br>Recap about did-for-repo situation<br>Before going further, let me do a recap of the did-for-repo situation for people who haven’t been following recently.<br>I heavily recommend reading the repo lifecycle post by Nelind because it can give you really good insights about "repository having a DID" concept.<br>Tangled recently switched the git repository identifier from sh.tangled.repo record AT-URI to plain DID. This is to allow repository transfer to different owner without loosing all the related data like stars, issues and PRs. We are still in progress of migrating existing records using the AT-URI as a reference, but eventually DID will be the preferred way to reference the git repository.<br>How repo renaming works today<br>While DID of the git repository represents the existence, owner still has sh.tangled.repo record to claim the ownership of that repo. Basically we do two-way verification for the repository ownership:

A repo claim its current owner and name through {knot}/xrpc/sh.tangled.repo.describeRepo.

A user claim the repository ownership by having sh.tangled.repo/ record in their PDS.

When there are more than one sh.tangled.repo records pointing to same git repository DID, we treat invalid ones as "old repository name" and redirect to current name.

For example, when alice renames repo-a to...

tangled repo issue repository state from

Related Articles