Hacker Newsnew | past | comments | ask | show | jobs | submit | GeneralMayhem's commentslogin

Internal and external have wildly different requirements. Google internally can't update a library unless the update is either backward-compatible for all current users or part of the same change that updates all those users, and that's enforced by the build/test harness. That was an explicit choice, and I think an excellent one, for that scenario: it's more important to be certain that you're done when you move forward, so that it's obvious when a feature no longer needs support, than it is to enable moving faster in "isolation" when you all work for the same company anyway.

But also, you're conflating code and services. There's a huge difference between libraries that are deployed as part of various binaries and those that are used as remote APIs. If you want to update a utility library that's used by importing code, then you don't need simultaneous deployment, but you would like to update everywhere to get it done with - that's only really possible with a monorepo. If you want to update a remote API without downtime, then you need a multi-phase rollout where you introduce a backward-compatibility mode... but that's true whether you store the code in one place or two.


The whole premise of microservices is loose coupling - external just makes it plainly obvious that it’s a non starter. If you’re not loosely coupling you can call it microservices but it’s not really.

Yes I understand it’s a shared library but if updating that shared library automatically updates everyone and isn’t backward compatible you’re doing it wrong - that library should be published as a v2 or dependents should pin to a specific version. But having a shared library that has backward incompatible changes that is automatically vendored into all downstream dependencies is insane. You literally wouldn’t be able to keep track of your BOM in version control as it obtains a time component based on when you built the service and the version that was published in the registry.


> if updating that shared library automatically updates everyone and isn’t backward compatible you’re doing it wrong that library should be published as a v2 or dependents should pin to a specific version

...but why? You're begging the question.

If you can automatically update everyone including running their tests and making any necessary changes to their code, then persisting two versions forever is a waste of time. If it's because you can't be certain from testing that it's actually a safe change, then fine, but note that that option is still available to you by copy/pasting to a v2/ or adding a feature flag. Going to a monorepo gives you strictly more options in how to deal with changes.

> You literally wouldn’t be able to keep track of your BOM in version control as it obtains a time component based on when you built the service

This is true regardless of deployment pattern. The artifact that you publish needs to have pointers back to all changes that went into it/what commit it was built at. Mono vs. multi-repo doesn't materially change that, although I would argue it's slightly easier with a monorepo since you can look at the single history of the repository, rather than having to go an extra hop to find out what version 1.0.837 of your dependency included.

> the version that was published in the registry

Maybe I'm misunderstanding what you're getting at, but monorepo dependencies typically don't have a registry - you just have the commit history. If a binary is built at commit X, then all commits before X across all dependencies are included. That's kind of the point.


> ...but why? You're begging the question. If you can automatically update everyone including running their tests and making any necessary changes to their code, then persisting two versions forever is a waste of time.

I’m not begging the question. I’m simply stating what loose coupling looks like and the blog post is precisely the problem of tight coupling. If you have multiple teams working on a tightly coupled system you’re asking for trouble. This is why software projects inevitably decompose against team boundaries and you ship your org chart - communication and complexity is really hard to manage as the head count grows which is where loose coupling helps.

But this article isn’t about moving from federated codebases to a single monorepo as you propose. They used that as an intermediary step to then enable making it a single service. But the point is that making a single giant service is well studied and a problem. Had this constantly at Apple when I worked on CoreLocation where locationd was a single service that was responsible for so many things (GPS, time synchronization of Apple Watches, WiFi location, motion, etc) that there was an entire team managing the process of getting everything to work correctly within a single service and even still people constantly stepped on each other’s toes accidentally and caused builds that were not suitable. It was a mess and the team that should have identified it as a bottleneck in need of solving (ie splitting out separate loosely coupled services) instead just kept rearranging deck chairs.

> Maybe I'm misunderstanding what you're getting at, but monorepo dependencies typically don't have a registry - you just have the commit history

I’m not opposed to a monorepo which I think may be where your confusion is coming from. I’m suggesting slamming a bunch of microservices back together is a poorly thought out idea because you’ll still end up with a launch coordination bottleneck and rolling back 1 team’s work forces other teams to roll back as well. It’s great the person in charge got to write a ra ra blog post for their promo packet. Come talk to me in 3 years with actual on the ground engineers saying they are having no difficulty shipping a large tightly coupled monolithic service or that they haven’t had to build out a team to help architect a service where all the different teams can safely and correctly coexist. My point about the registry is that they took one problem - a shared library multiple services depend on through a registry depend on latest causing problems deploying - and nuked it from orbit using a monorepo (ok - this is fine and a good solution - I can be a fan of monorepos provided your infrastructure can make it work) and making a monolithic service (probably not a good idea that only sounds good when you’re looking for things to do).


> I’m not begging the question. I’m simply stating what loose coupling looks like and the blog post is precisely the problem of tight coupling.

But it is not! They were updating dependencies and deploying services separately, and this led to every one of 140 services using a different version of "shared-foo". This made it cumbersome, confusing and expensive to keep going (you want a new feature from shared-foo, you have to take all the other features unless you fork and cherrypick on top, which makes it a not shared-foo anymore).

The point is that true microservice approach will always lead to exactly this situation: a) you either do not extract shared functions and live with duplicate implementations, b) you enforce keeping your shared dependencies always on very-close-to-latest (which you can do with different strategies; monorepo is one that enables but does not require it) or c) you end up with a mess of versions being used by each individual service.

The most common middle ground is to insist on backwards compatibility in a shared-lib, but carrying that over 5+ years is... expensive. You can mix it with an "enforce update" approach ("no version older than 2 years can be used"), but all the problems are pretty evident and expected with any approach.

I'd always err on the side of having a capability to upgrade at once if needed, while keeping the ability to keep a single service on a pinned version. This is usually not too hard with any approach, though monorepo makes the first one appear easier (you edit one file, or multiple dep files in a single repo): but unless you can guarantee all services get replaced in a deployment at exactly the same moment — which you rarely can — or can accept short lived inconsistencies, deployment requires all services to be backwards compatible until they are all updated with either approach).

I'd also say that this is still not a move to a monolith, but to a Service-Oriented-Architecture that is not microservices (as microservices are also SOA): as usual, the middle ground is the sweet spot.


I worked on building this at $PREV_EMPLOYER. We used a single repo for many services, so that you could run tests on all affected binaries/downstream libraries when a library changed.

We used Bazel to maintain the dependency tree, and then triggered builds based on a custom Github Actions hook that would use `bazel query` to find the transitive closure of affected targets. Then, if anything in a directory was affected, we'd trigger the set of tests defined in a config file in that directory (defaulting to :...), each as its own workflow run that would block PR submission. That worked really well, with the only real limiting factor being the ultimate upper limit of a repo in Github, but of course took a fair amount (a few SWE-months) to build all the tooling.


We’re in the middle of this right now. Go makes this easier: there’s a go CLI command that you can use to list a package’s dependencies, which can be cross-referenced with recent git changes. (duplicating the dependency graph in another build tool is a non-starter for me) But there are corner cases that we’re currently working through.

This, and if you want build + deploy that’s faster than doing it manually from your dev machine, you pay $$$ for either something like Depot, or a beefy VM to host CI.

A bit more work on those dependency corner cases, along with an auto-sleeping VM, should let us achieve nirvana. But it’s not like we have a lot of spare time on our small team.


Go with Bazel gives you a couple options:

* You can use gazelle to auto-generate Bazel rules across many modules - I think the most up to date usage guide is https://github.com/bazel-contrib/rules_go/blob/master/docs/g....

* In addition, you can make your life a lot easier by just making the whole repo a single Go module. Having done the alternate path - trying to keep go.mod and Bazel build files in sync - I would definitely recommend only one module per repo unless you have a very high pain tolerance or actually need to be able to import pieces of the repo with standard Go tooling.

> a beefy VM to host CI

Unless you really need to self-host, Github Actions or GCP Cloud Build can be set up to reference a shared Bazel cache server, which lets builds be quite snappy since it doesn't have to rebuild any leaves that haven't changed.


I've heard horror stories about Bazel, but a lot of them involve either not getting full buy in from the developer team or not investing in building out Bazel correctly. A few months of developer time upfront does seem like a steep ask.

"Ignoring the code entirely and only prompting" is the only definition of vibe-coding I'm aware of. It's from a Karpathy tweet (https://x.com/karpathy/status/1886192184808149383):

> There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists... I "Accept All" always, I don't read the diffs anymore. When I get error messages I just copy paste them in with no comment, usually that fixes it. The code grows beyond my usual comprehension.

It specifically doesn't mean "using an LLM as a code assistant". It definitely doesn't mean asking the LLM questions about code which you'll then use to write your own code. Those are LLM-assisted activities, and it's totally fine if you're using the LLM that way. But it's not what the term "vibe coding" means. "Vibe coding" is giving up on any pretense that you're in control, and letting the LLM take the wheel. It's fun for getting quick projects done, but it's also now becoming a distressingly common practice for people who literally do not know how to program in order to get a "product" to market.


Turning around a track definitely dissipates some heat energy through increased friction with the rails. Imagine taking a semicircle turn and making it tighter and tighter. At the limit, the train is basically hitting a solid wall and rebounding in the other direction, which would certainly transfer some energy.

The energy question is this: going from a 100kmh-due-north momentum to a 100kmh-due-south momentum via slowing, stopping, and accelerating again clearly takes energy. You can also switch the momentum vector by driving in a semicircle. Turning around a semicircle takes some energy, but how much - and where does it come from? Does it depend on how tight the circle is - or does that just spread it out over a wider time/distance? If you had an electric train with zero loss from battery to wheels, and you needed to get it from going north to going south, what would be the most efficient way to do it?


There is no "required" energy to change direction, even for a zero-radius change, think of a bouncing ball:

https://www.youtube.com/watch?v=QpuCtzdvix4


This only applies in perfectly elastic systems, where the bodies can convert kinetic energy to potential energy and back with perfect restitution. Which, thanks to the second law of thermodynamics, doesn't exist in reality. It's only a question of how much energy is lost. (Unless, of course, you include the medium into which the energy dissipates as heat into the system itself. But such a model is not useful in almost all practical scenarios.)


A bouncing ball is elastic. There is some loss in the process of storing the energy from the movement into the ball and then releasing it into the opposite direction. Good example though!


> Turning around a track definitely dissipates some heat energy through increased friction with the rails.

No it doesn't, but we're talking about identical spherical frictionless trains in a vacuum.


You are also talking about a track with infinite mass because otherwise the reason train can change direction is because it's pushing the track northwards


Obviously! It goes without saying that the track must be infinitely massive and infinitely stiff, mounted on an entirely inflexible infinite plane.

See, now you're talking real physics!


I like natural keys... if you can prove that they're actually immutable and unique for the thing they're representing. Credit card number is a decent natural key for a table of payment instruments, not for users. Even for a natural-key-believer, users pretty much always need a synthetic ID, because anything you might possibly believe to be constant about humans turns out not to be.


And what if you need to be able to refer to those instruments, e.g. check or use them, but at the same time not expose credit card number to whatever entity needs to do the check?

How do you store the payment instrument for a certain purchase?


Bill text: https://legiscan.com/CA/text/AB1043/id/3193837

This seems... not terrible? The typical counter-argument to any "think of the children!" hand-wringing is that parents should instead install parental controls or generally monitor what their own kids are up to. Having a standardized way to actually do that, without getting into the weirdness of third-party content controls (which are themselves a privacy/security nightmare), is not an awful idea. It's also limited to installed applications, so doesn't break the web.

This is basically just going to require all smartphones to have a "don't let this device download rated-M apps" mode. There's no actual data being provided - and the bill explicitly says so; it just wants a box to enter a birth date or age, not link it to an actual ID. I'm not clear on how you stop the kid from just flipping the switch back to the other mode; maybe the big manufacturers would have a lock such that changing the user's birthdate when they're a minor requires approval from a parent's linked account?

That said, on things like this I'm never certain whether to consider it a win that a reasonable step was taken instead of an extreme step, or to be worried that it's the first toe in the door that will lead to insanity.


The language suggests to me that GitHub would be a covered app store and a FOSS Linux distribution without an age gate API would be illegal in California (along with all programs that don't check the age API, e.g. `grep`), so it seems quite a bit worse in terms of killing free speech and culture than requiring adult sites to check id to me.

Notably, a "covered app store" doesn't seem to need to be... a store. Any website or application that allows users to download software is covered. There's no exemption for non-commercial activity. So every FOSS repo and programs like apt are covered? The requirement is also that developers will request the signal. No scoping to developers that have a reason to care? So vim is covered? Sort? Uniq?

Honestly I can't believe big tech would go along with it. Most of their infrastructure seems like it would clearly be illegal under this bill. Either there's something extremely obvious I'm missing or every lawyer looking at this bill is completely asleep at the wheel.


I hadn't thought about GitHub -I'm guessing the authors of the bill didn't either - but you're right, that is somewhat concerning. Still, I don't think it's the end of the world...

> The requirement is also that developers will request the signal. No scoping to developers that have a reason to care?

I don't see that requirement. Here's the sum total of the developer's responsibilities (emphasis added):

> A developer with actual knowledge that a user is a child via receipt of a signal regarding a user’s age shall, to the extent technically feasible, provide readily available features for parents to support a child user with respect to the child user’s use of the service and as appropriate given the risks that arise from use of the application, including features to do all of the following:

> (A) Help manage which accounts are affirmatively linked to the user under 18 years of age.

> (B) Manage the delivery of age-appropriate content.

> (C) Limit the amount of time that the user who is 18 years of age spends daily on application.

It would be nice if it had specific carve outs for things that aren't expected to interact with this system, but it seems like they're leaving it up to court judgment instead, with just enough wiggle room in the phrasing to make that possible.

If your application doesn't have a concept of "accounts", then A is obviously moot. If you don't deliver age-inappropriate content, then B is moot. The only thing that can matter is C, but I'd expect that (a) nobody is going to complain about the amount of time their kids are spending on Vim and (b) the OS would just provide that control at a higher level.


You missed these requirements for developers

> (b) (1) A developer shall request a signal with respect to a particular user from an operating system provider or a covered application store when the application is downloaded and launched.

> (b) If an application last updated with updates on or after January 1, 2026, was downloaded to a device before January 1, 2027, and the developer has not requested a signal with respect to the user of the device on which the application was downloaded, the developer shall request a signal from a covered application store with respect to that user before July 1, 2027.

Application developers are required to request an age signal from the operating system.

> (c) “Application” means a software application that may be run or directed by a user on a computer, a mobile device, or any other general purpose computing device that can access a covered application store or download an application.

So applications are any program that runs on any computer with the capability to install software from an online source. Ergo, a program like `sort` must request an age signal when it runs.

The bill is clearly thinking in terms of the two big phone monopolists while ignoring computers that are meant to act as useful tools (which contain thousands of programs from tens of thousands of authors and which have no business caring about what "store" they came from or what date they were installed on or anything about the user running them), but it explicitly says it applies to general purpose computers.

A massive improvement would be to say this only applies when there is an actual commercial store involved, and only place requirements on developers to do something if they would have some other requirement they need to comply with. And also realize that lots of applications are not meant to have the user there the whole time. How are batch jobs or interpreters like `python ` that you might leave running overnight on a job supposed to deal with the time limit? This bill is entirely focused on toys at the expense of computers. It should just place requirements on the actual companies that are causing the issues (social media/adtech, porn, gambling games, etc.)

Your store doesn't distribute social media apps, gambling, porn, etc. and just has things like text editors, music players, PDF readers, etc? No requirements should be needed. You develop a workout tracker? No requirement should be needed.


This is what worries me a bit, that this will be used as an excuse for walled gardens and so forth.

"We can't allow side loading because that would be illegal in terms of age verification".

I would love to be wrong about this though.


It's always possible that they'll say it, but it would be a lie based on my reading of this bill. Sideloaded apps can choose whether or not to respect the OS's advice about the age of the user, it's not on the OS or device to enforce them being honest.


It's beyond obvious that it will, and it's why Google and Apple support it


Article says apple hasnt said anything about it yet, neither for nor against


Yeah... I'm far from an expert on state-of-the-art ML, but it feels like a new embedding would invalidate any of the layers you keep. Taking off a late layer makes sense to me, like in cases where you want to use an LLM with a different kind of output head for scoring or something like that, because the basic "understanding" layers are still happening in the same numerical space - they're still producing the same "concepts", that are just used in a different way, like applying a different algorithm to the same data structure. But if you have a brand new embedding, then you're taking the bottom layer off. Everything else is based on those dimensions. I suppose it's possible that this "just works", in that there's enough language-agnostic structure in the intermediate layers that the model can sort of self-heal over the initial embeddings... but that intuitively seems kind of incredible to me. A transformation over vectors from a completely different basis space feels vanishingly unlikely to do anything useful. And doubly so given that we're talking about a low-resource language, which might be more likely to have unusual grammatical or linguistic quirks which self-attention may not know how to handle.


It's much weirder now.

The current holder of that domain is using it to host a single page that pushes anti-vax nonsense under the guise of fighting censorship... but also links to the actual PuTTY site. Very weird mix of maybe-well-meaning and nonsense.


The guy behind that page and bitvise appears to have gone totally crazy during the pandemic. On his blog, he said in 2021 "I forecast that 2/3 of those who accept Covid vaccines are going to die by January 1, 2025."

And in 2022, he wrote "Covid-19 is mostly snake venom added to drinking water in selected locations. There may also be a virus, but the main vehicle of hospitalizations is boatloads of powder, mixed in during 'water treatment.' Remdesivir, the main treatment for Covid, is injected snake venom. mRNA vaccines hijack your body to make more snake venom."


> mixed in during 'water treatment.' Remdesivir, the main treatment for Covid, is injected snake venom. mRNA vaccines hijack your body to make more snake ven

Whaaaaat the fuuuuuuck

Can anyone debug this statement?? I’m not looped into weird this realm of paranoid delusion torecognizs what they’re referring to here.


There's no sense debugging the output when the hardware that produced it is clearly defective.


> MCP promises to standardize AI-tool interactions as the “USB-C for AI.”

Ironically, it's achieved this - but that's an indictment of USB-C, not an accomplishment of MCP. Just like USB-C, MCP is a nigh-universal connector with very poorly enforced standards for what actually goes across it. MCP's inconsistent JSON parsing and lack of protocol standardization is closely analogous to USB-C's proliferation of cable types (https://en.wikipedia.org/wiki/USB-C#Cable_types); the superficial interoperability is a very leaky abstraction over a much more complicated reality, which IMO is worse than just having explicitly different APIs/protocols.


I'd like to add that the culmination of USB-C failure was Apple's removal of USB-A ports from the latest M4 Mac mini, where an identical port on the exact same device, now has vastly different capabilities, opaque to the final user of the system months past the initial hype on the release date.

Previously, you could reasonably expect a USB-C on a desktop/laptop of an Apple Silicon device, to be USB4 40Gbps Thunderbolt, capable of anything and everything you may want to use it for.

Now, some of them are USB3 10Gbps. Which ones? Gotta look at the specs or tiny icons, I guess?

Apple could have chosen to have the self-documenting USB-A ports to signify the 10Gbps limitation of some of these ports (conveniently, USB-A is limited to exactly 10Gbps, making it perfect for the use-case of having a few extra "low-speed" ports at very little manufacturing cost), but instead, they've decided to further dilute the USB-C brand. Pure innovation!

With the end user likely still having to use a USB-C to USB-A adapters anyways, because the majority of thumb drives, keyboards and mice, still require a USB-A port — even the USB-C ones that use USB-C on the kb/mice itself. (But, of course, that's all irrelevant because you can always spend 2x+ as much for a USB-C version of any of these devices, and the fact that the USB-C variants are less common or inferior to USB-A, is of course irrelevant when hype and fanaticism are more important than utility and usability.)


As far as I know, please correct me if I'm wrong, the USB spec does not allow USB-C to C cables at all. The host side must always be type A. This avoids issues like your cellphone power supplying not just your headphones but also your laptop.


No, you're thinking about USB-A to USB-A, which is definitely prohibited by the spec. (Whereas USB-C to USB-C cables are most certainly not disallowed.)

What's disallowed is for a non-host to have USB-A, hence, USB-A to USB-A is impossible, because one side of the cable has to be connected to a "device" that's not acting in host mode.

Only the host is allowed to have USB-A.

This is exactly why USB-A is superior to USB-C for host-only ports on embedded devices like routers (as well as auxiliary USB ports on your desktop or monitor).

Generally, many modern travel routers have one USB-C and one USB-A port. Without any documentation or pictograms, you can be relatively sure that USB-A would be used for data, and USB-C is for power (hopefully, through USB-PD). Since USB-A couldn't possibly be used to power up the router, since USB-A is a host-only port.

USB-C is great for USB-OTG and the bidirectional modes, when the same port could be used for both the host and the peripheral device functions, like on the smartphones. https://en.wikipedia.org/wiki/USB_On-The-Go

If the port can ONLY be used in host-mode, and does NOT support Alt Mode, Thunderbolt, or bidirectional USB-PD, then USB-A is a far more fitting connector, to signify all of the above.


Yeah, I loughed out loud when I read that line. Mission accomplished, I guess?


Uptime and reliability are not the same thing. Designing a bridge doesn't require that the engineer be working 99.9% of minutes in a day, but it does require that they be right in 99.9% of the decisions they make.


Another way to think about it is that, if the engineer isn't right in 99.9% of decision, the bridge will have 99.9% uptime.


That's pretty bad for a bridge haha


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: