HackMD
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # SSB Protocol Design Call 30/06/2019 Attending: - Aljoscha - christianbundy - cft - arj - dominic - cryptix - Staltz - rabble ## Agenda - note taking? - how long do we have? - Discuss [@christianbundy](@+oaWWDs8g73EZFUMfW37R/ULtFEjwKN/DczvdYihjbU=.ed25519)s [off-chain content](%LrMcs9tqgOMLPGv6mN5Z7YYxRQ8qn0JRhVi++OyOvQo=.sha256) thread - Slowly rolling out changes, or one big change? - [@cft](@AiBJDta+4boyh2USNGwIagH/wKjeruTcDX2Aj1r/haM=.ed25519) will present birch I have a feeling that some of issues to be discussed are highlighted in the [summary diff](https://github.com/cn-uofbasel/ssb-birch#quick-summary-of-differences-jun-1-2019-to-bamboo-and-arj03s-variant). - Hamburg preparations ## Notes ```abc X:1 T:Speed the Plough M:4/4 C:Trad. K:G |:GABc dedB|dedB dedB|c2ec B2dB|c2A2 A2BA| GABc dedB|dedB dedB|c2ec B2dB|A2F2 G4:| |:g2gf gdBd|g2f2 e2d2|c2ec B2dB|c2A2 A2df| g2gf g2Bd|g2f2 e2d2|c2ec B2dB|A2F2 G4:| ``` ## offchain content - Dom thoughts on offchain-content: - one option: treat as new encoding type. in replication, send metadata and content as one thing. - cft: let's take a step back, big picture - there are things in the metadata we don't want to be deletable - e.g. follow information - what exactly are those things? What is the chain about? - cb: - 100% confident: shouldn't be able to delete deletion requests - changing feed types? - arj: do we even want delete? Immutable logs with deletions are an oxymoron - cft: things that can be offchain are application stuff, things that can not are about chain management - dom: (implicit agree), but: follow messages are application layer - alj: to me, offchain content isn't about deleting from the logical log, just for deleting from a local replica - cb's proposal diverges from that Cft: How do we deal with invalid feeds? ignore? bork the feed? (Alj thinks this is a *really* important question) alternative blob reference approach, msgkey hash with object path to the blob ref or mention (?) # transcription [00:00] alj: awseome .. also +1 on... <audiotear> [00:22] cft: ... i continue: so if we could quickly do one step back and understand what we are trying to achive and maybe also a little bit in the long run with the offchain-content. and let me start maybe the discussion in the following way: there are things, i guess, which should be in these event logs (or metadata) which should not be deleted at all. for example, things that are directed to tell the network layer what to do if you follow somebody. you shouldnt be just deleting that. it really has to be really in the log forever. because otherwise the network... as soon as you ask "please forget this entry", has it to go back and see that entry, was it because you followed somebody? does that mean that you are unfollowing somebody? so i think we should be clear what has to be in the chain, what can be offloaded/offchained? all that is for me not clear at all and before we even start, lets call it hacking, and i denfinitley would like to expand on the naming of these attachments, how i call them. can we quickly look at what the chain is about and what should go offchain content inside these parts? [01:45] cb: yeah. One thing, so.. I try think about this and then start enumerating possibilites and there were too many.. the one thing that i'm 100% sure, well.. that i feel very confident about is that we shouldnt be able to delete deletion requests. because uhm that ends up with a strange scenario where you can delete a message that's asking people to delete a message of you deleting a message..? so i think there are definitly going to be things onchain. deletion requests should not be off-chain, i don't think. and i'm not sure if there are other things on the network level. so if you can change a feed type, that should probably stay on chain. yeah, i think it would be usefull to enumerate those. [02:35] arj: there is also the question if we even want deletes. I mean, the current design is very sort of pure in the way that is an immutable log that just keeps on growing forever and ever. I can see some of the use-cases for this deleting of content but we just have to realize that is a very different model, in a way. so I'm not saying that it's good or bad just that it's very very different. <audiotear> [03:00] cft: ..application stuff. but things that have to stay in the chain really is about the chain-managment. maybe let's call it that way. [03:34] dom: on your previous example of follow messages: I think I would not consider it a problem to replicate...? that you have not posted a follow message for. and you can follow peers.. uhm. like, you can post a follow message that is encrypted, so no one else can see it. that currently works. Im a bit weary because.. I mean, keeping messages having always is simple. Having messages always in offchain content, but usually its just sent: that's also pretty simple. but having both sometimes messages in the offchance be ... in the like non-deletable content... then how does that get enforced? and i think if you have offchain content, you basically can't enforce whether something should be in offchain content or not. unless you just ignore that are types that arent offchain.. so I worry that this solution is just quite complicated. [05:32] alj: kind of exapnding on that: In my mind offchain content isn't about being able to delete content from your feed. it's just about being able to locally delete data from a feed replica, while still maintianing the ability to replicate that replica to other peers, well except for the stuff you deleted obviously. still, on the logical level, the log would still be an append-only log. and that's where christianbundys thread divereged from my previous suggestion for offchain content. because in that thread it was more like we effectivly don't have append-only logs anymore and i'm very skeptical of that. [06:32] dom: so what I'm thinking about is just an offchain-content where you are receiving a message (..?) and just not sent the content. for whatever reason they have for doing that (not sending the content) thats their decision. but you could always when your replicating just say "oh i don't have that content" and if someone doesn't like that, they could ask someone else for that content. [07:27] cft: can I ask about what you call metadata. This is.. lets call it the naked chain information. Who wrote it, which sequence number and what is the previous hash. that's more or less... [07:40] dom: correct. just the absolute minimum metadata for replication. [07:50] alj: actually for verification. dom: yea. [07:52] cft: could there be also maybe be a little bit more than just the hash to the content. namely the size? that could maybe be a decision if you want to fetch that content at all or not. [08:10] cb: i think that's usefull. the implementaion i have does have size... <audiotear> [08:18] dom: yea i think i recall aljoschas proposal includes a size. [08:27] alj: it even enforces it. if what you just described happend, we consider the feed broken and stop replicating it. [08:40] cft: yea, probably ignoring would be a safer decision than just ending the feed. what about having multiple contents, what I suggested in burch as having attachments? .. okay. the silence is a not so enthusiastic reaction, i see. so i try to make a little bit of advertisment for that: the reason why I came up with the attachment thing is that, you want to be very selective and also be able to name the different pieces. so think about one post and it has three pictures. so you would have four elements, the post text plus the three pictures. and some clients would like to be, just picking the texts, or the others could be "okay I want the 2nd of the three attachments" or things like that and that comes then to the naming of these things. it would help to introduce names to sub-content by that venue of attaching things, like we have in MIME. [10:09] alj: so what is the advantage of baking that in the protcol instead of just publishing a message that... <audiotear> [10:16] cft: so lets call it a manifest. so the content would be a manifest, and inside there you would enumarate all the possibilities.. other problem.. if you look at christianbundies suggestion that we have alternting metadata and content pieces.. you would have one big... <audiotear> added to the feed if they are not independant [11:00] alj: i think thats more from a replication concern then actual feed structure concerenc because. if i understood you correctly, if we had it as part of the metadata, multiple contents then during replication you could specify which attachments to inline and which not so sent. did i get that part right? [11:40] cft: i have to think about that, maybe you are right. somehow I wanted smaller granulatiy but you are right that this targets at the replication time not ncesessarlitly rendering time. i have to think about that [11:55] alj: yes and uhm.. one addtional point: then we can get to the sort of.. uhm.. dominic posted this thread about transistivly fetching cipherlinks basically. where i draw this comparssion to captnproto and what was it called? future chaining something..? but basically we could do that as well for those sort of manifest contents. so i don't thinkt that there are actual performance and roundtrip gains that we could only get by adding them as part of the metadata. i think a clever replication protcol can always offset that. [12:40] arj: and I also think that is really important to keep the core protocol as simple as possible and then built the other things ontop of that. because later on you might be able to put in all kinds of clever replication tricks that you didn't think about in the beginning afterwards. [13:04] dominic: idea here, we currently have EBT replication stream which just send messages, each message that comes through is a message with or without content. And then have another stream that is a blob push protocal, in this I'm saying whenever you send me a message just send me the blobs that message mentions without having to ask for it. This would be an independant feature that users can turn on/off. More push style that is selective for specific types. [14:28] cft: my concern is when trying to stich things together in my mind is the naming of the content. If we would have like bundy's suggestions, inline of the content with the metadata we have a natural naming schema. Say event.0 is the metadata, event.1 is the content, evnet.2 is an attachment etc. If we don't have that the only name we will end up with is the hash and that is the thing I'm really reluctant. A simple namespace. This is such a stress to build distribution systems for flatly named content. [15:27] alj: my main response to that is. Blobs are basically a flat namespace. we could just have rpcs that lets say please give me this blob by hash and btw I know that it was referenced in the following feeds, then that information can be used. I think that is more general because you can specify multiple feeds. [15:56] dominic: I think Christian means things like say you have a message and content points to several blobs. How do those blobs relate to that message. You attach the extra links at the bottom and then you say the 1,2,3 etc. Another option I'd like to suggest is you have path into the data. The content is a structured type that has keys and values. Currently you have mentions, that is an array and then you could take the fourth one or any mention that points to a message. You could say things like that. Any blog posts has a blob link, so you could describe push these items that are on this path inside the content. The way you refer to that blob is that you do by hash or you could refer to it by the message id / path. Like IPFS. Does that make sense Christian? [17:49] cft: absolutely, I see that would replace the numbering. It would mean content is really attached to the seq no. We would have 2 parallel feeds: metadata, each entry is numbered and content where each is also numbered. It would be more explicit than the hints. [18:37] alj: you would still need to be able to verify the data. It wouldn't make sense to say go into this object and path xyz because the hash needs to be known. [19:05] dominic: the path would start with hash of msg, id seqno, and then you have the path inside of that object. You could receive that message and then requst parts. [19:30] alj: you said whole message, aren't we talking about cherry picking? [19:51] dominic: a way to reference blobs inside a message, not about receiving a part of the msg. [20:25] alj: at which point does this need to be part of the core protocol? [20:40] dominic: higher layer, doesn't need to be part of the msg replication protocol, interesting side protocol. A way of addressing Christians use case. [21:00] cft: good question alj. Lets go back to delete individual things. If we always have to delete the whole content, makes a diff to only delete a part. [21:25] alj: say we have offchain content, then you are free to delete not the whole message and only keep some of it [22:00] arj: would still be nice to have a way to say that I only want to delete a certain part of my message by speciying the path [22:10] alj: my understanding that delete is a local operation [22:25] dominic: not advoating deleting the text part of a message because then it won't validate, blobs are simple [23:00] alj: again, local operation [23:05] dominic: it is, if you post a message that asks other people to delete that you have thought globally but acted locally. [23:26] alj: application layer, right? [23:30] dominic, arj: yes [23:35] cft: confused. If you delete locally you can't help replicate, and if you have holes in the content then you can't validate? [24:00] alj: you can still validate because you delete the content, but you keep the hash. Hash is enough for validation. No content. [24:23] bundy: if the msg specifies a size and you don't have content to give them, would they validate? [24:38] alj: good question [24:50] cft: if you selectively delete from a message, you would how to specify how you validate. Is it concat of all the bytes? Tree of hashes? [25:12] alj: not sure there is a need to validate the message again. You get a message once, check it, that's it. After that you can delete [25:50] cft: if you a message, everything was there except 1 image. How would you handle that? [25:12] alj: Don't care. Your decision [26:00] dominic: don't need the image to validate the msg, you just need to check the hash. The signature still signs the image, that means if you do get the image later, you can verify that this was the missing image. Don't need image to check signature. [26:30] cft: coming back to the multipart msg. 3 things: metadata, text, image. Someone says forget the img. From now on there is no img anymore. How do you check that the rest is correct without the image? [27:00] alj: you would get that for free, if you just to what we currently do with the manifest approach. Only sign the manifest. [27:25] cft: what is really signed? Not the bytes of the content, the bytes of the manifest [27:37] alj: no, bytes of the hash of the manifest. Because the manifest is just the content of a msg. Nothing special about it. [27:47] cft: agree. In the prev case you would concat all the bytes and that would be the content. No substructure. Would the manifest thing have to be made official? [28:09] alj: I don't think so. Why would it need to be? Just application data? [28:25] dominic: correction. I propose calling it platform layer, the replication protocol doesn't care about that. Just bytes. Agree on a good format to encode this data. We can't really stop someone from doing something completely different. People tend to choose the same thing ;) [29:00] alj: thanks, self-describing format implicit. Please don't use json [29:17] dominic: yes [29:20] cft: platform layer would then look at the manifest. Needs to be specced to delete specific parts. Right? [29:40] alj: selective delete, where? [29:43] cft: same case, text and image referenced in a manifest. Protocol layer can validate even if image is missing. Correct? [30:17] dominic: yes, manifest would be official. But seperate discussion. Encoding is independant of this. [30:40] cft: ok. Still have flags, when feed is terminated. Not off-chain? [31:10] all: yes [30:40] cft: might there be more than one 1 bit? [31:40] bundy: yes delete would be one one type, ssb mutual credit have problems if not stored on chain [32:25] alj: to clarify, bamboo supports a whole byte. Will be need for more types [33:28] cft: delete is platform layer. So not part of core protocol? [33:40] alj: agree [33:45] arj: you have a short int, what the different numbers mean doesn't have to be part of the core protocol [34:20] bundy: you should still be able to post on-chain content messages for backwards compat. [34:38] dominic: current msg type works like it does. Offchain would be a new encoding type, not json. On-chain = current method. Not 1 that can do all. Simple as possible. [35:30] bundy: great if it was a different msg encoding, with offchain content and a bunch of different features. My goal is to make it as simple as possible to move from now to the next iteration rather than giant leaps. Iterative. [35:55] dominic: small iterative changes are great but in an immutable protocol, means you have to support all the quirks forever. We want to do enough work to iterate on db, that can change. No hacks. Future is a lot longer than the time it takes to get this out. [36:56] bundy: scope? 3 month, 2 years? [37:25] dominic: Good question. this year. [37:40] alj: make sense with 2 efforts? 1) incremental (json still, add limpaa) 2) full redesign [38:30] arj: work together on a design that can be rolled out in the current implementation and not have to redesign everything [39:00] alj: always dissapointed if we have to support the old stuff [39:25] dominic: thats life [39:30] cft: ambition to have a future proof design? Can carry a long way beyond json. [40:00] bundy: what is a new feed type? [40:40] dominic: moving to a binary protocol is not that hard. Migrating the impl. will be a lot of work. New feeds is going to be easy if they don't require massive architectural changes on the inside. We could support limpaa links and still do normal replication. Off-chain content: msg validation is the hash, not the content. Application layer ignores if empty. Take our time getting it supported by applications. That part could be incremental. [42:42] alj: limpaa links is a minor version bump. [42:50] bundy: Would these need a new feed type? Can have limpaa in json? [43:10] dominic: def. a new feed type. Breaks validation. [43:25] bundy: To use a new feed type, is that a message you post on your feed? Or a completely new feed? [43:40] dominic: new feed with a new public key. Same-as good idea. Different discussion [43:55] bundy: do we need a new feed type? You could push messages with new encoding [44:10] dominic: more confidant that a new feed won't cause problems. What is you have old, new and the back to old again? Then you have holes they can't validate. Easier with 2. Just go back. [45:00] rabble: same identity? [45:10] dominic: tag at the end is different. Current @ base64. ed25.. is the legacy js style. I would encaurage people to use a diff key. Not sure if it will break. Safer with different key [46:00] rabble: same as working then? [45:10] dominic: can be done incrementally [46:20] rabble: social aspect [46:25] alj: simpler if we don't use old feeds. Ordering issues goes away [46:45] rabble: all follow that rule? [47:00] cft: question for bundys proposal about ordering of content and then metadata. Strange? [47:20] alj: replication issue, not signing [47:30] bundy: replication part of protocol? [47:40] alj: not at this level [47:50] cft: summarize thinking, like dominics idea of two streams. How is off-chain content delivered? [48:20] bundy: I didn't want a situation in the js implementation where a msg was added to the db before the content. No db rebuild. It is a bit arbitrary. [49:10] dominic: Christian I think there are more ways to skin this cat. When you receive a buffer that is the message. You don't have to have take those bytes and hash them. You can have a format.. [49:50] cft: confused. Lacking the overall view. Which channels, how is that thing coming to me? If there is seperation between off-chain content and metadata? [50:10] dominic: that was what bundy was sugggesting, I was going to suggest a way that could basically make. It would be exactly like the current behaviour where massages come one at a time, except they would come as buffers instead of json objects. And different rule for hashing them. You looked at the msg and just hash the metadata not the content and that was the id for that msg. Still 1 item that goes to the db, this would be easy to port the current protocol. Behave exactly the same. [51:00] cft: not following, what do you mean by, is coming as buffer instead of json? Can't parse ;) [51:10] dominic: in the muxrpc, each msg has a framing, these chunks come through. In EBT you have a stream, messages grouped into a stream, but each message has a little that says its this type, part of this stream, this long, and if its a string or json or buffer. [51:50] cft: I see. The scenario you explained is valid for something that only has the metadata, the off-chain content has been deleted? Works for both in combination? [52:05] dominic: both in combination [52:10] cft: which sequence? Content or metadata first? How do I know that content is missing? [52:25] dominic: I would put the content after, because then you can parse. Not sure if this is quite true. Could be the metadata would be a fixed size, or more limited size. Content is bigger, so you could skip content. [53:00] cft: natural for me with content after. Bundy suggested the opposite. That was why I was puzzled [53:20] alj: third suggestion, start with a boolean indicating whether the content is missing or not, then the metadata, then content. [53:29] dominic: Thats good [53:39] bundy: for muxrpc, to encode the boolean, metadata and content as a string and use a delimiter between them? Or binary? [53:56] dominic: yeah, that is why I wonna do this with binary format. [54:00] bundy: understand [54:56] alj: think we should nail down exactly what feed types are [55:00] dominic: top level item Call in two weeks, alj and arj can't attend. Hamburg is coming up in 3. [57:00] alj: opening up? [57:20] dominic: Against that, need to focus. No beta. The people interested know. [58:00] bundy: somebody can join? [58:20] dominic: sure

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully