From 179a8899e4c14d8c9f7b2cfe19f4d0e69ad60f39 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Wed, 25 Mar 2020 08:56:03 -0500 Subject: [PATCH] Update README. Closes #2 --- README.md | 24 ++++++++++++++++++++---- diagram.md | 32 ++++++++++++++++++++++++++++++++ diagram1.png | Bin 0 -> 18898 bytes 3 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 diagram.md create mode 100644 diagram1.png diff --git a/README.md b/README.md index 9708def..f50fa53 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ Below are some possible use cases to illustrate real-world applications. Once pr * Secure Scuttlebutt import / export / gateway tool * A newsgroup / NNTP analog * A social mapping / point-of-interest sharing site - * A play-by-mail (or bluetooth) file sharing app + * File sharing app that operates over Bluetooth + * A compatibility gateway between Secure Scuttlebutt and Pigeon messages. * A turn-based board game * An IoT data logger * Sync a feed over email (via external tool) @@ -98,6 +99,8 @@ signature AerpDKbKRrcaM9wihwFsPC4YRAfYWie5XFEKAdnxQom7MTvsXd9W39AvHfljJnEePZpsQV ``` +![A hierarchy diagram showing how the message in example 2 points back to example 1, and how example 1 points back to NONE](diagram1.png) + # I Have Internet Access. Why Should I Care? * [How Iran Turned Off the Internet](https://thewire.in/tech/how-iran-turned-off-the-internet) @@ -117,7 +120,7 @@ signature AerpDKbKRrcaM9wihwFsPC4YRAfYWie5XFEKAdnxQom7MTvsXd9W39AvHfljJnEePZpsQV # Prior Art -Pigeon borrows many of the ideas set forth by the Secure Scuttlebutt protocol. It is my opinion that SSB is one of the most innovative protocols created in recent years. Without the research and efforts of the SSBC, this project would not be possible, so a big thanks goes out to all the people who make SSB possible. +Pigeon borrows many of the ideas set forth by the [Secure Scuttlebutt protocol](https://ssbc.github.io/scuttlebutt-protocol-guide/). It is my opinion that SSB is one of the most innovative protocols created in recent years. Without the research and efforts of the [Secure Scuttlebutt Consortium](https://github.com/ssbc), this project would not be possible, so a big thanks goes out to all the people who make SSB possible. I've also been inspired by the compactness and minimalism of [SQLite, which should serve as a role model for all of us](https://www.sqlite.org/talks/wroclaw-20090310.pdf). @@ -127,7 +130,7 @@ In many ways, this protocol can be considered an amalgam of the best ideas from * Configuration is bad and should be considered a design comprise in nearly all situations. We will allow a limit of 10 configuration options for all eternity. These are simple key/value pairs. No nesting, no namespacing, no dots, no dashes, no nested config names, no arrays, none of that crap. Seriously, I'm watching you. * No singletons. No signing authorities, no servers of any kind, even locally, no differentiation between peers (eg: no "super peers"). - * Offline-first. Never incorporate TCP or UDP features ever. Such concerns must be handled by application developers. This is to ensure that the protocol is always a viable option for off-grid use cases. + * Support Offline-first by being offline-only. Never incorporate TCP or UDP features ever. Such concerns must be handled by higher-level protocols or by application developers. This is to ensure that the protocol is always a viable option for off-grid use cases. # Roadmap @@ -135,12 +138,16 @@ In many ways, this protocol can be considered an amalgam of the best ideas from This is the brainstorming phase where the initial proof-of-concept clients will be written. The first protocol client will be slow and may not be suitable for embedded use within a larger application. +This phase is complete when there is at least one functioning client implementation. + ## Phase II: Build a Working Application Using the protocol client from phase I, build an application which uses Pigeon for simulated real-world conditions. This phase will allow for discovery of problems with the draft specification and the first client implementations. Please see the "What's Possible" section for a list of applications that may be published. +This phase is complete when there are at least two applications (rather than libs or clients) that utilize the protocol. + ## Phase III: Client Improvements Once a gauntlet of applications have been built and outstanding design problems have been addressed, re-write existing client libraries. Unlike the client built in Phase I, the clients built in this phase will have a focus on: @@ -150,16 +157,26 @@ Once a gauntlet of applications have been built and outstanding design problems * Portability to targets like WASM, embedded systems, Windows, etc.. * Ability to be embedded into existing applications. +This phase is complete when: + * There is a client library that is written in an embeddable language (C, Rust, etc..). + * There is a client library that can performantly serve a mesh of more than 15 peers in a real-world application. + +Nice-to-haves for this phase: see the implementation of a WASM and bare metal (embedded) client. + ## Phase IV: Finalize v1 Spec Once a production-grade client exists, the focus will then become documentation. Using the knowledge gained from phases I-III, we will re-write all documentation, possibly using Gitbook or similar services. Version 1 of the protocol will be considered complete at this phase and the protocol will be considered "ready for production use". +This phase is complete when the "Pigeon Protocol Handbook" is authored. The handbook will be a guide less than 100 pages long, that can be read by a developer from start to finish (as opposed to being referenced) to help them start writing Pigeon applications. + ## Phase V: Stabilize, Maintain, Proliferate With a finalized spec and a portable client library, the next goal is to promote the product to as many developers as possible and continue to author software that is well suited to the protocol. +This phase will be considered complete when there are three production-scale apps using the libraries authored. By this point, we've hopefully made a difference and helped people regain control of their data and find a new alternative to the current status-quo of "online only" computer applications. + # Unanswered Questions * Ephemeral key exchange @@ -167,7 +184,6 @@ With a finalized spec and a portable client library, the next goal is to promote # The Initial Implementation Should... - * Allow for importing/exporting to SSB via plugins. * Prefer a monolithic internal structure. Avoid external dependencies except for limited use cases (Eg: crypto libs). Do not break things into smaller pieces until there are at least three real-world reasons to do so. Decoupling a library into a package for only 2 use cases is not acceptable. * Assume CPU and RAM are not plentiful. * Assume platform has no networking support. No servers. No hooks for startups, shutdowns, or reboots. diff --git a/diagram.md b/diagram.md new file mode 100644 index 0000000..9046906 --- /dev/null +++ b/diagram.md @@ -0,0 +1,32 @@ +Edit this diagram at https://mermaid-js.github.io/mermaid-live-editor/#/edit +```mermaid +classDiagram + None <|-- Example1: None + Example1 <|-- Example2: @DYdgK...Cve04=.ed25519 + + class None{ + empty + } + + class Example1{ + author @DYdgK...Cve04=.ed25519 + kind hello_world + prev NONE + depth 0 + + hello:"world" + } + + class Example2{ + kind hello_world + prev NONE + depth 0 + + key1:"my_value\n" + key2:"my_value2" + key3:"my_value3" + key4:%jvKh9...bvzGM=.sha256 + key5:&29f39...e6ca3.sha256 + key6:@galda...WJccg=.ed25519 + } +``` \ No newline at end of file diff --git a/diagram1.png b/diagram1.png new file mode 100644 index 0000000000000000000000000000000000000000..9c5cc73f1d7b2fd3e8439408c634b3e06fbb2e56 GIT binary patch literal 18898 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 literal 0 HcmV?d00001