Decko Distributed Storage

I've been investigating and deep design work on using the ipfs/ipns abstractions in the Decko ecosystem. Starting from the storage and distribution end, If we store Decko content in a Merkel tree representation, content objects within it, that is the trees and blobs in each Decko instance at initialization and as local changes accumulate, then we can put these hash pointers to immutable trees to good use. For all the content that is "read everyone", it is ok to share data over ipfs and represent it as hash pointers. A handful of initial hash pointers to content is all you would have to actually copy to start an instance, the rest of the published initial content.

That is the immutable parts, the creation of a local instance would necessarily involve creating mutable objects in ipns. A process would need to trace the initial content from the hash pointer for the latest release, and that would instantiate content references by tracing paths through the namespace. The content still unchanged from initialization, or updated in a new release would be referenced from the decko.org namespace. Local changes would get new signed entries that can replace references to other namespaces. This process would be a lot like managing a git workspace. Local changes are made to trees and blobs and a commit is created that references these updates and the original tree. While in process of preparing a commit, you have an action like git status that tells the differences between 1) the tree you are building on., 2) The changeset staged to be committed, and 3) the contents of the workspace. Similarly, we will have 1) as the current /ipns/MyDomainID/ 2) /ipns/MyStageID could be a possibility, and 3) local or server copies of trees and blobs.

{
{"Path": "/root/based/keyname" }
{"Name": "Root+Based+keyname" } {"Type": {"/": "hash of type card"} } # "self" for Cardtype card (can't be cyclic)
{"Content": "Value in card"}
{"key1": {"/": "Hash of +key1 child card"} }
{"key2": {"/": "Hash of +key2 child card"} }
}

That would be the content (JSON) of a card. Note that we can't link 'up' the tree from this node or we would be creating a cycle. Instead, the name/keys are stored as ordinary attribute values, and children and types are Merkel links. This means that each Node in the store has a hash that represents that node and all its decscendents (recursive), plus it's type card and name/key. The entire deck can be represented by a special "root" node which has all the "simple" card nodes as links. When anything is changed, all of the nodes that depend on it will need updated links including the special root node. That is, recursively, all of its ancestors. Descendants generally don't change with an update.

Networked Decks and Name Systems

We already have a lot of design thoughts under the heading WagNet, but we probably will want to move beyond much of that, keeping some good parts. If we have this mutable/immutable split on our system we might want to borrow a little both from ipfs/ipns and git trees and commits vs. branches and tags that are the mutable parts. For wiki content, I would want something more like Ward's FedWiki concept where each user could "fork" a card or cards from one deck and thereby make it part of their namespaces where they might apply some edits and updates. They can them post back to the forked deck in something like a pull request. These might be more automated that the git equivalent with the use of permissions (Roles, etc.)

In this way, editted content could be viewed and reviewed from the fork until it is correct and then merged as a group of changes back to the original. As with git branches and forks, the change sets between them are easily computed and viewed, and the representation of the trees and branches would be able to do more "lazy updates" and still know when they do have the most recent versions or the correct branched versions based on a systems of paths and namespaces. We would build upon merkledags and its APIs for access to data and resolution of paths against trees.

So, the state of a deck's branch would be a pointer from the mutable space to the immutable space. In the simplest form, you would just have one reference to from the mutable space to a hash in the immutable state representing the whole state of a Deck, all the cards and content. That's what you have when your local git workspace in up to date with the source repository. You have one hash pointer to the immutable space and it matches the one published at github (for example). When developers make and commit local changes, git can report on what "commits" they share or not and the subsets of the tree that are changed and which commit the final version comes from. The commits are immutable as are the trees and blobs they include. Similarly, any current deck state would be represented by a deck origin and changesets that are subsets of the cards in the deck that would change it from the original to the branched state.

It might be productive to compose a namespace (mutable view) of an origin or origins plus multible change streams from other namespaces in the federation. In git, this is always and only at the repo level, but we might have decks that integrate content from many source decks, each with independent work flows generating change sets.

Links