HN user

solatic

8,181 karma
Posts6
Comments2,119
View on HN
Ramp Router 2 days ago

free to use at launch

How does this help me control spend if I don't understand how much it will cost me a year after I bake it into my infrastructure?

For someone else it's the wrong choice, they don't know Python

The author ruins their entire argument with this one claim.

If "we picked this tool because we know it best" is a legitimate requirement, then every tool choice is justified as a "perfect" choice because it's what the architect was most comfortable with. If your emotions and current knowledge levels are considered reasonable justifications for a "perfect" solution, then all solutions are perfect solutions; they simply haven't had enough emotional justification yet. If all solutions are perfect solutions, then none are.

There are, ultimately, two kinds of software - those that need to ship by a deadline, and those that don't. A deadline forces you to eject dead weight that you don't need - requirements have a habit of getting clarified real fast when you need to build to a deadline. If you had time to over-engineer despite a deadline, you should consider working for a more productive organization. Meanwhile, the concept of "over-engineering" is a little vague for software that doesn't have a deadline. If you don't have a deadline, you don't have to compromise on quality. "Over-engineering" is then just a value judgement that you made poor use of your infinite timescale and built the wrong things with it. But who is making that judgement? Not the person who built it, not the person who funded it (i.e. usually self-funded as a hobby project), and not the person who uses it (since over-engineering is an implementation detail, rather than a product choice), so who cares?

edit: to clarify: "pick a stack you know already since we don't have time to learn a new one" is a totally valid requirement. But I disagree that it means that you built a "perfect" solution with it. I also disagree that you usually need to build perfect software - getting comfortable with adequate is how most people ship most software.

You can, of course, add traits. But at this point you're essentially creating your own language that compiles to Zig

I think herein lies the rub. What's the difference between a static analysis tool and an actual separate language that transpiles to the original? Hypothetically - again, very un-ergonomically - you could add traits to Zig code in comments, or in example-traits.typezig files that would be skipped by the Zig compiler (like how *.d.ts files are skipped). How much of a language is writing code in a particular syntax, versus how much of a language is writing code that will pass a tool "building" it, versus how much of a language is about the final compiled output that you get from the tool? All static analysis tools that support line-level exceptions are, essentially, programmed by comments, with their own language (typically highly simplified compared to a "full" programming language), that affect whether or not the "language" passes or not. What Typescript/JSDoc shows is that, actually, much more complicated tooling can be built with this programming-by-comments model than had been done before (to my knowledge), and thus even more powerful still tooling could be built with that model.

Of course there's a difference between static analysis and a language that transpiles. But perhaps it's more a question of degree than a simple binary classification.

Zig has no private fields

You may have missed the point here. You could add a comment to the struct field that marks the field as private, and build a TypeScript/JSDoc analogue that analyzes all accesses to the field and fails if it finds accesses from functions that aren't part of the struct that owns the field. You don't even need a comment on the field - you could copy Go's convention, add a comment to the struct definition marking it as "follows Go convention", and then fail any access from outside the struct to a field that starts with a lower-case character.

It doesn't prevent you from ignoring that tool and writing Zig code that imports the struct and accesses the field. It is, of course, not part of the Zig language itself. But if you adopted a tool like that, it would be your responsibility to run it across-the-board and pay attention to the results - same as how it is your responsibility to pay attention to the results if you added those JSDoc comments.

I wouldn't say it's impossible, rather un-ergonomic. TypeScript can add type information to ordinary JavaScript code via JSDoc comments; the result can both be executed as ordinary JavaScript as-is and type-checked with TypeScript. But it's a huge pain to try to write (and maintain) everything that way, it was supported as a hack to help migrate legacy codebases. You could probably take a similar "the lifetimes are embedded in comments" approach with other languages, and the result would be similarly un-ergonomic.

I've said for a long time that composability in software is a bit like playing Tetris: the lines have to clear.

I love this analogy, and I find it darkly hilarious that most sibling commenters don't seem to understand. Maybe you need to have worked within a million-line codebase to get it.

The only way to "clear the lines" in software is to eject them from the main codebase and into imported libraries with stable, well-documented, well-tested APIs that you very rarely if ever (security vulnerabilities?) need to touch after "stabilizing" them. Great public examples: the Go standard library, https://github.com/spf13/viper , https://github.com/uber-go/zap . Viper and zap combined are more than 20,000 lines of code (according to cloc) that I don't need to read or understand how they work - their lines have been "cleared" and all I need to know is the abstraction.

Half the joy to be found when working within massive codebases is successfully clearing lines.

I'm not convinced. Hyperscript's reactivity model is highly greppable, and it keeps the no-build approach to Web frontend interactivity. It's "just enough" in the same way that HTMX is.

React probably scales better for huge engineering divisions, but that isn't who the GOTH stack is aiming for anyway.

AWS and Google at least own their own hardware (Trainium and TPUs, respectively). It's a moat in the sense that designing, building, and deploying your own chips at scale is quite a feat and not easily replicated. The vertical integration will allow them to continue to be profitable once the models get good enough and competitors' prices race to the bottom. Google has Gemini; AWS may not deploy its own models (yet?), but that's not necessarily a losing position, as long as the market is able to run models sourced elsewhere on Trainium and the price is right.

have never measured it

That's because it's practically impossible to collect objective data here, i.e. without confounding factors.

A product where the user spends 99+% of their time reading/consuming is almost certainly easier to use with a GUI. The market settled on thumb-flicking for doom scrolling instead of a button or scroll wheel interface, for a reason.

A product where the user spends 99+% of their time writing is almost certainly easier to use with a keyboard. Most sane people do not write essays on their phones with two thumbs; a keyboard and a proper word processor are preferred.

Most products fall somewhere in the middle. Most products have multiple interfaces, some primarily for consuming information and some primarily for producing it, and thus would find different inputs more productive in different modes. When people claim that they find one input type is more productive than the other, most likely is that their particular use-patterns fall more in-line with the one most aligned with their use-patterns.

10 years ago, apps had to explicitly state if they needed network access. And then the powers that be decided that really all apps need network access no matter what.

Why does network access need to be a binary, all or nothing?

When you install an app, the app should request permissions to specific DNS names, i.e. pointing to the servers that the app's authors operate. If I install Todoist, the app should only ask for access to Todoist's servers. If I install Netflix, the app should only ask for access to Netflix's servers. The OS can then put a DNS firewall in and block any network access that wasn't granted when the app was installed.

And both ios and android make it hard to deny apps network access

The list of apps that genuinely need "any" network access (web browsers, VPN apps, stuff like Termux...) is incredibly small compared to the list of apps that need access to a small number of VPN targets (these days, most apps). Apple / Google could even decide, if they really want to make it easy for apps to request network access, to basically allow apps to automatically get network access, so long as the list of domains the app needs access to is no more than a handful. The security value of isolating "all" network access permissions to only the relative handful of apps that actually need to request it, would be huge.

Yeah, I'm working on a communications platform as a side-project, architecturally providing reliable communications is exceedingly difficult to self-host.

* Mobile calls are another form of push notification, Apple/iOS requires setting up APNS and Google/Android requires FCM, there is no self-hosted option for that at all and, for battery life reasons, no independent replacement is supported. Genuine ownership / independence from the main project requires, iirc, basically compiling from source to register different IDs against APNS/FCM.

* Trying to get into telephony, integrating with SIP is a huge pain. Nobody wants to deal with this.

* Nobody supports high availability for the underlying calls. None of the cloud L7 load balancers support media protocols - you're dropping down to L3 UDP load balancing. All of the available solutions (including LiveKit) depend on stateful services that, at best, place ceilings on call lifetimes (e.g. 5 hours) to allow for graceful draining, but "calls" in Discord-style settings where people connect to a room and stay connected will easily outlast those ceilings. Not supporting high-availability, IMO, is a huge ask for self-hosters - the price isn't in the maintenance window itself, but in deferring updates until the maintenance window, which can leave you vulnerable, particularly if you decide to leave the firewall open to ingress from 0.0.0.0/0 for ease of use. And of course, as a self-hoster, you rarely have a full follow-the-sun ops team, so either you schedule maintenance when everybody else is off (and you should be off too) or when everybody is on (and it's disruptive).

Surely having these guarantees for some packages beats having it for none? You can just define that option in your own configuration

This is exactly what I'm talking about. Once you have Nix on your system, it infects everything. You want to let it control everything, because that is where its power is. Your life would be so much easier if you could let it control even more, like the stuff you share with your team. It's the siren call. And then you find yourself pitching it to your team, and then you inevitably fail to pitch it, because you ramped up to it over months and it's just impossible to get anybody else ramped up to Nix that quickly.

It's guaranteed heartbreak every time and I got sick of it.

You can just silently use it and enjoy the convenience for the declarative parts of your setup, with no detriment to your ability to run the imperative, ad-hoc setup scripts that your company requires.

That's the kicker though. Nix's benefits come from the guarantees it can make based on its integration with the rest of the Nix-controlled ecosystem. Without the control, you don't get the guarantees, and you lose the raison d'être. You need to actively avoid the "value-added" parts (e.g. package options) because latest Homebrew upstream may give you a version that exposes an option that is not yet exposed by the package options, and you can't patch the package with Nix because you're not using a Nix-based package.

Chezmoi is declarative. The templates give me generated configuration. I can rollback anytime I want by reverting Git commits and calling chezmoi apply. It works well within its less-ambitious goals (compared to Nix).

I ran NixOS for a while, before I switched to Apple Silicon, so I consider myself fairly well-versed-enough (although nowhere near an expert) in Nix and the Nix ecosystem. My last four jobs have all issued me MacBook Pros; the last three with Apple Silicon.

Ultimately, my workplace setup is what has the most gravity. And the most I can get most workplaces to standardize on is Homebrew for package management of off-the-shelf software. Nix is so far outside of the wheelhouse for most engineers that I can't even propose it. It would be too much of a distraction for too many people for too long that it's just not seen as worth it and it's not worth spending the political capital on the attempt. Employers would literally prefer to run scripts from a whitewashing, barely-auditable Jenkins instance with parameterized jobs than to attempt to figure out how to distribute portable scripts and get everyone's permissions working.

So I need to pick software that will cooperate with other tools in an unstable fashion, rather than software that attempts to fully and exclusively control the environment to provide guarantees. Chezmoi fits. Nix and home-manager do not.

Stop Using JWTs 1 month ago

Necessary qualifier: for browser-based user sessions.

Plenty of good uses for JWTs for service-to-service communication.

edit: I read some of the linked stuff, e.g. https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-ba... . Please, if JWTs are such a horrifically insecure standard, go ahead and publish your means for hacking AWS STS's AssumeRoleWithWebIdentity , or don't publish and just exploit it by launching cryptominers in every Fortune 500 production AWS account. Let me know when you inevitably succeed, because JWTs are so insecure, right? /sarcasm

many people who’d consider a VPS would happily slap a .env with an unencrypted secret then ssh to update

I just want to point out that you can totally still do this with Kubernetes. Of course it's not correct, but you can save that unencrypted secret in a .env file right into your container while you're building it - no need to use Kubernetes's support for supplying environment variables from the manifest. And of course, you don't even need a Dockerfile to build that container - you can just exec into a running container, paste it in, and then docker save.

Kubernetes doesn't save you from making stupid decisions, it just makes it easier to make better ones.

Have you considered just answering truthfully?

To give you just a little more context than other commenters -

You answer truthfully when you're interviewing from a position of power. Either you're already employed somewhere and you're taking your time exploring your options to see if maybe you can end up somewhere a little better, or you're an employer with applicants lined out the door and you want to winnow them down to the best match. In either case, you don't care too deeply if an individual interview sucks, you just move on.

Truth is always the first casualty of war. And when someone is out of work and fighting for their ~life~ livelihood, or a founder is trying to convince the first customer or the first engineer to take a risk on them so that they can get their baby off the ground, the truth dies real quickly.

Did you read the original article?

The Facebook / Meta outage was so significant

The author specifically called out the Meta outage, as if he was offering a prescription ("It's easy to configure systems with tools like Ansible or pyinfra at scale") that would have prevented Meta (at Meta's scale) from suffering an outage. The argument that Meta should not have used DNS except that Meta runs at a scale where DNS is necessary... who comes up with these arguments?

It replaces DNS's pull-based architecture (contact a DNS server to get the IP address) with a push-based one (push the IP addresses to each /etc/hosts file).

Suggesting that a push-based, Ansible-based architecture will scale to hundreds of thousands of targets, with such pushes happening hundreds if not thousands of times a day, is a junior-level idea at best, dark comedy if I'm being charitable, and professional malpractice at worst.

Stocks going down didn't un-research drugs

Drugs cost pennies to manufacture after they are researched and make their way through the approval pipeline. There are many generic drug manufacturers who can work off the existing formulas.

The more apt comparison is that LLMs won't be un-trained. Opus 4.8 now exists. Even if Anthropic somehow went bankrupt, that particular asset could, at the very least, be sold for proverbial pennies on the dollar to a "generic" inference provider.

Concentrated ownership of the wealthy is not synonymous with “the public.”

I 100% agree. It's terrible that large private companies like Cargill and any others large enough to make this list: https://www.forbes.com/lists/top-private-companies/ are allowed to continue operating without being forced to list on stock markets and being subject to public reporting requirements. There's a very big difference between concentrated ownership by the wealthy and public ownership.

You are very literally arguing for plutocracy over democracy

You can only assume that public markets results in plutocracy if individual investors hold outsize amounts of outstanding shares. The elections for Boards of Directors are not competitive when an individual shareholder holds majority voting power. There is a separate argument for a wealth tax that I agree with, and there are arguments to be made for maximum share prices (reaching the maximum triggers an automatic stock split) to guarantee financial accessibility (cough, BRK.A, cough).

The public should own more than half. Via the stock market. Where public shareholders can vote in elections to control the Board of Directors, and elect Directors that act in the fiduciary interests of shareholders, and return excess capital to shareholders by issuing dividends. Where any member of the public can decide to buy or sell shares, being the most important development in the democratization of wealth development in all of human history, second only to the index fund that let members of the public put wealth development on autopilot?

When did public ownership mean that the government needed to be the owner? And when did we start to allow companies to float so few shares that public shareholder voting rights became largely meaningless?

The issue I have with these pieces is that AI will not affect the whole economy evenly. The disruptions come in bursts and fits: first digital artists were disrupted (e.g. Adobe Firefly), then junior engineering roles were disrupted, currently "measurer" roles (to quote Matthew Prince's piece on Cloudflare layoffs) are being disrupted, and it's rather foreseeable that occupations like lawyers and accountants are also at risk. But the key is that the disruption is not happening all at once. And that's a key fact because political disruption doesn't happen when a relative few people are laid off (like coal miners and factory workers were) but when a relative majority of people are hungry.

For such doomsdayer opinions to be correct, we'd see it in massive unemployment figures. US unemployment sitting at 4.3% does not bear that out. Finland and Spain are currently at >10+% unemployment. US youth unemployment may be at 9.5%, but British and Chinese youth unemployment are higher than 16%.

Is there some Finnish, Spanish, British, Chinese civil unrest that I'm not seeing in my media outlets?

But then why is it structured in that manner? What's the purpose?

This is bizarre. When you agree to take a $100k base salary, you don't get all $100k on the first day; your salary is split into pay periods, and if you leave earlier (voluntary or not) then you don't get the rest of the year's salary by default (severance aside).

I'll agree with you that RSUs for public companies should not have cliffs. But the idea that you agree to a large amount of compensation up-front (so that re-negotiation is infrequent) which is then paid out in portions on a regular basis is very standard, for both cash and equity.