Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-?? - WIP - Source Control Context #223

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

garyray-k
Copy link

I laid down a rough draft of how we can decentralize source control context using nostr. I am opening this Work In Progress PR so I can share it with others and gather feedback, as I'm certain that I missed something in my initial thoughts.

@fiatjaf
Copy link
Member

fiatjaf commented Feb 5, 2023

Are you working on this?

I was working on a git plugin myself to use git repos stored on Nostr, but eventually decided it was a bad idea. And it is better to use normal git servers for git -- and have them be self-hosted or hosted on a variety of service providers, then use Nostr to send open issues, send patches, comment on patches and for repository discovery.

I feel like these four functions above would make Nostr into an actually decentralized alternative to GitHub. Sending and applying patches was already done by @jb55 at http://git.jb55.com/git-nostr-tools, although it isn't being used much and I don't know if and how it could be improved.

The reason why hosting git data directly on Nostr is a bad idea is that it would be extremely inefficient and storage requirements would be massive -- so relays would start blocking this kind of thing and we would have to use special relays designed just for git-nostr, and at this point it is better to just use normal git servers that already exist. Each with its own specialty.

@mikedilger
Copy link
Contributor

hosting git data directly on Nostr is a bad idea

Agreed. Also the git protocol is a very efficient optimized for git, and git itself is already fully distributed.

@garyray-k
Copy link
Author

It's something I've dedicated some time to considering and working on a rough draft MVP implementation, but I wanted to open up the topic for discussion so I can hopefully learn from others that have given this some thought as well.

I 100% agree on not hosting git repositories on relays by default. But the discovery of git repos on a relay that decided to host the data could be part of the NIP, as I've outlined in the draft.

The NIP I began writing is outlining a way to store the context around source control. The draft here proposes using a tag in a specific kind to track the remote URL(s) for a given repository and creating an event from that.
From there, clients can NIP-10 most things to create context like comments/issues/etc.

There will be metadata needed for tracking line-specific comments and that metadata could be included in the tags part of an Event of this kind.

QQ: How do NIPs get numbered?

@arkin0x
Copy link
Contributor

arkin0x commented Feb 6, 2023

@garyray-k I really like the idea of using nostr for context and keeping git hosting on git servers. I'm imagining a web-based nostr client that is essentially a github-inspired interface for working on PRs, issues, bugs, etc.

Having a conversation around a PR on nostr is easy. But I think we would need some kind of nostr-enabled git hook to publish events that represent code changes on the remote repo, like this:

image

The other thing is that making edits to a repository via this nostr-git-client seems like a potentially bad idea since putting private keys into nostr apps is still not ideal security-wise... NIP26 is out there now so maybe this is going to get better. But you could work on your repo from CLI or Git client as normal and see your pushed changes show up in nostr-git-client because they would be published to the PR by a hook on the remote repo.

Not having the ability to directly interact with a repo via the client would make things like forking more difficult and clunky though... No forking, no committing, no merging, no creating new repos...

QQ: How do NIPs get numbered?

I was also wondering this 😅

@garyray-k
Copy link
Author

Having a conversation around a PR on nostr is easy. But I think we would need some kind of nostr-enabled git hook to publish events that represent code changes on the remote repo, like this:

I think the client would be responsible for this aspect finding new changes and updating the display. For an MVP, I envision the need for a client with two libraries, nostr and git (oversimplifying here). The git library is largely reading repositories and the nostr library publishes events with metadata to tie the event to a specific part of the git repo.

@hendore
Copy link

hendore commented Feb 6, 2023

I've been experimenting with this for a couple of days, and made decent progress, hit a few brick walls here and there but I thought I would give my input/conclusion.

I started with a script that I could use to publish git refs (heads/tags) and objects (commits/trees/blobs) to a unique repository, the plan here was to get the event structures/schemas sorted before porting this script to a git-remote-helper so that we could simple push/fetch using git with a custom remote handler

git remote add origin nostr://some.relay.io/814add12473702fcf229d4786bc46e5ddbabbb88027037e371ec4c7947de284d

After getting this far, I felt quite confident this could work, so I set about creating a client to interact with these events, that turned out pretty straight forward, I was able to create new repositories, update their details/settings etc... once a repository was created I could push branches up (with my dev script / not a git-remote-helper yet). At this point, I could browse all of my repositories and see all of their refs along with view the tree and latest commit of each ref.

What I found was, all refs/objects are quite light minus blobs, moving over to packed git objects (deltas) rather than loose objects (no deltas) would certainly help here but then I thought about maybe storing blobs on the filesystem outside of the database (but this would rely on relay changes and I was trying to do this without introducing any new relay features than already proposed). Turned out it wasn't actually the end of the world with the files I tested on since my UI was only ever subscribing to blob objects when viewing a file.

Few screenshots of the progress

Screenshot 2023-02-06 at 18 36 56

Screenshot 2023-02-06 at 18 38 17

Screenshot 2023-02-06 at 18 44 32

So things where looking good, however this was all just a big experiment, in the end I 100% came to the same conclusions that have been mentioned. Although I found there wasn't any performance issues with the test repos/branches I had published to a relay I'm sure with larger repositories it could be a concern.

The funny thing is, before I started any development I wrote about a few options, having a git-server was the in between option

Screenshot 2023-02-06 at 19 35 32

All that said, it was a fun experience, I learnt a tonne of git internals along the way so it wasn't a complete waste of time but I think it might be time I hang up the boots on this one. If anyone want's to discuss how a git-server model may look, I would be up for discussing / working on something.

@mikedilger
Copy link
Contributor

QQ: How do NIPs get numbered?

What I've done is look through all the PRs, find the highest number, and go one higher.

@fiatjaf
Copy link
Member

fiatjaf commented Feb 13, 2023

I like this draft and the initiative. Thank you @garyray-k.

I agree with the idea of having a dedicated kind for "merge requests" (and possibly one for "issues"?), but the responses to these seem to me to fit better in kind:1 events.

It would be nice to have these notes -- i.e. discussions about a merge request -- to show up in the normal "social" feed of users, right? And then social feed users could click on the context to see the event they were replying to and then what would they see? An event (that they would not understand) specifying a merge request. Do you think this is good or bad? Did you think about that?

@ofer-elrom
Copy link

It seems we are all here in agreement that relays should be a transport layer rather than a storage medium. This points to git servers holding the data and communicating over Nostr with git clients.
In my opinion, censorship resistance is very important for open-source code moving forward, and Git on Nostr can supply it. The trick is having publicly known code repository entities to which public communication is connected while having their data "hidden," private but verifiable.
I think the solution, in short, is that Nostr-authenticated developers can use a Nostr-compatible git client to push to and pull from Nostr-authenticated git suppliers using Nostr relays as a communication layer.

It can connect with @gayray-k suggestion above.
I am not sure I have the time to create this on my own. I would appreciate any remarks on this and help get more people on board with the idea.
For a more elaborate explanation, please see this google document: docs.google.com/document/d/1z96XpTtrUvrFZYPjMzlT5JuE41HF6X5vI99lvImVCvU

@garyray-k
Copy link
Author

garyray-k commented Feb 14, 2023

@hendore Nice research! I'm glad you concluded that relays mustn't hold repos, but there will likely be relay servers that do both for hosting simplicity.


It would be nice to have these notes -- i.e. discussions about a merge request -- to show up in the normal "social" feed of users, right?

I think this will happen with kind: 1 events as replies. To me, it makes a relay sort of a town square. You might not care to hear about merge request discussions, but by being on the "global" feed of a relay you will see it nonetheless.

And then social feed users could click on the context to see the event they were replying to and then what would they see? An event (that they would not understand) specifying a merge request. Do you think this is good or bad? Did you think about that?

I will have to do some research on how clients are handling the "content" field. My initial thought would be to standardize the content field of the merge request event so a client that does not explicitly handle "merge request events" can still display something meaningful. Along with this research, I wonder if clients filter based on root events. That seems possible but it might not scale to a certain point.

  • research how some clients handle unknown kinds

I think the solution, in short, is that Nostr-authenticated developers can use a Nostr-compatible git client to push to and pull from Nostr-authenticated git suppliers using Nostr relays as a communication layer.

Git already handles authentication and even has mechanisms for separate authors and committers. The goal of this NIP would be to anchor series of events to a single git "thing". The simplest I reasoned about was a merge request.
How would Nostr auth enhance existing git authentication?

@fiatjaf
Copy link
Member

fiatjaf commented Feb 14, 2023

My initial thought would be to standardize the content field of the merge request event so a client that does not explicitly handle "merge request events" can still display something meaningful.

That's kind of what I was thinking.

@ofer-elrom
Copy link

Git already handles authentication and even has mechanisms for separate authors and committers. The goal of this NIP would be to anchor series of events to a single git "thing". The simplest I reasoned about was a merge request.
How would Nostr auth enhance existing git authentication?

My purpose with "Nostr Auth" is to separate the constant public point of contact from a dynamic, nonconstant uncensorable IP generated for a git session. At the first simple stage, this IP may be the IP of a git server that is generated by a VPN per connection request. At later stages, the entire client-server git communication can be done by both the client and the server polling on private messages sent to them and transmitting data over relays with no server IP involved.
This does not help in git authentication. It helps enable a censorship-resistant public git service that can synchronize open-source development.

@garyray-k
Copy link
Author

@ofer-elrom
While I appreciate the consideration, I think what you're describing would be outside the scope of a NIP. From my understanding, you're trying to create a new way for git to be communicated/networked. That would not be the goal of this NIP. This NIP is aimed at merely defining a way to reference source control primitives (ie. merge request) as a nostr event so further context can be built from the root reference point.

@garyray-k garyray-k changed the title WIP - Source Control Context NIP WIP - NIP-69 - Source Control Context Feb 14, 2023
@garyray-k garyray-k changed the title WIP - NIP-69 - Source Control Context NIP-69 - WIP - Source Control Context Feb 14, 2023
@ofer-elrom
Copy link

While I appreciate the consideration, I think what you're describing would be outside the scope of a NIP. From my understanding, you're trying to create a new way for git to be communicated/networked. That would not be the goal of this NIP. This NIP is aimed at merely defining a way to reference source control primitives (ie. merge request) as a nostr event so further context can be built from the root reference point.

Thank you. I understand. Sorry for the distraction of focus.

@kouloumos
Copy link

I like were this is going.
Feature-parity with GitHub reviews (e.g. resolving inline review comments) is one of the evaluation schemes used when thinking about GitHub alternatives for Bitcoin Core (src) (and I assume for any other large-scale open source project).

Maybe https://github.com/zw/bitcoin-gh-meta can give some inspiration on the required context schemes.

@garyray-k
Copy link
Author

Someone brought up a good point of consideration: how do disparate notes maintain their tie together?

Example:
Dev A creates PR and the root event for the source control context.
Dev B creates a reply note using NIP-10
Dev A and B are publishing to different relays.
Dev B's relay goes dark and nukes all data.

How do we maintain this context?

@mikedilger
Copy link
Contributor

mikedilger commented Mar 4, 2023

Nostr provides redundancy if you utilize it. Dev B should post to more than one relay.

Now the trick here is that people following the repo need to see Dev B's note, so instead of what we do for a microblog (everyone writing wherever they prefer), repos should probably be hosted on a (per-repo) well defined set of relays (but more than just one) chosen by the owner of the repo, and these relays configured in a way that they allow access appropriately to this repo.

The NIP-65 model surely won't work. It's not 1-to-many, it's many-to-many.

@Semisol
Copy link
Collaborator

Semisol commented Mar 4, 2023

my proposal for Git:

  • ✅ store on Nostr
    • issues and patches, comments to them, their state, labels, assignees, ...
    • information about the current refs (branches, etc)
    • repository information, name, description, etc
  • ❌ store externally
    • the actual objects (discover git repos that may contain this data through nostr)
    • the patch contents (may be too large)
    • file attachments

69.md Outdated Show resolved Hide resolved
@kirkawolff
Copy link

kirkawolff commented Mar 4, 2023

The one assumption github makes about the git repository itself is there is only one official location to push and pull from. This makes sense in the case of something that's intended to be a frontend to a git server, but it doesen't leverage the decentralized intent behind git.

Github stores PRs on the central repo on a branch, which requires write access to the central repo. It makes more sense in decentraland to point to a branch on a git remote rather than requiring the project owner to manage a ratsnest of ACLs for everyone that wants to push.

Github solves this by allowing references to forks inside the platform, but this is clunky and clutters your own account and if you dont intend to actually fork the project then you will never make use of all of the other features in your own account.

It would be nice to have a "pure" github URI place to store your public copy of the repo without needing to access it through a bloated CMS like github. This could be as simple as your own ssh server and then anonymous read-only access is provided to the "Project context" as (multiple?) URI and sshkey fields. Alternatively, there might be future integration with git-torrent to host the central repo.

In the case of building it on a nostr backend, each PR should point to a unique http/ssh uri (which does not preclude using the central repo).

@melvincarvalho

This comment was marked as spam.

@garyray-k
Copy link
Author

garyray-k commented Mar 4, 2023

@kirkawolff

Github stores PRs on the central repo on a branch, which requires write access to the central repo. It makes more sense in decentraland to point to a branch on a git remote rather than requiring the project owner to manage a ratsnest of ACLs for everyone that wants to push.

The owner of the root repository Event would be listing the remote locations that are canonical. How they manage ACL for those is outside the scope of this NIP.

It would be nice to have a "pure" github URI place to store your public copy of the repo without needing to access it through a bloated CMS like github. This could be as simple as your own ssh server and then anonymous read-only access is provided to the "Project context" as (multiple?) URI and sshkey fields. Alternatively, there might be future integration with git-torrent to host the central repo.

This already exists. You can host remote repos outside of github that people can clone from. This is a decent article describing the process (https://www.inmotionhosting.com/support/website/git/git-server/). And if you look at a GitHub URL, it's a remote URL + file path.

69.md Outdated Show resolved Hide resolved
@melvincarvalho

This comment was marked as spam.

@OpenSourceOptimist
Copy link

How do we feel about adding the POSSIBILITY to include the patch in a merge request event somehow?

It would enable users to create merge requests without having write access to any git server. Could be a confusing first time experience if you need to find a git server to host your changes. Clients would probably be forced to have default git servers for their users just like with images now.

The obvious downside is that including the patch would create large events. Completely agree with the general sentiment that the relays should not store the repository. Sending patch files around is the OG way to use git so it could make sense to support them in this brave new word. Maybe another kind and another NIP?

For example this is the patch for this PR https://patch-diff.githubusercontent.com/raw/nostr-protocol/nips/pull/223.patch

@garyray-k garyray-k marked this pull request as draft March 4, 2023 16:34
@fiatjaf
Copy link
Member

fiatjaf commented Mar 6, 2023

I also think this NIP shouldn't be using number 69. Better leave that number for something less important and more playful.

@garyray-k garyray-k changed the title NIP-69 - WIP - Source Control Context NIP-?? - WIP - Source Control Context Mar 7, 2023
@KaffinPX
Copy link

KaffinPX commented Mar 7, 2023

Hey everyone, im creating a new NIP like this one because we CANT implement an exact git over Nostr because of commit chains because it needs order which cant be possible on an async network.

@spearson78
Copy link

I created a proof of concept git integration for nostr.

You can use it to create a git repo server that takes its config from nostr.

By issuing commands to a relay you can trigger the creation of git repositories and manage the permissions of these repositories. Authentication is handled by associating your nostr profile with an SSH key.

A quick demo video is here https://www.youtube.com/watch?v=G-WzlC8XfW4

The source code and documentation is here. https://github.com/spearson78/gitnostr

@ofer-elrom
Copy link

I created a proof of concept git integration for nostr.

You can use it to create a git repo server that takes its config from nostr.

By issuing commands to a relay you can trigger the creation of git repositories and manage the permissions of these repositories. Authentication is handled by associating your nostr profile with an SSH key.

The project mentioned in the link seem to be moving forward with similar concepts in mind. I think it may be good if you joined:
#223 (comment)

@PeerRich
Copy link

I created a proof of concept git integration for nostr.

You can use it to create a git repo server that takes its config from nostr.

By issuing commands to a relay you can trigger the creation of git repositories and manage the permissions of these repositories. Authentication is handled by associating your nostr profile with an SSH key.

A quick demo video is here youtube.com/watch?v=G-WzlC8XfW4

The source code and documentation is here. spearson78/gitnostr

this is really cool @spearson78, should we team up and join forces with nostrgit.com? we're currently discussing backend and CLI

@KaffinPX
Copy link

Everyone check #358

@npub1zenn0
Copy link

Doesn't a patch based workflow work better over nostr? Please correct me if I'm wrong.

Sending patches is just sending events. So Gerrit over Github? Essentially the email lists based flow except not email. Just a matter of directing Gerrit backend to look at Nostr for new content?

@fiatjaf
Copy link
Member

fiatjaf commented Apr 16, 2023

Yes, @npub1zenn0, I think you are right.

@jb55
Copy link
Contributor

jb55 commented Apr 16, 2023

PRs are still useful though. The PRs over nostr demo I was tinkering with looked similar to this one:

./target/debug/git-nostr-pr --base master --upstream jb55@jb55.com/git-nostr-tools --origin git://jb55.com/git-nostr-tools --title "my pr" | jq .
event sent to ws://127.0.0.1:8080
{
  "content": "",
  "created_at": 1681609363,
  "id": "7a3f6d933a7e9c394b37831f1c14c0c9c5ce6add8ada79c45e94b26e8cf5e988",
  "kind": 1969,
  "pubkey": "589b887d77f39d0d24f65fb800097b970adbf75b6315d2fee8822cba9b4cf5d8",
  "sig": "6d18a2327f0c0aabedc86d733a72d94e7383b7765350cca491045266279bdbbad26d4397e35c99fcfdb5d3055627c5e75b6c766749217908cd53e383d4a7344e",
  "tags": [
    [
      "base",
      "7fcc945b352591f0a793c10af52a32ef65392960"
    ],
    [
      "origin",
      "git://jb55.com/git-nostr-tools"
    ],
    [
      "branch",
      "03471cd1237a7e8ae76fc4050e46161fc102709f",
      "rust"
    ],
    [
      "subject",
      "my pr"
    ],
    [
      "t",
      "git-nostr-tools"
    ],
    [
      "p",
      "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
    ]
  ]
}

@OpenSourceOptimist
Copy link

OpenSourceOptimist commented Apr 16, 2023

@npub1zenn0

Doesn't a patch based workflow work better over nostr?

Patches fit very well with nostr and I think we should support it for several reasons (see #223 (comment)).

On the other hand PRs is the dominant way people interact with git these days. PRs are just like @jb55 says still useful. But most of all they are familiar.

We might be best of supporting both references to commits on git servers and patches in the protocol but having in mind that it should be easy for app developers to present everything as PRs because that is the most familiar.

@npub1zenn0
Copy link

npub1zenn0 commented Apr 16, 2023

Right, pull requests are indeed the de facto way at this time. However, making Gerrit work over nostr should be the low hanging fruit. I would like to guess it possible to have an MVP Gerrit instance open with a separate micro service that looks at nostr and posts into the Gerrit instance as admin, in reasonably short time.

Then again if a PR version is done and well, could do the same with a gitlab instance.


And on this NIP: Git LFS was brought up npub1zenn0/go-git-nostr#1 . There should be a tag for including lfs pointers. Maybe something like ["lfs", "filename", <pointer_to_NIP_81/94_event>].

@gedw99
Copy link

gedw99 commented Apr 16, 2023

Thanks @npub1zenn0

yes a pointer is exactly what’s needed

@fiatjaf
Copy link
Member

fiatjaf commented Apr 16, 2023

What is the difference between a PR and a patch? To send a PR you must have a git server to point to, but to send a patch you don't need that?

In terms of UX both should be equivalent, no? You send the patch and people can comment on the patch and ultimately opt to "merge" the patch or not.

@npub1zenn0
Copy link

I make the distinction in that a patch is something you overwrite (mimicking force push) if you change it, while a PR is something with a branch that you push new commits onto.

@jb55
Copy link
Contributor

jb55 commented Apr 16, 2023

What is the difference between a PR and a patch? To send a PR you must have a git server to point to, but to send a patch you don't need that?

patches are just a textual diff to a file, and applying patches has no link to the previous history. In certain contexts merging a branch is the only allowed workflow to preserve history and auditability. bitcoin-core works this way. Also sometimes you need to merge large chunks of code at once. Linux/linus himself uses PRs to merge large subtrees of changes, whereas maintainers collect patches into their branches for Linus to merge. They serve two different purposes, I don't think there should only be patches on nostr, since it doesn't cover the uses cases of merging large subtrees and preserving commit history.

@gedw99
Copy link

gedw99 commented Apr 16, 2023

Great conversation

https://github.com/icyphox/legit/blob/master/go.mod#L7

this might help !! At least for something to experiment on ….

it does unified diff .

The way it does git diffs and merge is clean, and it just happens to be a git server and gui in 100% golang .

It’s highly stable. I have been using this for a few months.

@DanConwayDev
Copy link
Contributor

Excited to see such an active discussion. This is slightly alternative architecture and how a NIP like this could fit:

blob storage and retrieval

There are different viable models to store, serve and retrieve data in a way that present like a standard git server/client interaction. This may be using a standard git server on a niche relay with a nostr permissions wrapper, or using a client to mimic this delivery whilst abstracting an alternative model under the hood. There needs to be experimentation because getting the incentives right for actors to serve the underlying data is challenging given that storage and bandwidth is expensive.

Interactions with git servers and relays should be trust minimised. Nostr events following a NIP standard should prove every change made is authorised by an maintainer. Other clients and relays that want to sync with the git server which was pushed to must be able to pull the update from the git server, verify it using the nostr event before writing it. Clients cloning a repo should be able to use available events to validate they have the complete and unadulterated repository as of the date of the last Nostr event they received.

Some models for delivering git data might use Nostr events to store git metadata and store blobs using torrents. Some might use a standard git server. Both would support the above NIP and would only accept write changes that have been signed. Bridges could enable repositories to be stored using multiple models. This would reduce entry barriers repository maintainers wouldn't have to choose one model.

Collaborative Software Development Experience

A vibrant array of clients, serving different aspects of the software development collaboration experience will emerge. micro-apps might address a single feature and other clients might support many: Kamban boards, issue tracking, comments on lines of code, PR review, etc.

Clients would utilise anchor points with a standardised referencing schema outlined in a NIP for elements both inside a git repository (lines of code, commits, etc) and outside the git repository (PRs, issues, kamban boards, etc).

These NIP(s) would facilitate innovation at the storage and retrieval layer and the collaboration experience layer to proceed independently.

Any thoughts?

Note: I just published a NIP-23 article entitled The Bull Case for a GitHub Alternative on Nostr, which might add some context.

@gedw99
Copy link

gedw99 commented Apr 18, 2023

Start with a Unified Diif capability that is the core of what git does , so that just like git the client can diff and send in patches and the relay can apply those patches.

@DanConwayDev
Copy link
Contributor

DanConwayDev commented Apr 19, 2023

@gedw99, if we work purely off a patch model:

  1. We wouldn't be able to carry out maintenance involving rewriting history.
  2. It would be inefficient from a storage and bandwidth point of view. Particularly for the data relays, for which we might have an incentive challenge.
  3. Users would have to change their normal workflow which creates additional switching barriers.

I wrote a follow up article entitled Key Challenges for a GitHub Alternative on Nostr. In it I suggest standardising the 'anchors' between the social experience and elements in a repository (eg. commits or line of code) as the first standard to agree in this usecase. This could be a soft-standard or a NIP. Doing this would enable developers working on the social experience and those working on the git repository side, something to work off.

@gedw99
Copy link

gedw99 commented Apr 20, 2023

@gedw99, if we work purely off a patch model:

  1. We wouldn't be able to carry out maintenance involving rewriting history.
  2. It would be efficient from a storage and bandwidth point of view. Particularly for the data relays, for which we might have an incentive challenge.
  3. Users would have to change their normal workflow which creates additional switching barriers.

I wrote a follow up article entitled Key Challenges for a GitHub Alternative on Nostr. In it I suggest standardising the 'anchors' between the social experience and elements in a repository (eg. commits or line of code) as the first standard to agree in this usecase. This could be a soft-standard or a NIP. Doing this would enable developers working on the social experience and those working on the git repository side, something to work off.

thanks @DanConwayDev just read the blog and i see the history rewrite aspects and time ordering. very well written. Ordering of mutations in an offline first collaborative system is an age old problem ( CRDT, etc etc ). If we can get this right, then rewrite history with UDIff presents a archetype for all collaborative systems with a git baed file system ?

@DanConwayDev
Copy link
Contributor

@gedw99 thanks for you feedback.

Ordering of mutations in an offline first collaborative system is an age old problem ( CRDT, etc etc ).

We could follow the model I outlined in 'The Conflicting Change Problem' section of the article I referenced above, with each 'Authorisation Event' referencing the previous mutation it was building upon. Do you think this model is workable? It is dependent on solving the 'Group Authorisation Problem' which I hope to be publish an outline solution to soon.

If we can get this right, then rewrite history with UDIff presents a archetype for all collaborative systems with a git based file system ?

We could establish a standard for a new type of patch that supports all possible mutations of the repository. This could be based on the existing git patching model and UDiff. a client wrapper could simulate pushing and pulling from a remote git server whilst operating entirely through patches.

I still feel patching is an inefficient model and the state reversion problem is better solved in a more elegant way. For example, Authorisation Events compactly including diffs in git/refs. The beauty of a standard for Authorisation Events is that the patch model, as well as other models could be built out and maintain compatibility as I discussed in the 'The Interoprablilty Problem' section of the article.

@gedw99
Copy link

gedw99 commented Apr 21, 2023

@gedw99 thanks for you feedback.

Ordering of mutations in an offline first collaborative system is an age old problem ( CRDT, etc etc ).

We could follow the model I outlined in 'The Conflicting Change Problem' section of the article I referenced above, with each 'Authorisation Event' referencing the previous mutation it was building upon. Do you think this model is workable? It is dependent on solving the 'Group Authorisation Problem' which I hope to be publish an outline solution to soon.

If we can get this right, then rewrite history with UDIff presents a archetype for all collaborative systems with a git based file system ?

We could establish a standard for a new type of patch that supports all possible mutations of the repository. This could be based on the existing git patching model and UDiff. a client wrapper could simulate pushing and pulling from a remote git server whilst operating entirely through patches.

I still feel patching is an inefficient model and the state reversion problem is better solved in a more elegant way. For example, Authorisation Events compactly including diffs in git/refs. The beauty of a standard for Authorisation Events is that the patch model, as well as other models could be built out and maintain compatibility as I discussed in the 'The Interoprablilty Problem' section of the article.

Hey @DanConwayDev

Can i answer in general for now, as i read your blog article and the other things and it makes sense but the jargon is a little vague.

If we don't allow for offline mutations, which we don't AFAIK. Then it is a matter of ensuring all mutations are globally ordered, just like any async message broker architecture The tricks i know to do that are:

  • time smeer clock to avoid leap year hell. AWS and google run these in there DC, and there is golang implementation.
  • time ordered rewrite buffer. Because there is a delay between a mutation send and arriving you have an in memory buff on the server that collects them and reorders them before letting them through to the Server proper.

Then your all set.. You can also then run subscription queries, where a query for data causes the actor to be added to the presence map and so then when any data changes on the server / relay all actors get a CDC like CUD event, which they use to update their local copy of the data. Very standard stuff for this area. Why do this ? because then the clients never have stall data, so when they later send a mutation, it's a mutation based on up to date data, and so you massively reduce the number of validation through backs from the server.

I guess you can think of this as a best practice way of ensuring linearizability, but not inside a DB but outside one. The old "Turning the database inside out" by Martin Kleppmann ...

Web Clients - You can do this inside anything. These days a Service worker PWA for example. So this model support web apps too. Indexed DB limits you to 50 MB non deterministically, so some cache eviction strategies are needed. I only say this because i see most Nostre use cases with their only being a Relay, and then Clients. Some Use cases however might be a proper durable server being fed off the relay too and then clients talking t the Server ? don't know....

I hate being so general about he patterns, but again its seems like Nostr is really imitating this classic pattern above. Hope this is helpful in some way ??

@DanConwayDev
Copy link
Contributor

@gedw99 Thanks for taking the time; that was helpful. I thought it best to flesh out my proposition a bit more to allow for a more specific critique. My proposal for authorisation groups is outlined in this NIP draft.

I have traded-off simplicity of design and implementation against speed of state change confirmation. The needs here are medium-low frequency of changes so I don't think change conflicts are going to be a regular occurrence. Most users interact asynchronously at low-frequencies with git services. CI/ID and webhooks less so...

@gedw99
Copy link

gedw99 commented Apr 29, 2023

hey @DanConwayDev I

see what you mean about speed of changes being low and so mutations very likely to be ordered and life is good then. Its a good solution and i agree it's the least worst path forward. Its always "what is the least worst solution" in software and engineering :)

CRDT etc is YAGNI if this works.

thanks for taking what i said into consideration.

@DanConwayDev
Copy link
Contributor

https://ngit.netlify.app/
https://github.com/DanConwayDev/ngit-cli

I wrote a prototype under the name ngit that builds on the patch model but brings it closer to PR workflow.

pull, push and even clone and merge are achieved by applying patches issued as nostr events.

There are events for repos, branches, patches, PRs, merges and groups.

A patch is always applied to one 'branch'. A 'branch' isn't reissued to refer to the latest commit like in git. Instead it is just an id linked to a repo that patches can be associated with.

Merges indicate that a patch from one branch is applied to another branch.

PRs indicate a desire to merge one branch into another. Comments and further patches can applied to a branch as the conversation around the an associated PR continues.

Groups manage the permissions on branches so that maintainers and authors can add patches to PR branches and only maintainers can merge or commit directly to the main branch. This partially implements the Nostr Groups draft NIP.

The patch application process is adjusted so that commit ids are preserved which addresses the history and audibility needs of projects like bitcoin core.

@lonerodriguez
Copy link

All that said, it was a fun experience, I learnt a tonne of git internals along the way so it wasn't a complete waste of time but I think it might be time I hang up the boots on this one. If anyone want's to discuss how a git-server model may look, I would be up for discussing / working on something.

hello hendore, is there a possibility to try out/download your client? I think the presentation is pretty good and I would like to work on it further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.