As an example, at the Picasoft non-profit, we host an alternative messaging app, facing the web giants. If a bot accesses the server, it can retrieve all their conversations, which is true for any online service.
If this is true, please fix your messenger and add e2ee. A simple version with great UX has many problems but this is exactly what it (mostly) solves.
Can we please also talk about how commits are actually weird in git? Like, a commit is a state of the repo identified by its hash. Except when you do basically anything with commits like merge or rebase a branch you’re really talking about the changes that this commit made. Hell, if you look at a commit you see the diff of changes. And then every commit changes its hash on a rebase which was supposed to identify it. Great.
Also, have you noticed that when you make a PR on Github, and you at some point merged main into your branch to update, there is a merge commit in your branch which actually disappears after the PR? Sure, that’s kind of what you want but it’s not at all obvious why this happens.
And if you have some kind policy of not changing history and you start using revert then git sabotages you when you try to merge again after a hotfix it will just ignore your commits because it thinks it already has them but doesn’t think about the fact that they got reverted. But don’t worry, git tells you about this WHEN IT’S TOO LATE. It will go “Well, I guess you shoulda used --reapply-cherry-picks, now I threw those commits away. Sucks to be you. Go restore your state!”
Strangely, cd foo/**/bar doesn’t work here. It gives me “cd: string not in pwd: foo/inner1/inner2/bar” but I can copy that string and it works just fine. So, maybe not the greatest UX on that feature. :D
The out-of-the-box behavior of disabled buttons and inputs is pretty atrocious, both from an accessibility standpoint and from a usability standpoint. This article talks about a very specific situation in which a developer might be tempted to disable a form submit button to prevent duplicate submissions. However, there are many other cases where a button should be disabled but still be focusable.
Taking the form from the article’s the example, say a user entered invalid or incomplete content. They should not have to press the submit button to learn that it doesn’t work. It should look disabled and it should also be possible to show a tooltip on focus and hover saying why it’s disabled. This is currently impossible with the disabled attribute.
… say a user entered invalid or incomplete content. They should not have to press the submit button to learn that it doesn’t work.
If that’s what you want, then you are not wrong (about the tooltip). But disabling a button in general isn’t great. To quote my favorite website:
Do not validate when the user moves away from a field. Wait until they try to move to the next part of the service - usually by clicking the ‘continue’ or ‘submit’ button at the bottom of the page.
and from the section after
Only add client side validation if you find a user need for it. For example, because research shows it helps the user if you validate the information they’re providing as they type.
I apologize for being the “well acchhtually” guy if you didn’t mean anything by it. The certainty in your wording just triggered me a bit. It is really really difficult to do forms right and there is no one correct way (disabling the submit button certainly isn’t it).
My favourite example of this: the ACM Digital Library now requires you to enter an ORCID for every author in a paper. You cannot save state until you have entered every author’s ORCID (so make sure that you know them up front). You cannot paste these 16-digit numbers because their validation JavaScript intercepts every keypress and breaks paste. Oh, and you can’t disable JavaScript because the submit button is JavaScript.
It seems that the real bug is that you cannot focus disabled buttons. On the other hand, you also cannot properly focus or hover buttons on mobile (so no tooltip) and just not disabling the button and displaying a useful error when people press it is often a good solution.
For a high level view of what we’re working towards, this talk w/ me and Randy is your best bet. That focuses more on the social side of things and what we’re trying to deliver.
The distributed object infrastructure stuff with Spritely Goblins is well described by both the Heart of Spritely paper (the original link for this post!) and, as you noticed, the Goblins page and associated video.
We also have two other major projects happening:
Hoot, our Scheme -> WASM compiler, so we can get this tooling in the hands of users
[OCapN[(https://github.com/ocapn/ocapn), the Object Capability Network, which is the protocol Goblins uses and which while larger than just us, we have done a lot of work kicking off the foundational documents on.
You can find out a lot more details by reading the news posts we publish. For a coherent roadmap, the older https://spritelyproject.org has one, which is mostly intact but that website is deprecated. A reframing of our roadmap and revisal of spritely.institute is on the plan for 2024.
It is installable, but it might be worth noting that (at least when I looked at doing so) it required downloading all the CT logs from the start which required a fairly large amount of disk space - many terabytes.
Switching code from executing on a green thread to running on the OS thread stack can be prohibitively expensive for FFI. Go just accepts this FFI cost; C# recently aborted an experiment with green threads for this reason.
It’s not clear to me what is being said. Green threads need to switch to OS threads for when there is no runtime for the green threads?
I take that comment in the context of stack copying, mentioned in the paragraph above. When Go grows its stack, it has to rewrite all the local pointers to the stack so that they point to the new stack location.
This means that you can’t pass a pointer to the stack across the FFI layer: that pointer could become invalid in the future, which means that C code would try to follow a pointer into memory that has been freed. A solution to this problem is to never pass pointers to the stack, only to the heap, but this is expensive.
Green threads are “green” in part because they have a small amount of stack space. Becaue of the small stack, you can’t call a C function directly because it may require the large amount of stack space it is accustomed to having.
Would the motivating justifications, syscall expense and stack size of os threads, vanish in Rust compiled to run (as root) in a unikernel on firecracker, for instance?
The first axis of choice in this design space is between cooperative and preemptive scheduling.
Is there also a 0th axis of choice, overlooked as such in the article, but mentioned in terms of a presumed choice already implicitly made, and that’s the existence of user space as an expensive detour from kernel space, versus just one space.
Code in a unikernel is not really running “as root”, as even superuser processes on a UNIX system nominally have memory protection. Rather, it’s running with all the safeties turned off. That doesn’t negate the cost of stack allocation though: threads still need a stack. You also still need to preserve a bunch of ABI state (register values, etc) on a preemptive switch between full threads. The privilege switch cost (when you’re making a system call) is really the only thing that goes completely away just by being inside the kernel.
It’s still a very interesting solution to consider. If the OS threads are so expensive and we can make cheaper green threads. Well, can we make the OS support cheaper threads as well? It seems like you end up roughly with the same problems as the article but if the OS was doing your green threads your programs wouldn’t have to include the runtime for them anymore (okay, doesn’t help on embedded) and since async/await introduced Pin I think the other argument against green threads is also gone now.
I don’t understand. What does this article have to do with ligatures? By “st” did you mean “site”? I don’t see any ligatures anywhere on the page (in Chrome on macOS; the rendered body font is Open Sans Light).
After I developed a mysterious pain in the ball of my hand and twinges in my wrists I looked into ergonomics for typing. My summary of what I found via web-searches is to look at, in order
Same, I have gone quite a bit through ergonomics literature, and there is virtually no research on layouts.
Though I found from practical experience that the frequent letters N and T are awkward diagonal index stretches because they are on the outer index column. With row stagger you can cheat a bit. But with column stagger it’s more comfortable to use a layout that puts these on the home row.
I’m not sure if that isn’t due to economics instead of ergonomics. Personally, I switched from regular German to neo2 and it helped for me. I type less strained and cramped on it.
I assume that it’s mostly due to the additional layer for programming symbols and not the more ergonomic placement of letters. Although, that is definitely also noticeable for me now when I go back to qwerty.
Switching to a different layout can help, but the improvement is marginal, compared to the benefits of fixing one’s posture, and using more ergonomic hardware. If anything, then better and/or smarter keybinds help more than a new layout: if you can get rid of chording, or unnecessary load on pinkies (doesn’t require a layout change, you only need to move the modifiers to better places - like your thumb - to see big improvements).
Rust has found itself competing in the “web service” space. In that space users very often want async for a number of reasons. Dealing with a Slow Loris attack without async, for example, is hard. Threads are also relatively expensive, in terms of memory/ creation. For a language that prioritizes “fast” and “light”, threads aren’t totally ideal if you want lots and lots of concurrency.
Before async await things could be awkward. Writing code that you wanted to time out meant that your various network / IO clients had to ensure they exposed a socket API at all levels. It’s often desirable to place your concrete client impl behind a trait, but now your trait has to expose socket APIs or otherwise timeouts have to be specified at a much higher level. In async that’s much less of a concern - you can pretty trivially handle timeouts. And those timeouts can apply to non-io code. You could write a JSON-lines decoder that, after every 100 lines, yields back to the caller - this is really nice and trivial to express with async, and it doesn’t even have to do with performance or parallelism or IO etc.
Sticking to the threads is the right thing to do, while async should be employed only when needed and only in the little parts of the code where it is needed.
Unfortunately Rust community jumped on the async bandwagon uncritically, because it is web-scale
Then the user agent is free to strip the element as it is “complementary” content. Most callouts aren’t complementary, but warnings or other notes directly related.
Sorry that wasn’t worded right & I was out at lunch.
As noted in the post, <aside> elements have an implicit complementary role which means that content needs to be standalone (not stripped out).
complementary role
A landmark that is designed to be complementary to the main content that it is a sibling to, or a direct descendant of. The contents of a complementary landmark would be expected to remain meaningful if it were to be separated from the main content it is relevant to.
There are various types of content that would appropriately have this role. For example, in the case of a portal, this can include but not be limited to show times, current weather, related articles, or stocks to watch. If the complementary content is completely separable from the main content, it might be appropriate to use a more general role.
With the exception of some ‘tips’, a callout is rarely standalone & not like “show times, current weather, related articles, or stocks to watch”. A callout is something directly related to the body copy of the article and thus isn’t suited for an <aside>. I also mentioned this reasoning in Asciidoctor’s issue tracker which has caused moving forward with <aside> to halt while considering a possibly better option.
You should define what a callout is or link to a definition.
How is it different from an , a , an or a . Is it a box? A speech bubble? Does it need an icon? Does it need a border? Can it be ignored and the text inlined or does that destroy the text for example because it now repeats something?
Was the opening three sentences of the abstract not sufficient?
As the name may imply, callouts (sometimes called “admonitions”) call out a specific text from the content.
They are meant to draw priority attention to specific text.
Often you see accompanying labels such as: tip, note, attention, warning, caution, danger, important.
How you design is up to a lot of room for interpretation & there isn’t a standard per se other than something box-like with a one-word label/title and body text. Icons could be done via ::marker as mentioned, but it doesn’t have to be a requirement. The text itself has a few I my personally-designed callouts without any icons.
You need to use complex font technology to render them properly. More complex than SVG. I would rather switch to a framebuffer and see the SVG. Without the font, the diagrams actually look pretty terrible.
I’m a HUGE text enthusiast, but having gone down this path before, it doesn’t work out as nice as you’d think. Sticking to 80-120 column terminals is also a problem. Many non-trivial diagrams expand pretty wide.
Not even mentioning phone keyboards? People don’t even press anything anymore they swipe and then completely change the word by picking a different suggestion! Go send some key events for that! 🌲
Oh, and mice are also mad now. People click multiple things at once, their cursor doesn’t move anymore and when they click something a really long time, oops we lied they didn’t click at all they’re just selecting something.
Oh, and why do Ctrl+S for save and Ctrl+Q not work in terminals? Because the terminal people wanted to use that for terminal stuff like windows is using Alt+F4 and MetaL+l!
My, the entire GitHub issue is full of people using the C++ toolchain. It feels like Andrew made a language, and is now discovering that most of his users (or at least his most vocal users) actually came for the toolchain.
I genuinely thought this was a well understood thing. AFAIK, the most significant “corporate” adoption Zig has found so far has been Uber who exclusively use the toolchain and not the language. Most news I hear about Zig from outside of that ecosystem is about their linker zld or some big improvement to zig cc, rarely the language.
Perhaps a clarification is needed then. To me it looks like the respective goals of the project and its users aren’t quite aligned.
I personally was a bit surprised C++ compilation is so important. Especially since interfacing to it is such a pain. The Zig FFI is only to C, right? So those C++ users have to make a C API anyway. From the outside, it makes sense to me that C++ compilation is just an ancillary benefit of the Zig toolchain.
Also, users who consider quitting Zig over this change may be users the project doesn’t even want at this relatively early stage (where “early” <= 1.0): those who value the toolchain more than the language are using short term considerations, and building a language (I think it’s obvious to anyone that’s Zig’s main goal) is a long term thing. It’s not for me to judge, but perhaps the best course of action is to go through with that plan, bite the short term drawbacks, and accept the loss of users and donations.
What’s really disheartening though is that Andrew built a language, and so many people cared more about the toolchain. It’s like remembering Leslie Lamport for LaTeX instead of his work on concurrency and formal methods.
To me it looks like the respective goals of the project and its users aren’t quite aligned.
Yes, this reminds me of the situation with ksmbd, which Samsung developed to support SMB Direct, but approximately all users simply want to avoid Samba’s GPLv3 license.
The language is still unstable, it’s expected that corpos don’t invest into using it yet. Maybe they won’t even once it gets stable, but the current situation tells us nothing in that regard.
I agree the situation is expected, but it could have been the case that Zig is so attractive companies start to use Zig even if it is unstable. That didn’t happen, so it tells us something. A small something, but not nothing.
(Unexpectedly, Dropbox started to use Rust even if it is unstable, because Rust was so attractive to their goals.)
but it could have been the case that Zig is so attractive companies start to use Zig even if it is unstable. That didn’t happen, so it tells us something.
Zig cc doesn’t do anything particularly magic. It uses support that’s already in clang, it just provides the contents of the sysroot directory and sets the –sysroot and -target flags for you. Companies that care about this typically already provide configured versions for the targets that they care about. For example, XCode can do this for multiple macOS / iOS versions.
As with other similar efforts, zig cc is limited by licenses. If you want to cross-compile for Windows, I believe the visual studio redistributables allow you to install their headers and libraries on any system for the purpose of cross-compiling (I believe the person doing the compilation is required to accept the license, not sure how Zig does this), so it’s ‘just’ a matter of getting the right files. Apple explicitly prohibits this. Zig works around that by building their own sysroot from Apple open source bits, which hits a brick wall as soon as you want to use anything not in the open source repos (e.g. any of the GUI frameworks). Building a sysroot for most *NIX systems is fairly easy and most companies that want to cross compile for multiple *NIX variants build their own.
now discovering that most of his users (or at least his most vocal users) actually came for the toolchain
I’ve heard people say the same thing about Go, that they aren’t there for the “language,” but are there for the toolchain and the experience it creates.
zig cc basically completely takes care of cross-compilation for any target. It’s pretty much a clang distribution that can cross-compile to whatever target you want without having to do any special trickery. It’s a drop-in replacement for gcc/clang, too, and is marked as stable, which is why you’ll see e.g. Uber using it.
It’s really quite nice and am honestly surprised something like this was never made officially by the clang/LLVM project.
It’s really quite nice and am honestly surprised something like this was never made officially by the clang/LLVM project.
It did. That’s what zig cc uses. Clang supports a number of flags that make this trivial:
--sysroot specifies the root to look for headers when compiling, libraries when linking.
-B lets you specify an alternate path to search for tools, so you can drop in an alternative linker, assembler, or whatever if your target needs one.
-target lets you specify the target triple.
The only thing that you need to do is provide a sysroot.
For an open-source *NIX system, that’s trivial. If you have an install you can just copy the relevant files out of it. If you want to target FreeBSD, for example, if you just extract base.txz from any release, you have a sysroot that works for targeting that release and architecture. It’s a bit more complex if you want libraries from packages, but they’re usually tarballs + metadata and you can just extract them into your sysroot.
It’s harder for proprietary platforms because you don’t have unlimited redistribution rights to their include files and libraries (or library stubs for dynamic linking). A lot of the Windows things can be extracted from the Visual Studio redistributables (though you must accept the license before doing this). On macOS / iOS, the T&Cs explicitly prohibit using any of their parts to compile from non-Apple platforms. Zig builds a macOS sysroot out of the open source Darwin bits, but that means you can’t use any headers or link any libraries that are part of the proprietary components, which includes all of the GUI frameworks and most system services.
That’s true, clang is a lot better in this regard than gcc. I still find it completely insane that gcc requires a fully separately-built toolchain to do any kind of cross-compilation (at least it did when I looked into it last year)…
Still, zig cc definitely hits the spot when it comes to the convenience - no need to deal with sysroots or alternative toolchains. Just specify the target and it figures it out.
I still find it completely insane that gcc requires a fully separately-built toolchain to do any kind of cross-compilation (at least it did when I looked into it last year)…
I think they’re working on it. At least gdb can now be built with support for multiple targets. It makes sense when you consider the history. GCC started at a time when memory was measured in single-digit megabytes and disks were typically double-digit megabytes. Cross compilation was rare and so there was absolutely no desire to make compile times longer (the first time I compiled GCC, it was an overnight job, and that was quite a few years later) and add disk space requirements for a feature that very few people needed. Target selection was done with #ifdef, which meant that you weren’t paying any indirection cost at run time (which would have slowed things down).
In contrast, when clang came along, computers were already pretty fast. I started doing LLVM dev on 1 GHz machines with >1 GiB of RAM (I did a lot on a 1.2 GHz Celeron M, which took about an hour and a half for a clean build). The overhead from indirection in the per-platform or per-CPU bits was tiny and compiling all targets didn’t add a huge amount of time (10-20%), and being able to test all targets from a single was considered a benefit that outweighed all of the costs. In particular, few people are expected to build LLVM from source (the GNU project expected everyone to build GCC from source, early on, because that was how you distributed it), only developers and distributors. Developers benefit from taking 20% longer to build a single binary that can compile for anything rather than having to build 10 different binaries.
One of the problems with big software projects in general is that they must be built with the constraints that are present when they are started and typically grow to be useful and widely supported by the time that those constraints have changed. For example, LLVM began very early in the multicore era and so none of the core data structures were designed for concurrency. If you modify any function that refers to a global, you must modify that global’s use-def chain, which means that you can’t do that concurrently with anything else in the same module. There’s been a lot of work on ThinLTO to try to bring parallelism back, but building this from the start would give you something very different. And, by the time you’d finished, people would complain that it didn’t use your quantum AI coprocessor, which could do compilation much faster.
Still, zig cc definitely hits the spot when it comes to the convenience - no need to deal with sysroots or alternative toolchains. Just specify the target and it figures it out.
This works only because zig cc provides packaged toolchains for some platforms. If you want to target anything else (e.g. macOS with Cocoa), you’re in exactly the same place you are with clang.
Wait, cross compilation is still hard? What year is it?
I would like a meme for this; you wonder what the problem is and it turns out there is a much bigger problem. As if, you wonder why the car doesn’t start and then realize it doesn’t have an engine.
In addition, zig packages stand out for being really easy to compile, because they take advantage of the built-in C++/Objective-C support in the compiler. Rather than shelling out to any subprocess, the zig community has been porting projects over to use build.zig instead, so cmake doesn’t need to be installed.
There are also may PRs that members of the zig community have made to (such as this one) to add build.zig as an alternative build system for open source projects. All of that work goes away for non-C projects.
engines prominently lists node. And while you hate it with the depth of your soul, you are not going to Bun or Deno because you know this will not stop the pain. This will only make the pain worse.
I say, let the young play with the shiny new toys.
I say, stable, stable, stable. node, npm, nvm, save-exact.
Few, well maintained, with a decent community packages.
There’s also moment.js. You love that library, it has a really pleasent API. But the internet decided it’s too “mutable”, too fat, it doesn’t support treeshaking and now you have to migrate to date-fns. You haven’t started yet, but you already feel the painful refactoring in your bones.
You got a good API, plenty of examples, battle tested… It still puzzles me why we self-sabotage all the times in the js world and we try to reinvent the wheel forgetting all the past experience…
Oh, dear jest. It started as a fast test runner. But now it’s big and fat, it depends on some babel pacakges while the rest of your app is transpiled by a mix of esbuild and swc. Properly configuring it with ESM and TypeScript was a PhD science project.
This is just the consequence of the above. The amount of pain the fragmentation of the ecosystem produce is unbelievable.
Feels like anything controlled in a sufficiently large portion by a for-profit enterprise will inevitably get worse over time. Just happy I can still self-host a mail server without huge problems.
And its meaning is already drifting, I guess. I’d have said that what the big players are doing to email is more like a sort of distributed EEE. They largely haven’t progressed their email services along the enshittification pipeline at all. Gmail’s current iteration is more annoying than what it replaced, but I think it’s still trying to provide a useful service to its users, to the extent Google’s batshit product management is able to optimise for anything you can’t measure with a TSDB.
Google has enshittified plenty of things—search, maps, chrome, anything to do with android—so just to be clear, I’m definitely not saying that they wouldn’t enshittify email-the-product. But it’s not a good move, economically, to enshittify a product that still has meaningful competition, so I think they’d have to kill email-the-protocol first. And although Big Email has a shared interest in making email worse, they won’t cooperate on ending it completely.
Admittedly Gmail could be more transparent about its spam detection algorithm but even their product teams know that email-the-protocol is too ingrained into literally everything for them to think they could replace it without creating a rowboat situation for themselves or they would have already.
The SMTP protocol /is/ ancient and its design reflects that. There should be a new protocol or at least a new version so that an MTA that isn’t a collection of antiquated necessities can be built.
I really like JMAP but it’s suffering from ecosystem problems. The servers don’t want to implement it without client support, clients don’t want to invest in it until it’s widely supported by servers. Clients really need to go first because they tend to already couple the things that JMAP integrates, whereas sending mail, receiving mail, managing calendars and managing contacts are often handled by different things on the server (there’s a proxy that can talk to an IMAP, SMTP, CalDAV and CardDAV server, but then you don’t get all of the benefits). Servers also need to change their model a bit: JMAP removes the idea that each email lives in one canonical folder and integrates smart folders as a core idea.
If this is enshittification, then it’s pretty indirect because Google isn’t actually squeezing value out of the email users except maybe by pushing people towards large email platforms.
Just happy I can still self-host a mail server without huge problems.
Isn’t it a problem for you that mail sent from that server is likely to end up in spam folders if users of your mail server write to Google (or, as another commenter points out, Microsoft) users?
I’ve run my own server for decades and a school’s server for a little less than a decade, and gmail never did that to me, no matter what my users did. The worst that happened was rate limiting.
A “petname system” is a database and a set of interfaces which use that database to bidirectionally map human readable names to cryptographically secure names.
OK, each user will have a secure database which maps unique IDs to human-readable aliases.
Where does that database live? It definitely can’t live on any specific device, because I (as a user) have many devices, all of which need to have the same “petname resolution” behavior.
So this means the database needs to live at some third-party endpoint, which all of my devices can access. This (necessarily!) represents a delegation of trust.
And I’m definitely not going to run my own petname database, I’m going to outsource that work to a hosting provider. So then what is the difference between this outcome and, basically, DNS? The trust model is more or less the same, isn’t it?
My petname database is stored locally on devices I own and replicated across my devices.
Data doesn’t have to be centralized in order to be accessible from more than one location. Decentralized systems have existed for decades, and interest in them is growing. The Petnames paper introduces one small part of that, which is decentralized naming systems.
The reason my ad-hoc system is not as convenient as storing all my personal information in the Apple or Google cloud is due to the economic incentives of capitalists for whom “personal information is the new oil”. They can pump a lot of money into software with a polished UI, and they call sell hardware with that software preinstalled.
But I am hoping to transition to more convenient and easy to use software that is private and local-first. There are a number of projects. Today I am planning to dive into <anytype.io> and see if that meets my requirements. Please reply if you have opinions or experience with private, local-first, decentralized personal computing software.
Data doesn’t have to be centralized in order to be accessible from more than one location. Decentralized systems have existed for decades, and interest in them is growing. The Petnames paper introduces one small part of that, which is decentralized naming systems.
Data doesn’t have to be centralized to be accessible on multiple devices, true. But devices have to know where to send their local updates, and how to receive updates from other devices. And the only practical way to do this kind of synchronization does require a centralized coördinator.
For one reason, because updates between arbitrary devices like phones can’t rely on peer-to-peer, gossip-style communication if they’re expected to be reliable. You need a clearinghouse to take responsibility for message receipt and re-broadcast.
But more importantly, because you need a single source of truth for the set of valid devices. If a device is lost or compromised, you need to be able to revoke that device from the list with authority.
So, I’m curious! —
My petname database is stored locally on devices I own and replicated across my devices.
How do you replicate it?
Please reply if you have opinions or experience with private, local-first, decentralized personal computing software.
I’m down with local-first! But there’s no avoiding a centralized coördinator. If you don’t want to trust that coördinator, that’s fine, you can encrypt before sending, and decrypt after receiving — but that makes the payload opaque, which makes optimizations (delta compressions, etc.) really difficult.
—
Today I am planning to dive into <anytype.io> and see if that meets my requirements.
It looks like this service hosts user data encrypted with a single shared key on a (private?) set of IPFS nodes. Those nodes act as the centralized coördinator I describe above.
IPFS is a content-addressable storage system, so updating a document will create a new document with a different address. This kind of punts on all of the data synchronization issues, and means that updates to a document are not observable by consumers of that document, without some additional out-of-band effort. It doesn’t look like devices can be managed individually, or have unique keys. It doesn’t look like the key(s) can be rotated.
In the petnames essay, it says “names can have two out of three properties: decentralized, globally unique, human meaningful.”. Petnames are decentralized and human readable, but not globally unique. Decentralized architectures are a compromise: you gain useful properties, you lose other useful properties.
If I store all my personal data in a third party cloud, then I have a single source of truth (something you want) but I lose properties that are more important to me. First, I have to trust the third party that runs my cloud. Second, I can’t work offline. I want a local-first compute environment that is highly tolerant of being offline. What I am willing to give up is a single source of truth. If I edit documents on offline devices, then they become out of sync with their replicas on my other devices, until synchronization time arrives. If I make changes to the same document on different devices, I may have to resolve conflicts. I’m sure you’re aware that git can support this kind of decentralized workflow.
For a specific example, I have a cellphone, a laptop, and a desktop. They each contain copies of my personal data. I sync data manually between them, but there is no master. I’m looking for something more seamless and automatic, while remaining decentralized. Suppose I’m travelling with my laptop and cellphone. I have no internet or cellular connection. I’d like to be able to seamless sync my laptop and cellphone (via bluetooth or wifi hotspot) without a lot of ceremony. Neither one is the master; new changes on one get propagated to the other. My desktop at home won’t be synced in this situation, since it isn’t reachable. Maybe that explains why I want a decentralized system without a single source of truth.
Anytype.io uses different definitions of “local first”, “decentralized” and “open source” than the ones I was expecting.
For a specific example, I have a cellphone, a laptop, and a desktop. They each contain copies of my personal data. I sync data manually between them, but there is no master. I’m looking for something more seamless and automatic, while remaining decentralized. Suppose I’m travelling with my laptop and cellphone. I have no internet or cellular connection. I’d like to be able to seamless sync my laptop and cellphone (via bluetooth or wifi hotspot) without a lot of ceremony. Neither one is the master; new changes on one get propagated to the other. My desktop at home won’t be synced in this situation, since it isn’t reachable. Maybe that explains why I want a decentralized system without a single source of truth.
I get it. There is no authoritative source of truth for your personal data, there is only the individual view(s) of that data on each device, which are the result of applying all of the updates received by the device. And it should definitely be possible to share updates between devices directly, without going through a centralized coördinator. I agree!
The problem is: how? Specifically?
Are you aware of any mechanism for an iOS application to broadcast an update to a set of trusted peers, and for that update to be reliably received by a commandline application that’s running on a nearby laptop which identifies as one of those peers? And furthermore, that those updates can also be reliably delivered to an Android application which only connects to the internet (or comes close to the laptop or iPhone) some days later?
As far as I’m aware, there is no practical solution to this problem. Bluetooth, Bonjour, etc. just don’t provide the necessary discoverability and interoperability. Even if they did, it’s insufficient — I shouldn’t need to bring my Android physically next to my iPhone for them to have the same view of my data, I should only need to connect them both to the internet. Moreover, if I connect my iPhone to the internet on Monday, whatever updates it has should be received by my Android when I connect it on Tuesday. These kind of table-stakes requirements are only solved with a centralized and stateful coördinator.
This UX is what matters, and UX is bound by the constraints of the underlying technology. All available evidence suggests the best compromise solution for these kind of use cases is to proxy updates through a centralized third-party service over the internet. That sucks, sure! But fixing it requires changes the underlying protocols, and the APIs they provide to relevant devices.
Here’s what I would consider a practical solution for me, and it’s fully decentralized and peer-to-peer. If any two of my devices are both connected to the internet at the same time, then, using an appropriate protocol, they discover each other and synchronize with each other. In practice, my desktop is always running and connected to the internet, so it would normally be always available to act as a synchronization point. For other people, their cellphone is always turned on and connected to the internet, and could serve the same role.
Given appropriately designed software, the UX is simply the requirement to register each new device you get with an existing device in the peer group, so that they all know about each other and will sync with each other. This is not any more difficult than registering each new device with your third party centralized sync service.
I haven’t tried to actually implement this, but I know that suitable protocols exist, and that they can use distributed hash tables to allow peers to find each other without the need for static IP addresses on all peers. Tor Onion Services are an existence proof that this is possible.
I also said I want to sync locally if the internet isn’t available. You say that this isn’t practical, and claim that Bluetooth and Bonjour aren’t good enough. But you don’t convince me that this isn’t possible. Elsewhere on this page, @crazyloglad mentions they are working on “(Arcan) A12 where the constraints are such that DNS is not an option (e.g. transiently airgapped networks) where fleets of user-facing devices still need to dynamically discover and join together to form a network transparent desktop”. If they can figure out how to do that, then why can’t we have software that lets two of my devices discover each other on a LAN and sync? Maybe I should learn more about Arcan.
Here’s what I would consider a practical solution for me, and it’s fully decentralized and peer-to-peer. If any two of my devices are both connected to the internet at the same time, then, using an appropriate protocol, they discover each other and synchronize with each other. In practice, my desktop is always running and connected to the internet, so it would normally be always available to act as a synchronization point. For other people, their cellphone is always turned on and connected to the internet, and could serve the same role.
…
I haven’t tried to actually implement this, but I know that suitable protocols exist, and that they can use distributed hash tables to allow peers to find each other without the need for static IP addresses on all peers. Tor Onion Services are an existence proof that this is possible.
There’s a lot of complexity hiding behind “an appropriate protocol” :)
Discovery requires some kind of coördination. You can have everyone register with a centralized server, like DNS. Or, you can do some kind of P2P thing, like Tor/Onion. But you can’t avoid seeding each node with an initial set of peers, which you either have to specify manually (laborious, unreliable, bad UX) or — you guessed it — fetch from a centralized server.
(In fact, even if you’re manually specifying the initial set of peers, you’ve almost certainly just copy/pasted those IPs from a website somewhere, which is effectively the same thing as querying a centralized server for them!)
Given appropriately designed software, the UX is simply the requirement to register each new device you get with an existing device in the peer group, so that they all know about each other and will sync with each other. This is not any more difficult than registering each new device with your third party centralized sync service.
While end user devices can pretty easily make outgoing connections, it’s unfortunately very difficult to get them to reliably accept incoming connections. Most carriers and many ISPs will prevent it outright, and even when they don’t, there’s an infinite universe of complexity in dealing with NAT.
Systems that need end-user devices to be able to accept incoming connections (like Tailscale for example) often solve this problem by having the device make an outgoing connection to a — you guessed it — centralized server, which proxies incoming requests back through that connection.
I also said I want to sync locally if the internet isn’t available. You say that this isn’t practical, and claim that Bluetooth and Bonjour aren’t good enough. But you don’t convince me that this isn’t possible. Elsewhere on this page, @crazyloglad mentions they are working on “(Arcan) A12 where the constraints are such that DNS is not an option (e.g. transiently airgapped networks) where fleets of user-facing devices still need to dynamically discover and join together to form a network transparent desktop”. If they can figure out how to do that, then why can’t we have software that lets two of my devices discover each other on a LAN and sync? Maybe I should learn more about Arcan.
Oh there are all kinds of mesh network protocols and local network discovery mechanisms, almost uncountably many. The problem to solve here isn’t the technology. The problem to solve is the integration with the device and the user experience. Making it usable.
I say Bluetooth and Bonjour and all current technologies aren’t viable, because (as far as I’m aware) there is no software in existence today which has the synchronization behavior you describe. If it were feasible to do, then I have to believe that someone would already be doing it.
The ‘centralized versus distributed’ is a misdirect or a false dichotomy; there is a substantial difference from DNS as an externally authoritative distributed asynchronously mutating namespace versus internally (yourself) synchronised swarm of cutesy names you call things you like/dislike over ephemeral rendezvous points (coordinates really). Centralised as in pub, not as in tax office. Relatedly, scale isn’t millions of names but the much more manageable tens-to-hundreds – your silicone family.
Unless ‘hung drawn and quartered’ comes back into fashion your are also not geographically distributed (and if it is, well, other problems take priority. You might be in Japan, you might be in Germany or travel between the two but there is a substantial latency and tolerance depending on the time at airport checkin.
For that, pub/subscribe with the “trusted third party” being another instance of you and part of your namespace suffice as petname is transport securing pub-key doubles as state-authenticating signing key. Meet up at the pub at table #5 to coordinate the heist kind of a thing, leave ICANN out of it.
You can punch your swarm of devices as a synch operation (or NFC tap / ubikey for when kinetic energy fails to initiate key transfer) or huddle up before playing ball, You can’t punch DNS as easily as NAT (even though one might like to do that on a daily basis) as others get sad and disagree with your naming of things.
It seems like you’re suggesting that resolving a given identifier could yield different results depending on client identity, locality, or jurisdiction. Is that true? If so, can you give some examples of this kind of identifier?
Something which doesn’t qualify is, say, Google. When I type google.com I need to get the same logical result, regardless of where I am, or what my local pub is, or what I decide is my silicone family. The concept of google.com is invariant to all of those things. Any system which returns a different logical result for google.com based on any of those variables is broken. My local pub does not get to decide what google.com means.
(Different physical results that take advantage of e.g. CDN locality is a different thing, of course.)
The LAN discover case is somewhat easy, depending on threat model. compromised-by-default IoT devices or others on your corporate network building public key databases or leveraging discovery beacons for denial-of-service amplification is a somewhat spicier challenge. mDNS (Bonjour) comes from the era where this wasn’t much of a threat and pragmatism “I need to find my printer, whatever the cost” ruled (and the cryptographic tools needed weren’t exactly for public consumption at the time).
Unless you are the retrocommunications nerd running your network as a token ring or single chain coaxial, chances are kind-of high that the stricter ‘peer-to-peer’ definitions will fail by being bound to a physical layer that has a hub an spokes kind of a topology. There’s still a difference from that as centralisation to one of [FAANG] serving the entire world and forcing that as a design constraint for how the protocol is supposed to scale.
The HCI model is more involved than that (at least from my ‘networked desktop’ perspective) as it is not just about the different device having synchronised access to the same world state, but for them to act as different kinds of sources and sinks. This is why I have a local namespace of petnames (“connection points”) that correspond to access control models that links together with the networked form. Examples would be to connect “this part of my desktop is allowed to manage the clipboard and inject input” to a networked device that I am actually using to generate the input, or “my mobile phone is allowed to act as video source (webcam) on my desktop, but not synch my documents folder”.
For rediscovery on the global internet you will need some form of third party rendezvous, but that does not have to be an 8.8.8.8 like behemoth, but a virtual piconet like master of your very own terror cell. That one can also act as traffic relay or NAT punch, as well as state store / backup. Alas it also opens up the can of worms that is ‘transitive trust’ as the other option being manual management, which is .ssh/id_rsa annoying or the physical form of annoying with having a TPM in your keyring.
A Petname system implies nothing about your database being secure. It’s the underlying names in it that are secure, in the Zooko’s Triangle sense, i.e. no one else can use that name because they don’t know the corresponding private key.
You probably want the database to be secure for the same reason you want your existing contacts db to be secure, but it’s not a requirement of the system. In practice you can do things like add the cryptographic names as custom fields to address cards and keep using iCloud or Google or whatever.
A petnames database hosted for you somewhere requires trusting fewer people and machines. With DNS you delegate trust to the whole unencrypted path between your machine and the authoritative nameserver for whatever domain you want to reach.
You could also encrypt your database and then so long as you trust your software you could trust that your petname host could only do denial of service and rollback attacks rather than just feeding you arbitrary names.
Same for other sources of petnames, if they’re signed then they can be significantly higher trust than DNS.
I imagine what GP is thinking of is more like “Syncthing easy”, but you could even have your petname database sync with iCloud if you really wanted to.
So this means the database needs to live at some third-party endpoint, which all of my devices can access. This (necessarily!) represents a delegation of trust.
Not if the database is encrypted with a local key or password. Sure you’d have to download it and upload it again every time you need to synchronise it (I’m guessing it could be automated as a background task), but it would prevent any funny business from the provider.
OK, sure, but that just kind of moves the issue of trust away from the DB provider, and into the key manager. That is, any reasonable UX for managing those keys across all of your devices would necessarily need to live at some third-party endpoint, for the same reasons. And now we’re back to the same issue of trust delegation.
Sure, when I use KeepassXC I have to trust KeepassXC. But if the protocol between DB and key management is standard, the DB provider and key manager may be separated, and protect me from the DB provider. At least with this scheme any bug or backdoor from the key manager may be spotted (if it’s Open Source like any security product should be).
Not perfect, but still better.
Or just duplicate your pet names across your devices. I do that with my password database, no online anything involved, and the occasional desync has yet to be a deal breaker.
I appreciate that your password manager doesn’t sync through a third party. I hope it’s not controversial to observe that this is a fairly niche setup, and is really only viable for technically sophisticated users such as yourself.
These edge cases are interesting and useful, but the ultimate test is the general case. It needs to be feasible for grandma to use the thing. Grandma can definitely be convinced to use a password manager, but only if it works across her iMac, tablet, and phone without extraordinary effort. She’s definitely not going to sync a password DB between those devices manually.
The only way to solve this problem, AFAICT, is to delegate that work (and trust) to a reliably accessible third party.
The only way to solve this problem, AFAICT, is to delegate that work (and trust) to a reliably accessible third party.
Under Capitalism. Otherwise I could see manufacturers agree on a standard, such that grandma can have one client per device, and one service of her choosing, all independent from each other if she so choose (typically that would be a Microsoft and Apple clients with a Google server). She would have to trust her client (Microsoft and Apple) that her data is not leaked, but the server (Google) will not be able do decrypt anything without her password.
Now syncing is a bit expensive: download the entire DB, merge, upload the whole thing again. Or maybe chop it up in a content addressed manner, but then you’d leak quite a bit of metadata, such as the number of entries. In any case, I can see it working for Grandma, if the big FAANG agree on such a standard even though they probably have no interest to.
The only reason Grandma can’t have that is because this kind of setup is not the default. If it was it would be as easy as navigating Facebook.
Well, two points. One, capitalism won and it’s not going anywhere, so there’s not much point in talking about alternatives, you just gotta treat it as an invariant. Two, I don’t think it’s capitalism that makes this true, I think it’s just that the market has made it clear what a viable UX looks like. Manufacturers won’t agree on a standard unless doing so serves their interests. Decentralization doesn’t really serve anyone’s interest, so there’s no incentive. And why would Google host this opaque data? It can’t do anything with it. Does grandma care if it’s encrypted on the server? No! Grandma cares about product features and capabilities. Encryption is incidental.
Sadly I’m afraid I’ll have to agree with you. Which is why we’re all gonna die.
The problem with capitalism is that it cannot last. Finite boiling world and all. What comes after depends how it phases itself out. Unfortunately I’m anticipating a severe reduction in human population (we’re not all gonna die, but I can easily see most of us dying), and with it disruptive social changes. I don’t see capitalism surviving its own collapse. Or maybe the situation isn’t as dire as I think, and we’ll just continue the cyberpunk route we’re currently taking. Some kind of corporate fascism, if not good old fascism.
The rest of your analysis I also agree with: the incentives just aren’t there. They could make a nice UX for privacy-preserving decentralisation and all that jazz, but I agree they just won’t.
I haven’t lost all hope however. I do believe an alternative to capitalism has a chance. But just thinking that throws me outside the Overton window, and that’s a problem.
You mentioned the second one but you just need to have an extra verification of the index.html.
Just make it open source, pin the version and verify that you’re getting everything. Boom, done. Once you’ve done that then you only need to worry about browser itself being hacked and not the website code.
Posting another thing wrong about this article:
The Lavabit situation is also explained incorrectly. Levison wasn’t forced to modify his website, rather he was forced to give up his SSL keys. He did offer to give up Snowden’s emails specifically but your article is wrong enough to be harmful.
This is a theoretical solution. Signedpages is a browser extension and not a web compatible solution. In practice, easy distribution and updating is one of the main benefits of the web as a software distribution platform. So, sure you could verify but what do you verify against? The best you can do is something like CT so you at least cannot be attacked individually but that also doesn’t exist yet.
For the verification just check it against the git release hash or npm somehow.
It’s theoretical but it’s perfectly valid and simple enough to implement. The author is saying that this is impossible when that’s false given the current technology available to us.
If this is true, please fix your messenger and add e2ee. A simple version with great UX has many problems but this is exactly what it (mostly) solves.
Haha! We won’t “fix Mattermost” 😂
I love e2ee, and we use it when software is available. But sometimes the software just doesn’t exist, you know?
Anyway, even having e2ee on the services is not a good reason to not care about a server’s defenses imo.
Can we please also talk about how commits are actually weird in git? Like, a commit is a state of the repo identified by its hash. Except when you do basically anything with commits like merge or rebase a branch you’re really talking about the changes that this commit made. Hell, if you look at a commit you see the diff of changes. And then every commit changes its hash on a rebase which was supposed to identify it. Great.
Also, have you noticed that when you make a PR on Github, and you at some point merged main into your branch to update, there is a merge commit in your branch which actually disappears after the PR? Sure, that’s kind of what you want but it’s not at all obvious why this happens.
And if you have some kind policy of not changing history and you start using revert then git sabotages you when you try to merge again after a hotfix it will just ignore your commits because it thinks it already has them but doesn’t think about the fact that they got reverted. But don’t worry, git tells you about this WHEN IT’S TOO LATE. It will go “Well, I guess you shoulda used
--reapply-cherry-picks
, now I threw those commits away. Sucks to be you. Go restore your state!”Strangely,
cd foo/**/bar
doesn’t work here. It gives me “cd: string not in pwd: foo/inner1/inner2/bar” but I can copy that string and it works just fine. So, maybe not the greatest UX on that feature. :DThe out-of-the-box behavior of disabled buttons and inputs is pretty atrocious, both from an accessibility standpoint and from a usability standpoint. This article talks about a very specific situation in which a developer might be tempted to disable a form submit button to prevent duplicate submissions. However, there are many other cases where a button should be disabled but still be focusable.
Taking the form from the article’s the example, say a user entered invalid or incomplete content. They should not have to press the submit button to learn that it doesn’t work. It should look disabled and it should also be possible to show a tooltip on focus and hover saying why it’s disabled. This is currently impossible with the
disabled
attribute.If that’s what you want, then you are not wrong (about the tooltip). But disabling a button in general isn’t great. To quote my favorite website:
and from the section after
I apologize for being the “well acchhtually” guy if you didn’t mean anything by it. The certainty in your wording just triggered me a bit. It is really really difficult to do forms right and there is no one correct way (disabling the submit button certainly isn’t it).
My favourite example of this: the ACM Digital Library now requires you to enter an ORCID for every author in a paper. You cannot save state until you have entered every author’s ORCID (so make sure that you know them up front). You cannot paste these 16-digit numbers because their validation JavaScript intercepts every keypress and breaks paste. Oh, and you can’t disable JavaScript because the submit button is JavaScript.
I see you are a person of distinguished taste. :D
It seems that the real bug is that you cannot focus disabled buttons. On the other hand, you also cannot properly focus or hover buttons on mobile (so no tooltip) and just not disabling the button and displaying a useful error when people press it is often a good solution.
What’s a good introduction to Spritely in general? The FOSDEM talk here, maybe? https://spritely.institute/goblins/
Hello! Depends on what you’re looking for…
You can find out a lot more details by reading the news posts we publish. For a coherent roadmap, the older https://spritelyproject.org has one, which is mostly intact but that website is deprecated. A reframing of our roadmap and revisal of spritely.institute is on the plan for 2024.
I hope that helps!
Does anybody have some software which lets me search the CT logs for my domains?
https://crt.sh
Cert Spotter
Thanks! I had missed that it is also installable and not just a service.
It is installable, but it might be worth noting that (at least when I looked at doing so) it required downloading all the CT logs from the start which required a fairly large amount of disk space - many terabytes.
I use https://report-uri.com/ which has a certificate transparency feature (for free I think, at least, I’m not paying right now!)
They email you when a new cert pops up
Could somebody explain this part, please:
It’s not clear to me what is being said. Green threads need to switch to OS threads for when there is no runtime for the green threads?
I take that comment in the context of stack copying, mentioned in the paragraph above. When Go grows its stack, it has to rewrite all the local pointers to the stack so that they point to the new stack location.
This means that you can’t pass a pointer to the stack across the FFI layer: that pointer could become invalid in the future, which means that C code would try to follow a pointer into memory that has been freed. A solution to this problem is to never pass pointers to the stack, only to the heap, but this is expensive.
Green threads are “green” in part because they have a small amount of stack space. Becaue of the small stack, you can’t call a C function directly because it may require the large amount of stack space it is accustomed to having.
“Green” just refers to the name of the team at Sun that developed Oak which later became Java. It is not a metaphor for any technical features.
I never knew that bit of history. Thanks!
Would the motivating justifications, syscall expense and stack size of os threads, vanish in Rust compiled to run (as root) in a unikernel on firecracker, for instance?
Is there also a 0th axis of choice, overlooked as such in the article, but mentioned in terms of a presumed choice already implicitly made, and that’s the existence of user space as an expensive detour from kernel space, versus just one space.
Code in a unikernel is not really running “as root”, as even superuser processes on a UNIX system nominally have memory protection. Rather, it’s running with all the safeties turned off. That doesn’t negate the cost of stack allocation though: threads still need a stack. You also still need to preserve a bunch of ABI state (register values, etc) on a preemptive switch between full threads. The privilege switch cost (when you’re making a system call) is really the only thing that goes completely away just by being inside the kernel.
It’s still a very interesting solution to consider. If the OS threads are so expensive and we can make cheaper green threads. Well, can we make the OS support cheaper threads as well? It seems like you end up roughly with the same problems as the article but if the OS was doing your green threads your programs wouldn’t have to include the runtime for them anymore (okay, doesn’t help on embedded) and since async/await introduced Pin I think the other argument against green threads is also gone now.
I never needed ligatures in my life anyway but this st is just an abomination.
I don’t understand. What does this article have to do with ligatures? By “st” did you mean “site”? I don’t see any ligatures anywhere on the page (in Chrome on macOS; the rendered body font is Open Sans Light).
there is an st ligature in the “just” of the title (firefox, linux)
edit: and it is just an abomination
It’s Firefox-on-Linux specific for me, and can probably be removed by disabling the “liga” font feature for Montserrat.
The site doesn’t use any ligatures for me on iOS Safari.
After I developed a mysterious pain in the ball of my hand and twinges in my wrists I looked into ergonomics for typing. My summary of what I found via web-searches is to look at, in order
None of the ergonomics articles/videos I referred to mentioned layout. From this I infer it doesn’t have a significant impact on ergonomics.
Same, I have gone quite a bit through ergonomics literature, and there is virtually no research on layouts.
Though I found from practical experience that the frequent letters N and T are awkward diagonal index stretches because they are on the outer index column. With row stagger you can cheat a bit. But with column stagger it’s more comfortable to use a layout that puts these on the home row.
YMMV
I’m not sure if that isn’t due to economics instead of ergonomics. Personally, I switched from regular German to neo2 and it helped for me. I type less strained and cramped on it.
I assume that it’s mostly due to the additional layer for programming symbols and not the more ergonomic placement of letters. Although, that is definitely also noticeable for me now when I go back to qwerty.
Switching to a different layout can help, but the improvement is marginal, compared to the benefits of fixing one’s posture, and using more ergonomic hardware. If anything, then better and/or smarter keybinds help more than a new layout: if you can get rid of chording, or unnecessary load on pinkies (doesn’t require a layout change, you only need to move the modifiers to better places - like your thumb - to see big improvements).
Can somebody give a short summary on why Rust has async? Why not just stick to threads?
Rust has found itself competing in the “web service” space. In that space users very often want async for a number of reasons. Dealing with a Slow Loris attack without async, for example, is hard. Threads are also relatively expensive, in terms of memory/ creation. For a language that prioritizes “fast” and “light”, threads aren’t totally ideal if you want lots and lots of concurrency.
Before async await things could be awkward. Writing code that you wanted to time out meant that your various network / IO clients had to ensure they exposed a socket API at all levels. It’s often desirable to place your concrete client impl behind a trait, but now your trait has to expose socket APIs or otherwise timeouts have to be specified at a much higher level. In async that’s much less of a concern - you can pretty trivially handle timeouts. And those timeouts can apply to non-io code. You could write a JSON-lines decoder that, after every 100 lines, yields back to the caller - this is really nice and trivial to express with async, and it doesn’t even have to do with performance or parallelism or IO etc.
Sticking to the threads is the right thing to do, while async should be employed only when needed and only in the little parts of the code where it is needed.
Unfortunately Rust community jumped on the async bandwagon uncritically, because it is web-scale
I just use
<aside>
. “As an aside…”Then the user agent is free to strip the element as it is “complementary” content. Most callouts aren’t complementary, but warnings or other notes directly related.
What user agents actually strip
<aside>
s?They display fine, and from what I’ve been told, they screen-read fine. That’s “standard” to me and my readers.
Sorry that wasn’t worded right & I was out at lunch.
As noted in the post,
<aside>
elements have an implicit complementary role which means that content needs to be standalone (not stripped out).With the exception of some ‘tips’, a callout is rarely standalone & not like “show times, current weather, related articles, or stocks to watch”. A callout is something directly related to the body copy of the article and thus isn’t suited for an
<aside>
. I also mentioned this reasoning in Asciidoctor’s issue tracker which has caused moving forward with<aside>
to halt while considering a possibly better option.You should define what a callout is or link to a definition.
How is it different from an , a , an or a . Is it a box? A speech bubble? Does it need an icon? Does it need a border? Can it be ignored and the text inlined or does that destroy the text for example because it now repeats something?
Was the opening three sentences of the abstract not sufficient?
How you design is up to a lot of room for interpretation & there isn’t a standard per se other than something box-like with a one-word label/title and body text. Icons could be done via
::marker
as mentioned, but it doesn’t have to be a requirement. The text itself has a few I my personally-designed callouts without any icons.The lobste.rs Markdown ate your tag examples.
Better to just have links to SVGs in your code. Even hobbyist systems have SVG renderers because they’re trivial.
This would (theoretically) work in a terminal, though.
Kitty’s image API could render it
You need to use complex font technology to render them properly. More complex than SVG. I would rather switch to a framebuffer and see the SVG. Without the font, the diagrams actually look pretty terrible.
I’m a HUGE text enthusiast, but having gone down this path before, it doesn’t work out as nice as you’d think. Sticking to 80-120 column terminals is also a problem. Many non-trivial diagrams expand pretty wide.
I agree but sometimes people like having intermediate solutions for when their terminal doesn’t support SVG or they’re ssh’ing somewhere.
Not even mentioning phone keyboards? People don’t even press anything anymore they swipe and then completely change the word by picking a different suggestion! Go send some key events for that! 🌲
Oh, and mice are also mad now. People click multiple things at once, their cursor doesn’t move anymore and when they click something a really long time, oops we lied they didn’t click at all they’re just selecting something.
Oh, and why do Ctrl+S for save and Ctrl+Q not work in terminals? Because the terminal people wanted to use that for terminal stuff like windows is using Alt+F4 and MetaL+l!
Lol - you are 110% correct of course. What does “keyboard shortcuts” even mean for the vast majority of computer users.
My, the entire GitHub issue is full of people using the C++ toolchain. It feels like Andrew made a language, and is now discovering that most of his users (or at least his most vocal users) actually came for the toolchain.
Huh, not just any users, but some pretty high profile ones like Mitchell Hashimoto, of Hashicorp fame: https://github.com/ziglang/zig/issues/16270#issuecomment-1614062991
I genuinely thought this was a well understood thing. AFAIK, the most significant “corporate” adoption Zig has found so far has been Uber who exclusively use the toolchain and not the language. Most news I hear about Zig from outside of that ecosystem is about their linker zld or some big improvement to
zig cc
, rarely the language.Perhaps a clarification is needed then. To me it looks like the respective goals of the project and its users aren’t quite aligned.
I personally was a bit surprised C++ compilation is so important. Especially since interfacing to it is such a pain. The Zig FFI is only to C, right? So those C++ users have to make a C API anyway. From the outside, it makes sense to me that C++ compilation is just an ancillary benefit of the Zig toolchain.
Also, users who consider quitting Zig over this change may be users the project doesn’t even want at this relatively early stage (where “early” <= 1.0): those who value the toolchain more than the language are using short term considerations, and building a language (I think it’s obvious to anyone that’s Zig’s main goal) is a long term thing. It’s not for me to judge, but perhaps the best course of action is to go through with that plan, bite the short term drawbacks, and accept the loss of users and donations.
What’s really disheartening though is that Andrew built a language, and so many people cared more about the toolchain. It’s like remembering Leslie Lamport for LaTeX instead of his work on concurrency and formal methods.
Yes, this reminds me of the situation with ksmbd, which Samsung developed to support SMB Direct, but approximately all users simply want to avoid Samba’s GPLv3 license.
The language is still unstable, it’s expected that corpos don’t invest into using it yet. Maybe they won’t even once it gets stable, but the current situation tells us nothing in that regard.
I agree the situation is expected, but it could have been the case that Zig is so attractive companies start to use Zig even if it is unstable. That didn’t happen, so it tells us something. A small something, but not nothing.
(Unexpectedly, Dropbox started to use Rust even if it is unstable, because Rust was so attractive to their goals.)
Not while we’re still breaking for loop syntax :^)
TBF, Go is planning to break its loop semantics in version 1.22 next year. :-)
And TBF to Go, it’s mostly fixing it (if what you’re talking about is the
i := i
loopvar hack).Yes.
It is kind of ridiculous zig cc was produced by Zig community and not C++ community. Isn’t C++ community much much bigger?
One possible explanation is that while C++ has much much more compiler consumers than Zig, gap is smaller for compiler producers.
Zig cc doesn’t do anything particularly magic. It uses support that’s already in clang, it just provides the contents of the sysroot directory and sets the –sysroot and -target flags for you. Companies that care about this typically already provide configured versions for the targets that they care about. For example, XCode can do this for multiple macOS / iOS versions.
As with other similar efforts, zig cc is limited by licenses. If you want to cross-compile for Windows, I believe the visual studio redistributables allow you to install their headers and libraries on any system for the purpose of cross-compiling (I believe the person doing the compilation is required to accept the license, not sure how Zig does this), so it’s ‘just’ a matter of getting the right files. Apple explicitly prohibits this. Zig works around that by building their own sysroot from Apple open source bits, which hits a brick wall as soon as you want to use anything not in the open source repos (e.g. any of the GUI frameworks). Building a sysroot for most *NIX systems is fairly easy and most companies that want to cross compile for multiple *NIX variants build their own.
It’s not as simple as you make it sound.
Example 1: https://github.com/ziglang/zig/blob/master/tools/gen_stubs.zig Example 2: https://github.com/ziglang/glibc-abi-tool/
There is a bunch more stuff like this that goes into it.
I’ve heard people say the same thing about Go, that they aren’t there for the “language,” but are there for the toolchain and the experience it creates.
Our experience of technology is meaningful.
What are people using this toolchain for? I would have expected it to be pretty useless unless one also uses the language.
zig cc
basically completely takes care of cross-compilation for any target. It’s pretty much a clang distribution that can cross-compile to whatever target you want without having to do any special trickery. It’s a drop-in replacement for gcc/clang, too, and is marked as stable, which is why you’ll see e.g. Uber using it.It’s really quite nice and am honestly surprised something like this was never made officially by the clang/LLVM project.
It did. That’s what zig cc uses. Clang supports a number of flags that make this trivial:
--sysroot
specifies the root to look for headers when compiling, libraries when linking.-B
lets you specify an alternate path to search for tools, so you can drop in an alternative linker, assembler, or whatever if your target needs one.-target
lets you specify the target triple.The only thing that you need to do is provide a sysroot.
For an open-source *NIX system, that’s trivial. If you have an install you can just copy the relevant files out of it. If you want to target FreeBSD, for example, if you just extract base.txz from any release, you have a sysroot that works for targeting that release and architecture. It’s a bit more complex if you want libraries from packages, but they’re usually tarballs + metadata and you can just extract them into your sysroot.
It’s harder for proprietary platforms because you don’t have unlimited redistribution rights to their include files and libraries (or library stubs for dynamic linking). A lot of the Windows things can be extracted from the Visual Studio redistributables (though you must accept the license before doing this). On macOS / iOS, the T&Cs explicitly prohibit using any of their parts to compile from non-Apple platforms. Zig builds a macOS sysroot out of the open source Darwin bits, but that means you can’t use any headers or link any libraries that are part of the proprietary components, which includes all of the GUI frameworks and most system services.
That’s true, clang is a lot better in this regard than gcc. I still find it completely insane that gcc requires a fully separately-built toolchain to do any kind of cross-compilation (at least it did when I looked into it last year)…
Still,
zig cc
definitely hits the spot when it comes to the convenience - no need to deal with sysroots or alternative toolchains. Just specify the target and it figures it out.I think they’re working on it. At least gdb can now be built with support for multiple targets. It makes sense when you consider the history. GCC started at a time when memory was measured in single-digit megabytes and disks were typically double-digit megabytes. Cross compilation was rare and so there was absolutely no desire to make compile times longer (the first time I compiled GCC, it was an overnight job, and that was quite a few years later) and add disk space requirements for a feature that very few people needed. Target selection was done with
#ifdef
, which meant that you weren’t paying any indirection cost at run time (which would have slowed things down).In contrast, when clang came along, computers were already pretty fast. I started doing LLVM dev on 1 GHz machines with >1 GiB of RAM (I did a lot on a 1.2 GHz Celeron M, which took about an hour and a half for a clean build). The overhead from indirection in the per-platform or per-CPU bits was tiny and compiling all targets didn’t add a huge amount of time (10-20%), and being able to test all targets from a single was considered a benefit that outweighed all of the costs. In particular, few people are expected to build LLVM from source (the GNU project expected everyone to build GCC from source, early on, because that was how you distributed it), only developers and distributors. Developers benefit from taking 20% longer to build a single binary that can compile for anything rather than having to build 10 different binaries.
One of the problems with big software projects in general is that they must be built with the constraints that are present when they are started and typically grow to be useful and widely supported by the time that those constraints have changed. For example, LLVM began very early in the multicore era and so none of the core data structures were designed for concurrency. If you modify any function that refers to a global, you must modify that global’s use-def chain, which means that you can’t do that concurrently with anything else in the same module. There’s been a lot of work on ThinLTO to try to bring parallelism back, but building this from the start would give you something very different. And, by the time you’d finished, people would complain that it didn’t use your quantum AI coprocessor, which could do compilation much faster.
This works only because zig cc provides packaged toolchains for some platforms. If you want to target anything else (e.g. macOS with Cocoa), you’re in exactly the same place you are with clang.
Wait, cross compilation is still hard? What year is it?
I would like a meme for this; you wonder what the problem is and it turns out there is a much bigger problem. As if, you wonder why the car doesn’t start and then realize it doesn’t have an engine.
I burnt several weekends trying to cross-compile my Rust project from macOS ARM to Linux x86 with Nix so yeah… it’s still hard.
Cross compilation and cross linking for C and C++. Build executables for any platform. No other toolchain can do this.
In addition, zig packages stand out for being really easy to compile, because they take advantage of the built-in C++/Objective-C support in the compiler. Rather than shelling out to any subprocess, the zig community has been porting projects over to use
build.zig
instead, socmake
doesn’t need to be installed.There are also may PRs that members of the zig community have made to (such as this one) to add
build.zig
as an alternative build system for open source projects. All of that work goes away for non-C projects.On top of that, Uber has been paying the zig foundation to develop the cross-compiler for C++. Removing the cross-compilation support feels like zig is shooting itself in the foot in terms of adoption.
It probably would make sense to split off the toolchain into its own project then (that calls the Zig compiler on demand)?
So much truth in this article…
I say, let the young play with the shiny new toys.
I say, stable, stable, stable.
node
,npm
,nvm
,save-exact
.Few, well maintained, with a decent community packages.
You got a good API, plenty of examples, battle tested… It still puzzles me why we self-sabotage all the times in the js world and we try to reinvent the wheel forgetting all the past experience…
This is just the consequence of the above. The amount of pain the fragmentation of the ecosystem produce is unbelievable.
I’ve used moment.js before but it’s huge and bloated. There’s no reason to use it on the frontend. Here is how you print a time, no library needed:
Given the poor state of many things we should really not discard Innovation by insisting on stability too much, right?
Feels like anything controlled in a sufficiently large portion by a for-profit enterprise will inevitably get worse over time. Just happy I can still self-host a mail server without huge problems.
So glad we have a word for this now.
And its meaning is already drifting, I guess. I’d have said that what the big players are doing to email is more like a sort of distributed EEE. They largely haven’t progressed their email services along the enshittification pipeline at all. Gmail’s current iteration is more annoying than what it replaced, but I think it’s still trying to provide a useful service to its users, to the extent Google’s batshit product management is able to optimise for anything you can’t measure with a TSDB.
Google has enshittified plenty of things—search, maps, chrome, anything to do with android—so just to be clear, I’m definitely not saying that they wouldn’t enshittify email-the-product. But it’s not a good move, economically, to enshittify a product that still has meaningful competition, so I think they’d have to kill email-the-protocol first. And although Big Email has a shared interest in making email worse, they won’t cooperate on ending it completely.
Admittedly Gmail could be more transparent about its spam detection algorithm but even their product teams know that email-the-protocol is too ingrained into literally everything for them to think they could replace it without creating a rowboat situation for themselves or they would have already.
The SMTP protocol /is/ ancient and its design reflects that. There should be a new protocol or at least a new version so that an MTA that isn’t a collection of antiquated necessities can be built.
Have you seen https://jmap.io/ ? It’s specifically not for MTAs but for mail clients, though.
I really like JMAP but it’s suffering from ecosystem problems. The servers don’t want to implement it without client support, clients don’t want to invest in it until it’s widely supported by servers. Clients really need to go first because they tend to already couple the things that JMAP integrates, whereas sending mail, receiving mail, managing calendars and managing contacts are often handled by different things on the server (there’s a proxy that can talk to an IMAP, SMTP, CalDAV and CardDAV server, but then you don’t get all of the benefits). Servers also need to change their model a bit: JMAP removes the idea that each email lives in one canonical folder and integrates smart folders as a core idea.
It’s a cool idea, but I’d really like to see the RFC for existing protocols updated.
If this is enshittification, then it’s pretty indirect because Google isn’t actually squeezing value out of the email users except maybe by pushing people towards large email platforms.
Isn’t it a problem for you that mail sent from that server is likely to end up in spam folders if users of your mail server write to Google (or, as another commenter points out, Microsoft) users?
I’ve run my own server for decades and a school’s server for a little less than a decade, and gmail never did that to me, no matter what my users did. The worst that happened was rate limiting.
OK, each user will have a secure database which maps unique IDs to human-readable aliases.
Where does that database live? It definitely can’t live on any specific device, because I (as a user) have many devices, all of which need to have the same “petname resolution” behavior.
So this means the database needs to live at some third-party endpoint, which all of my devices can access. This (necessarily!) represents a delegation of trust.
And I’m definitely not going to run my own petname database, I’m going to outsource that work to a hosting provider. So then what is the difference between this outcome and, basically, DNS? The trust model is more or less the same, isn’t it?
My petname database is stored locally on devices I own and replicated across my devices.
Data doesn’t have to be centralized in order to be accessible from more than one location. Decentralized systems have existed for decades, and interest in them is growing. The Petnames paper introduces one small part of that, which is decentralized naming systems.
The reason my ad-hoc system is not as convenient as storing all my personal information in the Apple or Google cloud is due to the economic incentives of capitalists for whom “personal information is the new oil”. They can pump a lot of money into software with a polished UI, and they call sell hardware with that software preinstalled.
But I am hoping to transition to more convenient and easy to use software that is private and local-first. There are a number of projects. Today I am planning to dive into <anytype.io> and see if that meets my requirements. Please reply if you have opinions or experience with private, local-first, decentralized personal computing software.
Data doesn’t have to be centralized to be accessible on multiple devices, true. But devices have to know where to send their local updates, and how to receive updates from other devices. And the only practical way to do this kind of synchronization does require a centralized coördinator.
For one reason, because updates between arbitrary devices like phones can’t rely on peer-to-peer, gossip-style communication if they’re expected to be reliable. You need a clearinghouse to take responsibility for message receipt and re-broadcast.
But more importantly, because you need a single source of truth for the set of valid devices. If a device is lost or compromised, you need to be able to revoke that device from the list with authority.
So, I’m curious! —
How do you replicate it?
I’m down with local-first! But there’s no avoiding a centralized coördinator. If you don’t want to trust that coördinator, that’s fine, you can encrypt before sending, and decrypt after receiving — but that makes the payload opaque, which makes optimizations (delta compressions, etc.) really difficult.
—
It looks like this service hosts user data encrypted with a single shared key on a (private?) set of IPFS nodes. Those nodes act as the centralized coördinator I describe above.
IPFS is a content-addressable storage system, so updating a document will create a new document with a different address. This kind of punts on all of the data synchronization issues, and means that updates to a document are not observable by consumers of that document, without some additional out-of-band effort. It doesn’t look like devices can be managed individually, or have unique keys. It doesn’t look like the key(s) can be rotated.
In the petnames essay, it says “names can have two out of three properties: decentralized, globally unique, human meaningful.”. Petnames are decentralized and human readable, but not globally unique. Decentralized architectures are a compromise: you gain useful properties, you lose other useful properties.
If I store all my personal data in a third party cloud, then I have a single source of truth (something you want) but I lose properties that are more important to me. First, I have to trust the third party that runs my cloud. Second, I can’t work offline. I want a local-first compute environment that is highly tolerant of being offline. What I am willing to give up is a single source of truth. If I edit documents on offline devices, then they become out of sync with their replicas on my other devices, until synchronization time arrives. If I make changes to the same document on different devices, I may have to resolve conflicts. I’m sure you’re aware that git can support this kind of decentralized workflow.
For a specific example, I have a cellphone, a laptop, and a desktop. They each contain copies of my personal data. I sync data manually between them, but there is no master. I’m looking for something more seamless and automatic, while remaining decentralized. Suppose I’m travelling with my laptop and cellphone. I have no internet or cellular connection. I’d like to be able to seamless sync my laptop and cellphone (via bluetooth or wifi hotspot) without a lot of ceremony. Neither one is the master; new changes on one get propagated to the other. My desktop at home won’t be synced in this situation, since it isn’t reachable. Maybe that explains why I want a decentralized system without a single source of truth.
Anytype.io uses different definitions of “local first”, “decentralized” and “open source” than the ones I was expecting.
I get it. There is no authoritative source of truth for your personal data, there is only the individual view(s) of that data on each device, which are the result of applying all of the updates received by the device. And it should definitely be possible to share updates between devices directly, without going through a centralized coördinator. I agree!
The problem is: how? Specifically?
Are you aware of any mechanism for an iOS application to broadcast an update to a set of trusted peers, and for that update to be reliably received by a commandline application that’s running on a nearby laptop which identifies as one of those peers? And furthermore, that those updates can also be reliably delivered to an Android application which only connects to the internet (or comes close to the laptop or iPhone) some days later?
As far as I’m aware, there is no practical solution to this problem. Bluetooth, Bonjour, etc. just don’t provide the necessary discoverability and interoperability. Even if they did, it’s insufficient — I shouldn’t need to bring my Android physically next to my iPhone for them to have the same view of my data, I should only need to connect them both to the internet. Moreover, if I connect my iPhone to the internet on Monday, whatever updates it has should be received by my Android when I connect it on Tuesday. These kind of table-stakes requirements are only solved with a centralized and stateful coördinator.
This UX is what matters, and UX is bound by the constraints of the underlying technology. All available evidence suggests the best compromise solution for these kind of use cases is to proxy updates through a centralized third-party service over the internet. That sucks, sure! But fixing it requires changes the underlying protocols, and the APIs they provide to relevant devices.
Here’s what I would consider a practical solution for me, and it’s fully decentralized and peer-to-peer. If any two of my devices are both connected to the internet at the same time, then, using an appropriate protocol, they discover each other and synchronize with each other. In practice, my desktop is always running and connected to the internet, so it would normally be always available to act as a synchronization point. For other people, their cellphone is always turned on and connected to the internet, and could serve the same role.
Given appropriately designed software, the UX is simply the requirement to register each new device you get with an existing device in the peer group, so that they all know about each other and will sync with each other. This is not any more difficult than registering each new device with your third party centralized sync service.
I haven’t tried to actually implement this, but I know that suitable protocols exist, and that they can use distributed hash tables to allow peers to find each other without the need for static IP addresses on all peers. Tor Onion Services are an existence proof that this is possible.
I also said I want to sync locally if the internet isn’t available. You say that this isn’t practical, and claim that Bluetooth and Bonjour aren’t good enough. But you don’t convince me that this isn’t possible. Elsewhere on this page, @crazyloglad mentions they are working on “(Arcan) A12 where the constraints are such that DNS is not an option (e.g. transiently airgapped networks) where fleets of user-facing devices still need to dynamically discover and join together to form a network transparent desktop”. If they can figure out how to do that, then why can’t we have software that lets two of my devices discover each other on a LAN and sync? Maybe I should learn more about Arcan.
There’s a lot of complexity hiding behind “an appropriate protocol” :)
Discovery requires some kind of coördination. You can have everyone register with a centralized server, like DNS. Or, you can do some kind of P2P thing, like Tor/Onion. But you can’t avoid seeding each node with an initial set of peers, which you either have to specify manually (laborious, unreliable, bad UX) or — you guessed it — fetch from a centralized server.
(In fact, even if you’re manually specifying the initial set of peers, you’ve almost certainly just copy/pasted those IPs from a website somewhere, which is effectively the same thing as querying a centralized server for them!)
While end user devices can pretty easily make outgoing connections, it’s unfortunately very difficult to get them to reliably accept incoming connections. Most carriers and many ISPs will prevent it outright, and even when they don’t, there’s an infinite universe of complexity in dealing with NAT.
Systems that need end-user devices to be able to accept incoming connections (like Tailscale for example) often solve this problem by having the device make an outgoing connection to a — you guessed it — centralized server, which proxies incoming requests back through that connection.
Oh there are all kinds of mesh network protocols and local network discovery mechanisms, almost uncountably many. The problem to solve here isn’t the technology. The problem to solve is the integration with the device and the user experience. Making it usable.
I say Bluetooth and Bonjour and all current technologies aren’t viable, because (as far as I’m aware) there is no software in existence today which has the synchronization behavior you describe. If it were feasible to do, then I have to believe that someone would already be doing it.
The ‘centralized versus distributed’ is a misdirect or a false dichotomy; there is a substantial difference from DNS as an externally authoritative distributed asynchronously mutating namespace versus internally (yourself) synchronised swarm of cutesy names you call things you like/dislike over ephemeral rendezvous points (coordinates really). Centralised as in pub, not as in tax office. Relatedly, scale isn’t millions of names but the much more manageable tens-to-hundreds – your silicone family.
Unless ‘hung drawn and quartered’ comes back into fashion your are also not geographically distributed (and if it is, well, other problems take priority. You might be in Japan, you might be in Germany or travel between the two but there is a substantial latency and tolerance depending on the time at airport checkin.
For that, pub/subscribe with the “trusted third party” being another instance of you and part of your namespace suffice as petname is transport securing pub-key doubles as state-authenticating signing key. Meet up at the pub at table #5 to coordinate the heist kind of a thing, leave ICANN out of it.
You can punch your swarm of devices as a synch operation (or NFC tap / ubikey for when kinetic energy fails to initiate key transfer) or huddle up before playing ball, You can’t punch DNS as easily as NAT (even though one might like to do that on a daily basis) as others get sad and disagree with your naming of things.
As for the integration side, it is absolutely not OSI layered, hence why few seem to already be doing it: https://www.youtube.com/watch?v=_RSvk7mmiSE (2019)
I’m not totally sure what you’re talking about.
It seems like you’re suggesting that resolving a given identifier could yield different results depending on client identity, locality, or jurisdiction. Is that true? If so, can you give some examples of this kind of identifier?
Something which doesn’t qualify is, say, Google. When I type google.com I need to get the same logical result, regardless of where I am, or what my local pub is, or what I decide is my silicone family. The concept of google.com is invariant to all of those things. Any system which returns a different logical result for google.com based on any of those variables is broken. My local pub does not get to decide what google.com means.
(Different physical results that take advantage of e.g. CDN locality is a different thing, of course.)
The LAN discover case is somewhat easy, depending on threat model. compromised-by-default IoT devices or others on your corporate network building public key databases or leveraging discovery beacons for denial-of-service amplification is a somewhat spicier challenge. mDNS (Bonjour) comes from the era where this wasn’t much of a threat and pragmatism “I need to find my printer, whatever the cost” ruled (and the cryptographic tools needed weren’t exactly for public consumption at the time).
Unless you are the retrocommunications nerd running your network as a token ring or single chain coaxial, chances are kind-of high that the stricter ‘peer-to-peer’ definitions will fail by being bound to a physical layer that has a hub an spokes kind of a topology. There’s still a difference from that as centralisation to one of [FAANG] serving the entire world and forcing that as a design constraint for how the protocol is supposed to scale.
The HCI model is more involved than that (at least from my ‘networked desktop’ perspective) as it is not just about the different device having synchronised access to the same world state, but for them to act as different kinds of sources and sinks. This is why I have a local namespace of petnames (“connection points”) that correspond to access control models that links together with the networked form. Examples would be to connect “this part of my desktop is allowed to manage the clipboard and inject input” to a networked device that I am actually using to generate the input, or “my mobile phone is allowed to act as video source (webcam) on my desktop, but not synch my documents folder”.
For rediscovery on the global internet you will need some form of third party rendezvous, but that does not have to be an 8.8.8.8 like behemoth, but a virtual piconet like master of your very own terror cell. That one can also act as traffic relay or NAT punch, as well as state store / backup. Alas it also opens up the can of worms that is ‘transitive trust’ as the other option being manual management, which is .ssh/id_rsa annoying or the physical form of annoying with having a TPM in your keyring.
A Petname system implies nothing about your database being secure. It’s the underlying names in it that are secure, in the Zooko’s Triangle sense, i.e. no one else can use that name because they don’t know the corresponding private key.
You probably want the database to be secure for the same reason you want your existing contacts db to be secure, but it’s not a requirement of the system. In practice you can do things like add the cryptographic names as custom fields to address cards and keep using iCloud or Google or whatever.
A petnames database hosted for you somewhere requires trusting fewer people and machines. With DNS you delegate trust to the whole unencrypted path between your machine and the authoritative nameserver for whatever domain you want to reach.
You could also encrypt your database and then so long as you trust your software you could trust that your petname host could only do denial of service and rollback attacks rather than just feeding you arbitrary names.
Same for other sources of petnames, if they’re signed then they can be significantly higher trust than DNS.
You can store and synchronize with encryption easily if it’s only between your own devices.
Are we talking iCloud easy or rsync easy? 😉
I imagine what GP is thinking of is more like “Syncthing easy”, but you could even have your petname database sync with iCloud if you really wanted to.
Not if the database is encrypted with a local key or password. Sure you’d have to download it and upload it again every time you need to synchronise it (I’m guessing it could be automated as a background task), but it would prevent any funny business from the provider.
OK, sure, but that just kind of moves the issue of trust away from the DB provider, and into the key manager. That is, any reasonable UX for managing those keys across all of your devices would necessarily need to live at some third-party endpoint, for the same reasons. And now we’re back to the same issue of trust delegation.
Sure, when I use KeepassXC I have to trust KeepassXC. But if the protocol between DB and key management is standard, the DB provider and key manager may be separated, and protect me from the DB provider. At least with this scheme any bug or backdoor from the key manager may be spotted (if it’s Open Source like any security product should be).
Not perfect, but still better.
Or just duplicate your pet names across your devices. I do that with my password database, no online anything involved, and the occasional desync has yet to be a deal breaker.
I appreciate that your password manager doesn’t sync through a third party. I hope it’s not controversial to observe that this is a fairly niche setup, and is really only viable for technically sophisticated users such as yourself.
These edge cases are interesting and useful, but the ultimate test is the general case. It needs to be feasible for grandma to use the thing. Grandma can definitely be convinced to use a password manager, but only if it works across her iMac, tablet, and phone without extraordinary effort. She’s definitely not going to sync a password DB between those devices manually.
The only way to solve this problem, AFAICT, is to delegate that work (and trust) to a reliably accessible third party.
Under Capitalism. Otherwise I could see manufacturers agree on a standard, such that grandma can have one client per device, and one service of her choosing, all independent from each other if she so choose (typically that would be a Microsoft and Apple clients with a Google server). She would have to trust her client (Microsoft and Apple) that her data is not leaked, but the server (Google) will not be able do decrypt anything without her password.
Now syncing is a bit expensive: download the entire DB, merge, upload the whole thing again. Or maybe chop it up in a content addressed manner, but then you’d leak quite a bit of metadata, such as the number of entries. In any case, I can see it working for Grandma, if the big FAANG agree on such a standard even though they probably have no interest to.
The only reason Grandma can’t have that is because this kind of setup is not the default. If it was it would be as easy as navigating Facebook.
Well, two points. One, capitalism won and it’s not going anywhere, so there’s not much point in talking about alternatives, you just gotta treat it as an invariant. Two, I don’t think it’s capitalism that makes this true, I think it’s just that the market has made it clear what a viable UX looks like. Manufacturers won’t agree on a standard unless doing so serves their interests. Decentralization doesn’t really serve anyone’s interest, so there’s no incentive. And why would Google host this opaque data? It can’t do anything with it. Does grandma care if it’s encrypted on the server? No! Grandma cares about product features and capabilities. Encryption is incidental.
Sadly I’m afraid I’ll have to agree with you. Which is why we’re all gonna die.
The problem with capitalism is that it cannot last. Finite boiling world and all. What comes after depends how it phases itself out. Unfortunately I’m anticipating a severe reduction in human population (we’re not all gonna die, but I can easily see most of us dying), and with it disruptive social changes. I don’t see capitalism surviving its own collapse. Or maybe the situation isn’t as dire as I think, and we’ll just continue the cyberpunk route we’re currently taking. Some kind of corporate fascism, if not good old fascism.
The rest of your analysis I also agree with: the incentives just aren’t there. They could make a nice UX for privacy-preserving decentralisation and all that jazz, but I agree they just won’t.
I haven’t lost all hope however. I do believe an alternative to capitalism has a chance. But just thinking that throws me outside the Overton window, and that’s a problem.
I could upvote this without reading.
This is false.
Is wrong and so is the title of this article: Web-based cryptography is always snake oil
There’s a way around your issues:
You mentioned the second one but you just need to have an extra verification of the index.html. Just make it open source, pin the version and verify that you’re getting everything. Boom, done. Once you’ve done that then you only need to worry about browser itself being hacked and not the website code.
Posting another thing wrong about this article:
The Lavabit situation is also explained incorrectly. Levison wasn’t forced to modify his website, rather he was forced to give up his SSL keys. He did offer to give up Snowden’s emails specifically but your article is wrong enough to be harmful.
This is a theoretical solution. Signedpages is a browser extension and not a web compatible solution. In practice, easy distribution and updating is one of the main benefits of the web as a software distribution platform. So, sure you could verify but what do you verify against? The best you can do is something like CT so you at least cannot be attacked individually but that also doesn’t exist yet.
For the verification just check it against the git release hash or npm somehow.
It’s theoretical but it’s perfectly valid and simple enough to implement. The author is saying that this is impossible when that’s false given the current technology available to us.