The college wage premium, that is, the increased earnings associated with having a college degree as opposed to only being a high school graduate, hasn’t changed at all in the past 25 years, because median real wages have been flat as a pancake for everybody, no matter what their formal education level, for the past quarter century.
I wonder what’s happened to capital over this time? Value of S & P 500, inflation-adjusted, 1/2000 to 9/2025 (same period as the wage data):
2000: $1,394
2025: $6,688
On average, for more than the students' entire lives, stock-owners like Schmidt and (to a much lesser extent) I have stolen every last drop of the productivity increase of US workers at every age and education level. (See the actual numbers in the appendix)
Now, the perpetrators of this theft are telling their victims, the students and the public at large, that whether they like it or not they will be subjected to AI because that will make the perpetrators even richer. The victims have been informed that this new technology will:
Nothing better illustrates the contempt of the Epstein class for the proletariat than that these oligarchs would expect the graduating class to enthusiastically accept this prospect.
I was fooling around with FRED this morning, as one does, and here are some stats: (The FRED numbers are presented in nominal dollars; I’ve converted them to CPI-adjusted dollars).
Median usual weekly earnings of workers with a high school degree only:
2000: $968
2025: $980
Median usual weekly earnings of workers with a bachelor degree only:
2000: $1,587
2025: $1,580
...
Median usual weekly earnings of people with a bachelor’s degree or higher:
2000: $1,705
2025: $1,747
Here is a short list of YouTube videos on this topic:
As a boomer, I think this post might be the exception that proves Ms. Baba's rule.
Note that every single one of the ads that I saw watching these videos in an incognito window was advertising an AI company! As are 49% of all the billboards in the Bay Area. Read the room, guys!
In Why Does Everyone Hate AI?, Paul Krugman reinforces my point with actual data: He starts where I did:
Eric Schmidt, the ex-CEO of Google, recently gave a commencement speech in which he heralded the coming of AI — and was loudly booed by the students. This was not an outlier. There have been a number of similar incidents lately, evidence that many people now really hate AI.
Are we talking about a vocal but unrepresentative minority? No. A recent Pew survey found that American adults believe by a wide margin that AI will be negative for society and, by a smaller margin, that it will be bad for them personally:
Krugman goes on to pose a number of reasons for this PR fiasco.
First because:
we fear that AI will do terrible things because the companies selling it told us it would do terrible things. Last year, for example, Anthropic CEO Darius Amodei declared in an interview with Axios that AI could wipe out half of entry-level white-collar jobs and drive overall unemployment as high as 20 percent within 1 to 5 years.
He points out that these negative views were not present at the advent of the Internet nor at the rise of social media.
many ordinary people view AI negatively because they feel that it is being forced on them.
It’s true that many people are voluntarily using large language models for personal convenience or as a business productivity tool. But a significant part of AI use isn’t voluntary. This Wall Street Journal headline from February says it all:
Why are companies doing this? Presumably they believe that AI will raise productivity. But just as importantly, they’re responding to pressure from financial markets, which are rewarding companies for quickly adopting AI, apparently without regard to demonstrated results.
And while Americans workers are being dragooned into using AI, American consumers are being force-fed AI whether they want it or not. Most dramatically, Google has replaced its search engine with AI, without offering the option to opt out. One has to turn to obscure workarounds or third-party sites to get traditional search results.
So many people feel, rightly, that they aren’t being allowed to choose whether to use AI — not using AI has become hard both as a worker and as a consumer.
datacenters are a highly visible reminder of AI’s costs. Datacenters occupy huge tracts of land — one proposed site in Utah will be twice the size of Manhattan. They guzzle electricity and water. When they generate some of their own power, they create major local pollution. Not surprisingly, there is intense opposition to datacenter construction. According to a Reuters Ipsos poll, 57 percent of Americans — two-thirds of Democrats and half of Republicans — would oppose a datacenter in their neighborhood. Only 14 percent would support one.
A massive data center project in Box Elder County, Utah, helped bring down the state’s Senate president, who lost his GOP primary on Tuesday after his support for the controversial development fueled voter backlash.
Stuart Adams, one of Utah’s most powerful politicians and the longest-serving president of the state Senate in its history, lost to challenger Stephanie Hollist, a former university lawyer and vocal opponent of the data center.
Hollist accused Adams, as well as the state’s broader political establishment, of ignoring public concerns about a Stratos data center project that critics feared could cause serious environmental harms.
...
Box Elder County Commissioners Boyd Bingham and Lee Perry, who voted in favor of allowing the plans to continue, also lost their primary elections.
even before the advent of AI, tech companies had lost the public’s trust. Over the years Pew has regularly surveyed the public for its views on technology companies, asking whether they have a positive or a negative effect “on the way things are going.” In 2015 public opinion of tech companies was overwhelmingly positive. By 2022, the year ChatGPT was released, that goodwill had evaporated.
Why have Americans turned on tech companies? While it surely reflects growing awareness of the psychological and societal harm done by social media, much of it also reflects the enshittification of tech products.
AI is tightly linked in the public mind with the tech oligarchs who are pushing it. There is widespread awareness of the growing concentration of wealth and power at the top and how this is distorting our politics and harming our society. Aside from the MAGA faithful, Americans overwhelmingly favor government policies to reduce wealth inequality:
And AI is widely perceived, for good reason, as a technology that will increase the concentration of wealth at the top. Indeed, as I said, the AI companies themselves have already told us that the technology will have extremely negative effects on workers.
There’s a strong element of poetic justice in this turn of events. The AI industry deliberately made itself look menacing as a financial strategy, believing that the markets would reward the appearance of being “edgy.” In so doing, however, tech made itself highly unpopular. And even in an era in which money all too often buys power, public opinion matters.
I was going to write and publish this post earlier, but the last couple of weeks have been trying to enjoy (the rest of) my vacation and submitting job applications. It’s also been a bit weird. I’ve never worked anywhere else longer than 2 years (mostly because of the jobs being contracts), so it’s sad … Continue reading "Reflection: The end of 8 years at GitLab"
On June 23, 2026, we held our sixth annual WS-DL Research Expo. We continued the same format as the prior years (2025, 2024, 2023, 2022 & 2021), with one student from each WS-DL professor giving a short overview of their research. Links to all the materials (slides, papers, software, data) are gathered in the GitHub repo, but repeated here are the links for the students and their presentations:
News is, with few exceptions, place-based. “Where” is one of the journalist’s first questions, and without it, news feels groundless, baseless, unmoored. But news used to not only be written from a specific place, but also written for the people living in that specific place. In that sense, all news used to be local. But whether the news reported on immediate surroundings, the colony or state, the nation or empire, the function of newspapers was to provide a public record, both for audiences at the time, and for future readers. In fact, many editors were conscious of this function of the newspaper as a repository; some two hundred years ago, they provided, in the words of Hezekiah Niles in his prospectus for Baltimore’s Weekly Register, “something interesting at the present moment, and as a book of reference, a fund of reading always at hand, a work of much probable value” (September 7, 1811).* Newspapers were, from their earliest days, understood as a public good, as “work[s] of much probable value.”
Information has been mobile from its early days — from the troubadour to the telegraph, one might say — but because “news” is the sum of information plus time, or timeliness to be more exact, the accelerated speed of transmission is vital to the rise of news for national and international audiences. Most scholars agree that syndicated news really took hold after the Civil War with Chicago’s A.N. Kellogg Newspaper Company. As with our own moment’s undervaluing of local news, the transition away from “local” newspaper-reading audiences did not happen overnight and cannot be attributed to a single factor. Infrastructure, — in the nineteenth century, the railroads and stereotype printing; today, the internet and social media — combined with sociocultural shifts, makes the world feel smaller.
We are gathered here today to celebrate and to concern ourselves with news that does not move, that stays more or less in the place from which it came. It is, as Lincoln would say, “altogether fitting and proper that we should do this,” for reasons beyond the present moment. As an historian, I have been tasked with adjusting our gaze ever so slightly from the “now” to the “back then.” I’d like to draw out a few examples of the importance of local news in historical research in the hopes of showing, rather than telling, not only that historical local news matters, but also that we must retain its understanding of itself as a public good. Without this printed record, it is easy to forget that it is not just people who have history, but places too. Without the context of place, history too feels groundless, baseless, and unmoored. I fear that the history we are creating today might not even exist in a century from now, but I will say more about that later.
When we think of historical newspapers, we often think of the people whose lives they capture, and perhaps even the lives of the people who produced them. We might even think of the stories they omit, of the people not represented in these wilted and worn pages. More recently, environmental history has helped us to see historical newspapers as the place to uncover the histories of the land, as the sources that will shed light on the social and cultural causes of global warming and environmental degradation. The research and storytelling in the work of scholars and journalists alike are changing how we think of newspapers and the vital role they play in understanding the histories, and in turn, the futures of our environment. Corporate archives often do more to conceal than to reveal, if one can gain access to them at all. Government records can be little better. But, local newspapers contain the stories written by the local intrepid reporter who cites evidence of a paper mill’s destruction of the river running through the town. Similarly, where official records might have denied harmful contamination from Superfund sites, a historian can scan obituaries for evidence of untimely deaths from cancer clusters. We need local newspapers to read against official narratives told of the land, as well as of the people who inhabit it.
Inaugural issue of the Navajo Times, November 1, 1959. Source: Library of Congress.
Think, for example, of the hyperlocal newspapers published on reservations, such as the first newspaper published in the Navajo language in Window Rock, Arizona. The Navajo Times’s purpose, as stated in its inaugural issue in 1959, was “to serve the 6,000 Navajo children who are attending off-reservation schools. It is hoped that this newspaper will keep them informed about what is happening on their reservation. It is also hoped that this is a step toward supplying the Navajo people with an ever-increasing flow of information.” This paper then was to keep the local — the power of place — in the hearts and minds of its intended audience, no matter where they went, or were forced to go. This statement of purpose from the Navajo Times is a gentle reminder that people are, in part, defined by place, and the stories they told of “the local” have much to teach us today.
Aggregation of Historical Local News, a National Prerogative
As a researcher, I have been privileged to be a consumer of local news, and as a former senior program officer at the National Endowment for the Humanities (NEH), I was also a producer, managing the National Digital Newspaper Program (NDNP), the NEH program that funds and co-creates Chronicling America. Chronicling America does and does not serve the preservation of local news. As of my most recent check, it includes 4,684 newspaper titles and over 3 million issues, dating from 1736 to 1963. These titles certainly include a handful of “local newspapers,” no matter how that category is defined. And yet, this was not the intention of NDNP. In fact, for about the first 15 years of its existence, NDNP inadvertently discouraged the preservation of “local” newspapers by encouraging applicants to begin with papers of record, with those that had long runs, and most likely, were published in big cities intended for large audiences. Because so many of the states have by now contributed these “major” papers, the program shifted, in 2021, to newspapers that tell underrepresented histories. Until recently, applicants were welcome to define “underrepresented” in any way they chose, and they often chose place-based representation (see the 2024 Notice of Funding Opportunity (NOFO); “underrepresented” has been expunged from the 2025 NOFO). More and more newspapers from neglected areas were being included in Chronicling America. Without empirical evidence to back me up, I would venture that there has been a rise in “local” if not “smaller” newspapers in Chronicling America in recent years.
And yet, the resource will always fall short, for it cannot provide all that we are looking for. Those who designed it, back in the early 2000s, knew this. They knew that the 1963 cutoff date for inclusion would exclude many important papers, and they knew that many state partners were able to digitize far more newspapers than could be included in the national aggregator. And so, the genius of NDNP is not only what you find in Chronicling America, but also in the way that it established standards for newspaper digitization. Its hope was that Chronicling America would be just one of the manifestations of the work it enabled; states would also become aggregators of their newspapers, using the same standards. And they have done so, creating amazing state-level digital newspaper repositories, such as Georgia’s Historical Newspapers or the Texas Digital Newspaper Program, just to name a few. Such state-level efforts were encouraged to reuse content digitized for Chronicling America, as well as to include that which did not make it to the national aggregation level. CONSERV cataloging and the technical guidelines for digitization demonstrate that standardization must be part of the work of preservation; otherwise, the “local” risks being relegated to the dustbin of history. If we believe that “local” does not mean “less than,” then we must use the same standards for categorizing and making accessible local newspapers that we do for the so-called “papers of record.”
Local News as Public Data
The term “dark ages” has grown out of fashion for historians because it suggests that no light existed in the period from 500 to 1000 CE. Painstaking scholarship has slowly uncovered that this is not the case, that in fact people were innovating, creating, and exploring in ways not all that different from classical antiquity before it and the Renaissance afterwards. And, yet, the label “dark ages” resonates today, not because our current moment is failing to produce meaningful and innovative work, but because of the great difficulty the future will face in tracing the lives and outputs of the people of our moment. As Jonathan Zittrain has pointed out, the internet, which for better or worse houses much of our current culture’s memory and creativity, is “rotting.” Technologies that once signaled a great unfurling of access to information are now showing cracks and vulnerabilities when considered at a historical scale. The historical record of the current moment will be, in many ways, “dark.” We are in what might be referred to as the “digital dark ages,” not because important things are not happening, but rather because the future’s light on this moment is diminished, if not snuffed out completely.
We have been asked this morning to address what “getting local news preservation right” would require, and my response is that we must provide multiple ways to shine light on our current moment. Data is the new oil, or so we’ve been told for the last two decades, and I roll my eyes at this metaphor not because it is not true, but because data is so much more than a market commodity. Local news, in its many forms and instantiations, is public data, and we must preserve it because it has an inherent value that surpasses our current moment, that is so much more than its commodification. Because we cannot see the future, we cannot know all of these values, but based on our reliance on historical “local” newspapers to know the past, we can trust that they exist.
For the most part, libraries exist outside of the naked self-interest of capitalism, and the people who work in them must play a role in the preservation of local news. Librarians are the original public interest technologists, we might say, and I urge us to put them at the forefront of our conversations here. Journalists too exist in a space not completely captured by market forces, and they too want information to be free and to be accessible. I see an alchemy emerging from the alliance between these two professions that offers future generations not only a historical record of their communities from which they can analyze and learn, but also a model for forms of affinity and alignment that exceed capitalist logics and exemplify other modes of cooperative work. This gathering is an important step in this effort, and I am honored to be a part of it.
* Thank you to my friend and collaborator Will Slauter for providing this example and for his assistance with these remarks throughout.
In the hours following the release of CVE-2026-8461 for the project FFmpeg, site reliability workers
and systems administrators scrambled to desperately rebuild and patch all their systems to fix an out-of-bounds write in the MagicYUV decoder (libavcodec/magicyuv.c) caused by improper bounds checking, resulting in heap corruption, denial of service, and potential remote code execution when processing a specially crafted video file. This is due to the affected components being
written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes
these things just happen and there's nothing anyone can do to stop them," said programmer Mrs. Kitty Smitham, echoing statements
expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have
occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can
we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to
write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities
regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."
We discussed with our Nordic members and friends how, across Europe and beyond, policymakers are rethinking the foundations of the digital state and the infrastructure that powers it.
We’ve scattered a shower of rainbows around the site, and it’s up to you to try and find them all.
Decipher the clues and visit the corresponding LibraryThing pages to find a rainbow. Each clue points to a specific page right here on LibraryThing. Remember, they are not necessarily work pages!
If there’s a rainbow on a page, you’ll see a banner at the top of the page.
You have just under one week to find all the rainbows (until 11:59pm EDT, Tuesday June 30th).
Come brag about your shower of rainbows (and get hints) on Talk.
Win prizes:
Any member who finds at least two rainbows will be awarded a rainbow badge. Badge ().
Members who find all 11 rainbows will be entered into a drawing for one of five sets of LibraryThing (or TinyCat) swag. We’ll announce winners at the end of the hunt.
P.S. Thanks to conceptDawg for the kookaburra illustration. ConceptDawg has made all of our treasure hunt graphics in the last couple of years. We like them, and hope you do, too!
In the hours following the release of CVE-2026-55200 for the project libssh2, site reliability workers
and systems administrators scrambled to desperately rebuild and patch all their systems to fix an out-of-bounds write in ssh2_transport_read() due to a missing upper bound check on the packet_length field, resulting in heap corruption and potential remote code execution. This is due to the affected components being
written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes
these things just happen and there's nothing anyone can do to stop them," said programmer Mr. Alex Doyle, echoing statements
expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have
occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can
we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to
write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities
regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."
A year ago in The Back Of The AI Envelope I pointed out that the AI platforms were running the drug-dealer's algorithm, "the first one's free". By massively subsidizing the use of their products, they were generating overwhelming demand for them. They used this demand to justify massive investments, in the hope that, by the time they had to show a return on these invetment, the users would be so addicted that they would pay the vastly higher prices needed to generate a return.
I have to confess that I was late to the party. The earliest skepticism I've been able to find was from Sequoia Capital's David Cahn in September 2023, entitled AI’s $200B Question. Only nine months later Cahn re-ran the same analysis in AI’s $600B Question. His estimate of the revenue gap had tripled. Cahn wasn't alone. Independent journalists such as Ed Zitron were flagging this problem long before I was.
I started to write this post a couple of months ago when the maiinstream business press began to notice companies complaining about the cost of the tokens their employees were burning. Since then the trickle has turned into a flood, which made finishing the post hard. Below the fold I throw up my hands and dump out a small sample from the flood.
One difficulty has been that estimates of the size of the subsidy have varied widely, typically in the range of costing the platforms $8 to $14 to generate $1 in revenue. Two recent posts from Ed Zitron have illuminated this issue.
SemiAnalysis, an extremely pro-AI semiconductor analyst, ran a test made up of random long-horizon coding tasks until they maxed out the limit on OpenAI and Anthropic’s various subscription levels.
Their findings were shocking.
For $200 A Month, You Can Burn $8000 in Anthropic Tokens or $14,000 In OpenAI Tokens
That’s right. Anyone with a $200-a-month Anthropic subscription can burn $8000 in tokens, and with a $200-a-month ChatGPT subscription, you can burn $14,000 in tokens.
Zitron's numbers don't tell us the real cost of generating tokens but, subject to the assumption that the platforms are not subsidizing the token price, that means Anthropic is subsidizing their enterprise customers by up to 40 times, and OpenAI up to 70 times. No wonder they are seeing massive demand! But, despite OpenAI's subsidy being 175% of Anthropic's, OpenAI's adoption by businesses has recently been flat while Anthropic's has soared.
SemiAnalysis also analyzed the platform's gross margins, implausibly assuming that tokens were priced at 4 times the cost of generating them and:
With the current subsidies, all it takes for a user to have a gross margin of at best negative 25% is for them to use as little as 25% of their rate limit.
Naturally, subsidizing your sales like this means you are feeding cash into the furnace. We have seen OpenAI and Anthropic raising vast sums in equity, but because they both have been private companies we haven't seen the details of their spending or revenue. On June 15th this changed when Zitron saw OpenAI's 20025 financials and posted OpenAI Losses Increased Nearly 8X in 2025, With Spending Hitting $34 Billion, revealing that:
OpenAI Had $13.07 Billion In Revenue, $34 Billion In Costs and Expenses, and $20.92 Billion In Losses, with a net loss attributable to the company of $38.53 Billion
2025 was the year that OpenAI converted from a non-profit to a for-profit entity, leading to a $41.55 billion loss due to changes in fair value of convertible interests and warrant liability.
...
Ultimately, the net loss attributable to OpenAI in 2025 was $38.5 billion.
At the end of the year, OpenAI had just over $50 billion in assets, with almost half of that in cash.
Perhaps the most striking of their truly awful numbers were:
Revenue: $13.07 billion
...
Sales and Marketing: $5.73 billion
That is, OpenAI spent 44% of their revenue on sales and marketing! The hype needed to keep the AI bubble inflated is incredibly expensive. Despite this lavish spending, business adoption has been flat.
US equity markets are facing three IPOs of AI companies, SpaceX, Anthropic and OpenAI, each led by a world-class bullshitter, each losing tens of billions fo dollars a quarter, and all but SpaceX touting overwhelming demand for their products[1]. But, after they go public, they will need to charge enough to generate a return on their enormous capital investments. Ideally, they would have postponed the necessary swingeing price increases until the IPO money is in the bank.
Leaked internal documents viewed by Where’s Your Ed At reveal that Microsoft intends to pause new signups for the student and paid individual tiers of AI coding product GitHub Copilot, tighter rate limits, and eventually move users to “token-based billing,” charging them based on what the actual cost of their token burn really is.
The document says that although token-based billing has been a top priority for Microsoft, it became more urgent in recent months, with the week-over-week cost of running GitHub Copilot nearly doubling since January.
The move to token-based billing will see GitHub users charged based on their usage of the platform, and how many tokens their prompts consume — and thus, how much compute they use.
Anthropic, OpenAI and Microsoft have all now transitioned customers from subscriptions to token-based pricing. For serious users, this is eye-wateringly expensive. Jamie John, Rafe Rosner-Uddin and Ryan McMorrow's ‘We created a monster’: companies rein in AI usage as costs strain budgets quotes a small company's CEO:
But the company got a shock when Anthropic switched it over to token-based pricing in May. “Our spend went up 7x the first day and I’m like, oh shit, we created a monster,” said Busse. “[Large language model] companies have been subsidising all of our usage and now no longer. User-based pricing shelters you.”
Bryan Catanzaro, Nvidia's VP of applied deep learning, recently told Axios that "For my team, the cost of compute is far beyond the costs of the employees", quite an interesting statement from the company selling the shovels for the gold rush.
That perspective is shared by Uber's CTO Praveen Naga, who "[went] back to the drawing board because the budget [he] thought [he] would need is blown away already" as of two weeks ago. Likewise, Swan AI's Amos Bar-Joseph posted a while back on LinkedIn about how proud he was about a $113k bill from Anthropic (makers of Claude) for a four-person team.
Oversimplified math pins that amount that at $28k per person per month, which is likely more than each person's monthly wages. Jokes abound right now that "companies have discovered jobs again," and the humor is backed up by a 2024 MIT study stating that 77% of the time, it was preferable to have humans do the work.
Source
The reason is for the premature and impending price rises is that justifying the massive investment in building data centers, about 60% of which goes into rapidly depreciating hardware, requires implausibly astronomical revenues. Thierry Borgeat notes that:
In The AI Industry Is Panicking, Will Lockett estimates that over the next few years the AI platforms will accumulate around $3T in debt. Assuming this is at 3% over 10 years, servicing the debt will take $309B/year:
This means that for the AI industry to service its debt, it needs to generate hundreds of billions of dollars in profit each year.
Even giant monopolies like Google don’t make enough profit to service that much debt. AI can’t just be a novelty industry; it needs to replace human labour on a colossal scale to service this debt. Let’s optimistically assume AI one day reaches a 10% profitability margin, a cost parity with human labour, and the ability to complete most jobs (none of which are currently the case). Well, the average US salary is roughly $66,000, so at a 10% profit, the AI company will make on average $6,600 per year per job it replaces. To generate the $309 billion needed to service their debt, the AI industry will need to replace 46.8 million jobs, equivalent to around 27% of the current number of jobs in the US.
While this is all very rough maths, it highlights the implicit bet created by the debt the AI industry has racked up. To simply not default on this debt, the AI industry has to rapidly displace human labour at a staggering scale, even if we are extremely optimistic about AI’s economics.
One caveat with Lockett's math is that the cost of employing a human is greater than just the salary. It includes the employer's Social Security tax, health insurance, office space and so on. Chatbots don't need any of these. According to the Bureau of Labor Statistics:
Wages and salaries averaged $32.60 per hour worked and accounted for 69.9 percent of employer costs, while benefit costs averaged $14.01 per hour worked and accounted for the remaining 30.1 percent.
So the average profit per job would be around $9.5K, and the number of jobs displaced would be around 32.5KM.
How was the switch to token-based pricing received? We can guess from three pieces of recent news:
Last month, Anthropic announced a billing change that would have substantially increased costs for heavy users of its automation-focused Claude Agent SDK, including many third-party apps. On Monday, though, Anthropic abruptly announced it had paused those pricing changes just as they were set to take effect, allowing Agent SDK users to continue drawing from the more generous usage limits in their existing Claude subscriptions.
Microsoft is reportedly cancelling most Claude Code access for engineers in its Experiences and Devices division by June 30, 2026, shifting teams working on Windows, Microsoft 365, Outlook, Teams, and Surface toward GitHub Copilot CLI as the company tries to rein in internal AI coding costs. The decision is more than a procurement tweak. It is a rare glimpse into what happens when the world’s most aggressive AI software company runs into the same metered-billing problem now facing every large engineering organization.
Historically, companies wishing to IPO would be profitable. More recently they could have a successful IPO by showing a plausible path to profitability. Now, SpaceX has shown that even massive losses and a claimed path to profitability that is completely implausible is not a barrier to a successful IPO. But even despite this example, one would think that the last thing two companies racing to IPO despite massive losses and implausible paths to profitability would want would be to engage in a "drastic" price war.
Footnotes
xAI's product is so bad that even their employees won't use it and Musk has said it needs to be re-written from the ground up. So xAI has been reduced to renting its compute infrastructure to its competitors.
Registration is now open for the virtual Digital Library Federation’s (DLF) Forum online, October 14-15, 2026. The DLF Forum is a dynamic gathering place for GLAM professionals to share ideas, sustain critical work, and spark innovation. It connects library, archives, and museum practitioners, as well as other knowledge workers, through intentional community building and collaborative exchange. Learn more about
Be sure to check out the exciting details and join us in building momentum for what’s sure to be an inspiring experience.
Secure the early bird rate and start planning for yet another memorable online conference with DLF.
DLF member organizations receive two complimentary registrations for the virtual DLF Forum as part of their member benefits. Not sure who received your code? Email us at forum@diglib.org.
Applications are now open for the 2026 Virtual DLF Forum Digital Storytelling Fellows program
This year, DLF is launching a new fellowship experience that is directly connected to the Forum’s new Digital Storytelling Presentation session format. The program centers on digital storytelling, emerging technologies, and ethical practice across libraries, archives, and museums, while creating intentional opportunities for participation, reflection, and community engagement in a virtual setting.
We invite early-career and underrepresented practitioners to participate in the 2026 Virtual DLF Forum and help shape conversations about how stories, platforms, technologies, and communities intersect in our work.
Why Digital Storytelling?
Digital storytelling projects, including exhibits, platforms, collections, and collaborative archives, are increasingly central to how cultural heritage organizations document, interpret, and share knowledge. These projects also raise important questions about representation, labor, technology, access, and stewardship.
A cohort of 8–10 Fellows will engage directly with these themes through participation in DLF’s new Digital Storytelling Presentation sessions: interactive, installation-inspired presentations featuring collaboratively developed digital projects and dedicated discussion time. Because this is a new and experimental session type for 2026, the fellowship intentionally builds in structured engagement and feedback to help strengthen the experience and better understand what works in a virtual Forum environment.
Fellows will serve as conversation catalysts during these sessions by contributing questions, reflections, and observations that surface broader themes across the Forum community.
About the New Session Format
40-minute Digital Storytelling Presentation An interactive session highlighting digital storytelling projects developed through collaborative partnerships. Digital Storytelling Presentations focus on installation-inspired digital storytelling work, such as exhibits, platforms, or collections, designed for immersive and experiential engagement. Sessions may feature up to three presenters, for example, pairing a digital librarian or archivist with a community partner, student, artist, or scholar whose work is represented in, or inspired by, the project. Sessions will be scheduled within 50-minute blocks, leaving dedicated time for Q&A and discussion. Read more about the new session type here: https://www.diglib.org/digital-storytelling-in-practice-a-new-session-format-for-the-dlf-forum/
What Fellows Receive
Selected Fellows will receive:
Complimentary registration to the 2026 Virtual DLF Forum
A $250 stipend
Participation in a small cohort of 8–10 Fellows
A pre-Forum virtual orientation and meet-and-greet
Visibility through publication on the DLF blog
Fellowship Expectations
Fellows will:
Participate in a virtual orientation session on October 6, 2026
Attend the 2026 Virtual DLF Forum on October 14–15, 2026
Engage actively in Digital Storytelling Presentation sessions by:
Asking questions in chat or live discussion
Optionally sharing brief verbal reflections during session discussions
Incorporating insights from storytelling sessions into their post-Forum reflection
Participate in a virtual debrief session and/or complete a feedback survey
Contribute a short public reflection for publication on diglib.org (up to 1,000 words, due November 15, 2026)
Reflections may explore themes such as ethical technology, collaborative storytelling, digital exhibits, community memory, access, or emerging questions around provenance and stewardship.
Selected Fellows must attend the Forum in order to receive the stipend. Apply here.
Who Should Apply
We welcome applications from:
Early-career professionals (fewer than 7 years of experience)
Students and recent graduates
Contingent, contract, and adjunct practitioners
Professionals working in under-resourced or capacity-limited institutions
First-time DLF Forum attendees
Practitioners whose identities and perspectives are historically underrepresented in digital libraries and cultural heritage spaces
We recognize that professional pathways are not always linear. If you are unsure whether you meet these criteria, we still encourage you to apply.
Application Process
The application process is designed to be straightforward and accessible. Applicants will:
Answer a few short questions
Submit a brief personal statement (maximum 4,000 characters)
Share a link to an online professional profile, if available
What happens if I just point a git server at an object storage bucket?
Back when I was porting
agent sandboxes to Go, I
built everything on top of
billy, a filesystem
abstraction for Go. The whole trick of the project was teaching a Tigris bucket
to act enough like a filesystem that a shell interpreter and its tools couldn’t
tell the difference. Billy was the key layer that made the entire façade fall
into place.
After I had gotten things working, I learned that I’m using billy way outside
its normal usecase. It was originally made for
go-git, a pure-Go
implementation of git’s protocols and data formats. It doesn’t rely on the
/usr/bin/git binary existing at all. Every method on billy’s filesystem
interface exists purely because go-git needs it. This gave me a terrible idea: I
already have a bucket that can quack like a filesystem and go-git’s native
language is “filesystem”.
Can this Just Work™? Let's find out.
Git was always an object store
If you strip away the porcelain, a git repository is 4 basic things:
Objects, or compressed blobs of data. Most of the objects in any individual
repository are files.
Trees, or objects that map to other objects. TL;DR: trees are folders.
Commits, or objects that point at one tree and their parent commit. This lets
you pin down which files belong to one logical change set.
Refs, branches and tags, they are tiny mutable pointers into the pile of
objects.
Note
Until I started working on this I was under the impression that git stored
only the patches done to an empty folder and that was how it reconstructed the
history of your repository. It does not. It actually keeps track of the entire
files, which explains why big binary blobs fudge the tooling so much. The diff
mental model works fine for using git day to day; it’s just wrong at the
storage layer, which is the layer this post lives in.
For example, let’s say I just made a new git repository and committed a
README.md to it. The tree for the .git folder looks something like this:
$ tree .git
.git
├── COMMIT_EDITMSG
├── config
├── HEAD
├── index
├── objects
│ ├── 5e
│ │ └── b8151eb669aa4467b6dea2c4bce19183cd0b41
│ ├── 6a
│ │ └── 6a8ecfcae2632152486aca3d9150ef83dedd66
│ ├── f4
│ │ └── d2487a1c6d742c8037c0296ddf80625190bd80
│ ├── info
│ └── pack
└── refs
├── heads
│ └── main
└── tags
As you can see there are three objects. One of them is the commit
5eb8151eb669aa4467b6dea2c4bce19183cd0b41, the next is the tree, and the last
one is the README file. The main branch also points to that commit:
The cool part is that half of this is content-addressed. The content-addressed
bits never change once they’ve been committed. Git objects are a great fit for
Tigris’ internal model because they are append-only storage, just like
the fundamental model Tigris is built upon.
The things that do change often are the refs, which are updated to point to the
latest commit. These are tiny files though, which means that Tigris can handle
them with no effort required.
However, when we host git repositories on a server, we end up creating single
points of failure. Our git repos are hosted on single machines that can and will
break. The entire implementation relies on git objects being 1:1 correlated with
filesystem objects because everyone (even GitHub) shells out to the git binary
to actually store files. Hosting git repos becomes one of the most stateful
services in our stateless cloud-native environment.
Sure git is in-theory decentralized, but most of us have ended up using that to
put our git repositories in one big store that has questionable uptime
practices: GitHub. To be fair to hubbers, GitHub operates at a scale that none
of us can really think about. They’ve been pushing the limits since their
inception where they had to get Engine Yard to keep building them bigger servers
to handle the load. They have to do everything with a big mounted filesystem
because git’s tooling gives them no other option.
A travesty of horrors beyond human comprehension
Now suppose this weirdness bothers you enough to do something about it. To build
a git server without storing everything in the local filesystem, you have to
speak git somehow, and the conventional options aren’t really all that great:
If you shell out to the git binary, now your “library” is the argv of the git
process and your error handling is screen-scraping output. Internally, git
implements its functionality with a billionty subcommands rather than exposing
it all as a library. The codebase is held together by load-bearing calls to
die(), which kills the process.
If you link into git’s guts with libgit, you inherit the “when things go
bad, die()” behaviour and your app now suddenly starts crashing at random.
This is not good for uptime.
If you try to use libgit2 (the rewrite-that’s-actually-a-library), you have
to reckon with the fact that it’s addled by the GPL (with a linking exception,
try explaining that to your lawyers), you have to eat the jump to C every time
you do anything with git (very often), development has stalled, the Go
bindings have been archived, and it still assumes a local filesystem despite
assurances it does not.
It might sound hopeless, right? You may be able to use WebAssembly or something
to contain the madness (assuming you have a good way to implement
fork()/exec() or posix_spawn() or something similar), but what if there
was a pure Go library that could handle this all for us?
Enter go-git, a pure-go
implementation of the git protocol and internals from scratch. This doesn’t rely
on cgo or /usr/bin/git and it does not assume the repositories are stored in
the local filesystem. Its storage interface is written against billy, the exact
interface I’ve already taught to speak Tigris. I wanted a git server that was
just in a bucket and the pieces were sitting there and calling to me.
Oh no, it works
So I hacked up objgit, a git server
backed by object storage. The only filesystem call I had to add to get it
booting was MkdirAll. I wired up the
transport
package to a socket to implement the plaintext git protocol, hooked it up to a
bucket, and pushed the repo I was currently working on.
To my absolute astonishment, it worked.
Git pushed, pulled, logged, blamed, tagged, the whole kit and kaboodle. I didn’t
have to implement git myself, I just committed an egregious amount of shoving a
square peg into a round hole until the peg went in.
In hindsight this makes an annoying amount of sense. A bare repo is those four
kinds of things on a filesystem; swap the filesystem for object storage and
everything else Just Working™ is perfectly logical. Git’s on-disk format is
its database schema and if you fake open/stat/rename convincingly enough the
entire façade keeps working because APIs are the lies we tell ourselves to make
us sleep at night.
After a lot of hacking, I ended up with a feature list kinda like this:
Push and pull over three transports: HTTP, classic git://, and SSH
Repositories upserted on first push
Absolutely no effort put into authentication as this is an experiment and
authentication is annoying and complicated
Prometheus metrics so I could optimize the filesystem layer
Everything comes out of one Go binary with no local state, even the generated
SSH keys are stored in the bucket. You can run this in a Kubernetes cluster with
only the mutable storage required being temporary files for an optimistic cache
when doing smart git clones.
The rest of this post is what it took to get from “oh no, it works” to something
close to usable.
Obligatory disclaimer (like the best things in life): this is an experiment. It
has not been tested thoroughly or vetted for correctness. If it breaks in half,
you get to keep both pieces. Please do not move your company’s monorepo onto
this and then email me when it catches fire.
That one POSIX idiom that survived
Git is paranoid about durability, and its entire strategy is one Unix idiom that
you end up seeing many places: write new data to a temporary file and then
rename(2) it into place after you’ve assured it’s correct. POSIX guarantees
that rename is atomic, so readers either see the old file or the new one, not an
intermediate state inbetwixt the two. Packfiles (bundles of objects) land as
temporary files when uploaded then moved to their permanent home. Refs are
written as locked temporary files and then renamed over the ref. It’s rename all
the way down.
Object storage traditionally does not have rename as one atomic operation. S3’s
answer is to create exactly that intermediate state: CopyObject to the new
place and DeleteObject on the old one. This makes the most load-bearing idiom
in Git’s philosophy fall to pieces.
Luckily, Tigris has an extension for this:
RenameObject. To use
it, pass an additional X-Tigris-Rename: true header to a CopyObject call and
instead of copying then deleting on the client, it moves the metadata around on
the server. One round trip, no data movement, and the Unix idiom maps on the
bucket 1:1. Objgit’s implementation of Rename is trivial:
A second, sneakier violation hides in the same codepath. When go-git writes a
temporary file, it creates that temporary file and then immediately starts
opening it for reading so it can build the pack index. You cannot do that with a
single live object in any object storage system, you are either reading or
writing, never both. I ended up working around this by cheating a bit and
buffering the contents of newly written pack files into memory so that this game
of chicken kept working. I may have to change this to write that pack cache to
the filesystem as trying to push gcc.git made me run out of RAM. At the very
least, everything lies consistently enough that git doesn’t care, so win!
Death by a thousand stat() calls
With this correctness sorted, I tried pushing the
golang/go repository to objgit to see how long
it would take. It did work, but it took forever. Using the prometheus metrics
I mentioned before, I saw that it was making biblical amounts of HeadObject
calls. Some blocking profile analysis pointed to the fact that the git library
was using the stat() call to detect if a file exists. The flow was like:
Client has object x
Check if object x exists
Check if any pack has object x
And so on ad infinitum. This is fine-ish on a local filesystem because those
syscalls resolve in microseconds, not the tens of milliseconds it takes to get
from my office to the nearest Tigris region (please expand to Ottawa, I would
love that so much).
This was compounded with a discovery that the transport I was using (SSH —
classic git:// shares the same code path) was exploding every packfile into
loose objects when pushing it. Each loose object write was costing two round
trips: stat() to check if a file exists and then open() / write() to
actually put the data into Tigris. This made a 100,000 object packfile cost
200,000 object storage calls. Call it 10ms of latency for each one, and that’s
over half an hour of waiting for responses that mostly say “404 not found”.
Caching can’t really save you here either, read caches would absorb the repeated
reads; but this is a firehose of writes to 100,000 paths that probably have
never been read and likely will never be seen again.
The reason only two transports had this problem is a deadlock story. The git
library's fast path stores an incoming pack whole through its PackfileWriter,
by copying from the connection until io.EOF. Over HTTP that's fine: the
request body ends, EOF arrives, everyone goes home. Over git:// and SSH, the
connection is a persistent socket and the client is holding it open, politely
waiting for the server's status report. EOF never comes. The copy waits forever,
the client waits forever, and you have invented a distributed deadlock with two
participants. The original workaround was to hide the PackfileWriter
capability on those transports so go-git fell back to its streaming parser that
writes every object loose. Hence the stat storm.
So the solution was to stop depending on EOF at all. Packfiles are
self-delimiting: the header says how many objects are coming and a trailing
checksum marks the end, so a packfile scanner walks the stream and stops at the
trailer while a TeeReader mirrors exactly those bytes into the
PackfileWriter. This makes the rest of the façade fall into place and the git
library is happy. This made pushes into two uploads: a packfile and its index
instead of a torrent of round trips that mean nothing.
What about cloning?
Once I got pushing fixed, I moved on to the read path. In order to emulate
ReadAt, I used ranged GetObject requests so that the git library could read
individual objects out of packfiles. I was happy with this hack, but there was
one problem: the latency curse struck again. Cloning a simple repo with 318
objects and a 200KiB packfile made over 8,500 GetObject calls before I killed
it.
A git client cloning a repository reads repository packfiles thousands of times
with random access, walking objects and candidate delta bases over and over. On
a local disk you never notice because your page cache eats that for breakfast.
When every call is an HTTP request, a 200KiB repo turns into dozens of megabytes
of round trips. A 20MiB repo was effectively unservable.
In other words, I had un-cached the one workload that caching was designed to
solve.
The fix leans on a gift from git: pack files are immutable and
content-addressed. pack-<sha>.pack will never change for as long as it
exists. This makes them trivially cacheable to a faster local medium, such as
the filesystem. No invalidation logic is required. I made objgit download packs
to a local temporary folder and serve reads from there. To be on the safe side,
I did add least-recently-used caching to the mix so that my temp folder wouldn’t
blow up unexpectedly. This does mean that the first request for pack files is
slower, but then everything else is at filesystem speed.
Yes, this relies on the local disk again, but only as a cache that can and will
be thrown away. I think trading a stateless ideal for clones that terminate in
reasonable amounts of time is a worthwhile bargain.
Why so ListObjectsV2, Batman?
Once the other disasters were out of the way, one more remained: the metrics
showed a flood of ListObjectsV2 calls every time a clone was made and didn’t
stop making those calls after it was done.
Two things compounded. First, when git looks up an object that isn't packed, it
probes for a loose object at objects/<xx>/<rest-of-hash>. objgit keeps packs
whole, so there are no loose objects, so every probe misses, and each miss
across a distinct two-hex prefix triggered a directory listing to find out.
There are 256 possible prefixes. A single clone could issue up to 256
ListObjectsV2 calls whose collective answer was a resounding "there is nothing
here."
Second (and more embarrassing), the listing cache already had an optimization
for this. It collapsed entire subtree lookups into recursive scans so a single
listing of the repository could answer every stat() and probe beneath it. It was
completely dead in production. The cache matched recursive prefixes against the
repo root (refs/), but every repo is chrooted to its own directory, so real
keys look like myrepo.git/refs/heads/main. The prefix check wasn’t aware of
chroots so it never actually matched anything. Nobody noticed because a cache
that degrades to “no caching” still returns the correct answer, just slowly. To
rub it in, a cache warmer was dutifully re-listing every one of those useless
prefixes every 30 seconds for 10 minutes after each clone. Thousands of
background list calls were burned in the service of caching nothing of use.
The fix was insultingly small: when a repo’s filesystem gets chrooted, register
that chroot as a recursive subtree root within the cache. This made the cache
actually useful and resulted in only one ListObjectsV2 call instead of
hundreds. Every sufficiently advanced cache is indistinguishable from a no-op
until someone graphs the miss rate.
None of these disasters were exotic. They’re the things filesystems and kernels
give you for free — and every perfectly reasonable disk assumption fell to
pieces once a network round trip sat at the core. Serving Git repositories is an
accidental filesystem latency benchmark. If your storage abstraction has a weak
point, Git will find it and the metrics will show you where that problem is.
Post-receive hooks go in clown jail
One of the most useful parts of hosting your own git server is setting up
post-receive hooks. These have been used since time immemorial for things like
automatic deployments
when you push code to the server. The heart of this is how we get systems like
GitHub Actions: it’s code that runs when you are done pushing.
When you push to objgit with --allow-hooks enabled, it looks for a
post-receive hook in .objgit/hooks/receive-pack (this corresponds to the git
plumbing action, the name can and will be changed) in the tree of the commit you
just pushed. It will then spin up a
kefka sandbox with a
checkout of the git repository at the commit you just pushed mounted at /src
and mutable temporary files at /tmp. It gets coreutils and nothing else. No
host filesystem, no network, no arbitrary binaries. Output streams back into the
pusher as remote: lines just like when you git push heroku main. Eventually
I want to make custom commands to allow you to deploy
Tekton pipeline changes and kick off CI jobs that way,
but for now I’m happy with this working at all.
You can’t implement policy using these hooks yet. I’m working on it.
Now what?
I taught a bucket to speak git. Where this goes next, roughly in order of how
much the ideas keep me up at night.
CI is the obvious next step. I would wire up commands for things like “apply
kubernetes object” and “create tekton pipeline run” so that CI would run via
your friendly neighborhood Kubernetes cluster and then notify you through some
reasonable mechanism. That’s the first thing I’ll build when I have the time.
It would be nice to have a web UI for this, which is complicated for reasons
that have nothing to do with git trees, object storage, or anything else and
everything to do with the current state of the internet. Git lookups are
expensive in the best cases and with the current torrent of unethical scraping
ransacking git servers for every scrap of RAM they have, it’s probably a bad
idea to implement this without a lot of clever optimizations. Maybe the fact
that this doesn’t have load-bearing dependencies on /usr/bin/git would make it
more resilient against scrapers. The fact that this is based on object storage
could also mean that caching would be a bit easier (having basically unlimited
storage is kind of a low-key superpower for caching), but then the main issue
would be server load. It’s a tough cookie to handle.
Performance and stability are another place this needs to improve. I’ve tested
this on my developer workstation but that is far different from testing it in
production. There’s some other performance issues that are easy to fix, but the
big one is latency to Tigris. Maybe I can get the devops team to set me up a
k3k cluster
in production.
Right now this is an experiment as I plug along and feel out the shape of what
git-on-object-storage can be. A git server with no disk, no git binary, and no
database. If you want to take a look,
check it out on GitHub.
Last month, I had the great pleasure of keynoting the CALM (Conference on Academic Library Management) Conference, which is consistently one of my favorites. The video of my talk, Slow Management in a Fast World, is available below for those who would like to check it out! You can also view my slides here which include a long bibliography of works that influenced my talk at the end.
CALM Conference opening Keynote: Slow Management in a Fast World
Many thanks to all the amazing folks who organized this conference; it was such an honor and a pleasure to be part of it!
The advent of a cryptographically relevant quantum computer (CRQC) would
render state-of-the-art, traditional public key algorithms deployed
today obsolete, as the mathematical assumptions underpinning their
security would no longer hold. To address this, protocols and
infrastructure must transition to post-quantum algorithms, which are
designed to resist both traditional and quantum attacks. This document
explains why engineers need to be aware of and understand post-quantum
cryptography (PQC), and it details the impact of CRQCs on existing
systems and the challenges involved in transitioning to post-quantum
algorithms. Unlike previous cryptographic updates, this shift may
require significant protocol redesign due to the unique properties of
post-quantum algorithms.
At Electricity Maps, we’re data scientists, first and foremost.
Data comes in from many sources, and in many formats. We ingest and
harmonize it, apply our models to it, and make it available to the
world. This is the place to learn more about our data; read FAQs, or
deep dive in our methodology.
BLOBPROC is a less kafkaesque version of PDF postprocessing found in
sandcrawler, which is part of IA Scholar infra. Specifically it is
designed to process and persist documents with minimum number of
external components and little to no state.
The goal is to have artifacts (fulltext, thumbnails, metadata, …)
derived from millions of PDF files available in a storage system
(e.g. S3). In the best case, the artifacts can be kept up to date in an
unattended way
We’re more productive than ever. AI allows us to generate code at
supersonic speeds, unfold entire modules in seconds, and ship thousands
of lines of code. It’s easier to pick up tasks and generate value, even
in unfamiliar codebases. But there’s a dark side. AI-assisted code
generation isn’t free; there’s a hidden cost that we as an industry are
only beginning to realize: AI burnout. Are we dangerously ignorant to
this problem? And how can we cope with it?
A long while back I had an idea to hack a WiFi smart light bulb to do
something more useful to me. Actually, I had a few different ideas of
things to do with them. One of these ideas was to modify the device to
have an open WiFi access point and a web server hosting banned books.
The idea was that if you lived somewhere that banned books you thought
were important, you could theoretically stick a digital copy of the book
on one of these light bulbs. Then you could go install it somewhere in
your community
As AI companies get ready to go public and we get a deeper look at their
inner workings, it’s only natural to have questions about their
finances, like “Do they make money?” and “How?” Here are a few examples
to help the average layperson understand the business side of AI.
… the Map is now a two-dimensional “virtual world” art project which is
now comprised of over 4000 individual eight by ten inch panels. When
assembled, these panels form an approximate circle. The panel locations
are defined by N, S, E, and W coordinates that originate at the center
of the circle. The locations in the matrix do not change, but the panels
themselves are continually revised based on instructions drawn from the
artist’s custom deck of cards.
A step-by-step Jupyter Notebook demonstrating how to build and train a
compact small language model (“SLM”) from scratch using the TinyStories
dataset. Covers data preparation, BPE tokenization, efficient binary
storage, GPU memory locking, Transformer architecture, training
configuration, and sample text generation.
Hooper adores Darwin – his account of visiting Darwin’s Kent residence
Down House radiates reverence (“it’s a pseudo-religious experience”).
But he feels that Darwinism and its union with genetics in the so-called
“modern synthesis” has placed undue emphasis on competition in the
natural world and underplayed the roles of cooperation and
collaboration. In redressing that imbalance, Togetherness is not an
attempt to make evolution cuddlier and more palatable; rather, it is a
corrective deeply informed by what we have learned since Darwin about
how nature works. Written with immense charm and passion, and packed
with eye-popping facts, it is also a paean to the wonders of nature and
the value and urgency of preserving them.
These fungi form trading relationships with more than 70% of plant
species, building networks of tubular cells called hyphae that extend
the surface area of root systems up to a hundred-fold.
Collectively, these networks comprise one of Earth’s circulatory
systems.
Most people are aware of the high fixed cost of training the leading
generative AI models, but there are also significant variable costs of
“inference” in using generative AI. These inference costs are incurred
every time we enter a prompt and receive a response.
In the words of Harvard business professor Andy Wu, most people don’t
realize how “ridiculously expensive” AI is. Most are aware of the high
fixed costs, but not the variable inference costs incurred every time
the model generates an image. OpenAI expects to spend more than $150
billion on inference costs alone through 2030. While the vast majority
of users continue to access the platform for free, the question is how
the gap between resources and revenue will eventually close, and who
will bear the costs.
«Son nom semble la relier à une constellation, mais sa présence au monde
la rend indissociable des paysages qu’elle traverse : Hélène Dorion vit
environnée de lacs et de forêts, de fleuves et de rivages, de brumes de
mémoire et de vastes estuaires où la pensée s’évase. Dans ce recueil
voué aux forêts, elle fait entendre le chant de l’arbre, comme il existe
un chant d’amour et des voix de plain-chant. « Mes forêts… », dit-elle
dans un souffle qui se densifie de poème en poème. Et l’on entre à pas
de loup dans une forêt de signes où l’on déchiffre la partition de la
vie sur fond de ciel, sur fond de terre, sur fond de neige, de
feuillages persistants et de flammes qu’emporte le vent, de bourgeons
sertis dans l’écorce et de renouvellement. Un chemin d’ombres et de
lumière, qui donne sens à ce qu’on appelle humanité. »
If you have problems with webpage playback try these stream buttons,or
add the urls below to VLC or any other streaming/netradio software:
https://orllewin.radioca.st/stream - High quality 256kbps stream.
https://orllewin.radioca.st/lofi - Bandwidth friendly 64kbps stream.
The manifesto, in my imagined alternative, is the ugly smear on the
polished surfaces of conference keynotes, aspirational #bizdev posts and
job-ready portfolio pieces. The manifesto is awkward, clunky,
impractical, confronting, uncompromising, defiant: all qualifiers
undesirable in an increasingly professionalised, corporatised game
making ecosystem. These traits are what makes the manifesto beautiful.
Microsoft is turning to its biggest cloud rival, Amazon, to help address
capacity issues on its GitHub coding platform following a series of
AI-driven outages, according to two people familiar with the plans.
GitHub, which Microsoft acquired in 2018, is a popular place for
engineers to store and manage code, and collaborate on projects. As an
independent company, GitHub mostly operated its own data centers, but
Microsoft had planned to move the coding platform entirely to its Azure
cloud service by 2027.
Now, a boom in AI demand is forcing Microsoft to lean on Amazon. AI
coding tools have made it easier for developers to write more software.
That has swamped GitHub with a flood of new code, straining its compute
resources.
I was born in a small town to two schoolteachers who believed education was not just a profession but a purpose. Growing up in such an environment meant that learning was never forced; it was simply part of everyday life, and curiosity was always encouraged rather than questioned. Books were treated like companions in our home, and questions were welcomed more than answers. My father, a mathematics teacher and statistics topper, did not just teach numbers. He taught me how to see patterns in the world, how to question things, and how to stay curious. He had a way of turning ordinary moments into lessons, showing me that knowledge was not confined to classrooms but hidden in everything around us. Conversations at home often revolved around ideas, discipline, perseverance, and integrity, quietly shaping my mindset long before I understood their value. That atmosphere made me believe that effort mattered more than circumstance and that consistency could take a person farther than talent alone. No one imagined back then that this quiet boy would one day cross oceans and earn a Ph.D. in Computer Science. Dreams rarely ask where you start. They only ask how far you are willing to go.
My mother, who was also a schoolteacher, played an equally powerful role in shaping my values. From her, I learned patience, discipline, and the importance of consistency in everything I pursued. She believed that true education was not about marks but about character, and she constantly reminded me that knowledge should make a person humble, not proud. Watching both my parents teach day after day made learning feel natural to me, not like a task but like a way of life.
My grandfather’s life story was another silent source of inspiration. He grew up during colonial India and witnessed the struggles of a nation finding its identity. Rising through hardships, he eventually earned the respected position of a gazetted officer, a journey that required perseverance, resilience, and integrity. His life stood as proof that circumstances do not define destiny; determination does. Even without long speeches, his presence alone taught lessons that no classroom ever could.
I spent most of my childhood at my grandfather’s house because it was close to my school, and that environment shaped me deeply. The atmosphere there was disciplined, structured, and principled. Time was respected, routines were followed, and values were lived rather than spoken. Growing up in such surroundings quietly instilled habits that later became my strongest foundation during demanding academic years and life’s toughest challenges.
Growing up in a modest household meant resources were limited, but encouragement was abundant. Books were never treated as objects but as companions, and curiosity was never dismissed as childish. Those early years quietly shaped the mindset that later helped me face some of the toughest academic and personal challenges of my life.
My academic journey began with a Bachelor’s in Information Technology, followed by a Master’s in Computer Science at Manipal University. That was where curiosity turned into direction. I started building systems, experimenting with ideas, and asking questions beyond textbooks. I built an AI-based disease prediction model, and that project showed me something important. Technology is not just code. It is an impact. That realization changed the way I looked at learning and the future.
University life was not only about grades or achievements. It was where I learned independence, responsibility, and how to handle failure. Every project deadline, presentation, and challenge strengthened not only my technical knowledge but also my confidence in my own potential.
Alongside academics, I always had a creative side that refused to stay silent. I pursued a diploma in filmmaking because storytelling fascinated me as much as algorithms did. Cinema taught me perspective, emotion, and imagination. I developed a deep interest in psychological, horror, and suspense films because they explore the human mind in ways that science alone cannot explain. I even had the opportunity to perform on stage as Lord Krishna in a theatrical production, an experience that taught me confidence, presence, and expression. Since then, I have carried a quiet dream within me to one day create a film of my own.
That phase of life taught me something powerful. It showed me that growth does not happen when we limit ourselves to one dimension but when we allow different sides of our personality to coexist and complement each other. Creativity and logic are not opposites. They are partners. One fuels possibility while the other shapes it into reality. The ability to imagine helps innovation, and the ability to analyze helps execution. When both work together, ideas do not just remain thoughts; they become solutions. This balance later became one of my greatest strengths in research and problem-solving. During my university years, I became the only student from my institution to secure a full-time internship at HP R&D, where I worked on an AI-powered auto-diagnostics system. Walking into that environment, surrounded by brilliant minds and real-world challenges, felt both humbling and motivating at the same time. It pushed me to raise my own standards and think beyond what I had previously believed possible. For the first time, I saw how research and industry could come together to solve real problems. I realized that technology is most powerful when it moves beyond theory and begins to create a tangible impact on people’s lives. That experience strengthened my belief that innovation happens when curiosity meets discipline.
Walking into that workplace for the first time felt surreal. The environment was unlike anything I had experienced before, filled with people who spoke the language of innovation, curiosity, and possibility. It was proof that hard work can open doors you once thought were unreachable. In that moment, I realized that opportunities are not reserved for a select few; they often wait quietly for those willing to persist long enough to find them. More importantly, it showed me that I belonged in spaces where ideas mattered more than background.
Soon after, I achieved another milestone by becoming the first student from my university to intern at Procter & Gamble in Europe. There, I developed AI and IoT tools for safety and automation. It felt like I had finally reached the dream I once imagined. But life sometimes asks you to step away from comfort to pursue purpose. Leaving that opportunity after countless overnight visa trips was not easy, but I chose uncertainty because I wanted to create knowledge and not just apply it.
That decision was not understood by everyone. Some questioned it, others doubted it, and a few even discouraged it. But growth often begins where comfort ends. I realized that the path to something extraordinary rarely looks safe or predictable. Then COVID arrived, and my Ph.D. journey was delayed by nearly two years. Plans paused, uncertainty grew, and the path ahead looked unclear. Instead of waiting for circumstances to change, I decided to change myself. I spent that time upskilling, studying, building projects, and preparing for an opportunity I could not yet see. In August 2021, during travel restrictions and global uncertainty, I boarded a flight to the United States carrying two things. Fear and determination.
That flight was more than travel. It was a turning point. It symbolized leaving behind familiarity and stepping into the unknown with faith. Moments like that define a person not because they are easy, but because they demand courage. A Ph.D. is not just a degree. It is a test of patience, resilience, and belief. It is months of work that sometimes lead nowhere, papers rejected after weeks of effort, ideas challenged, and moments when you question yourself. But it is also growth, clarity, and discovery. Each obstacle became a lesson, and each lesson made me stronger. I learned that persistence is not loud. It is quiet, steady, and stubborn.
Some of the most important lessons I learned during my doctoral journey were not written in textbooks. They were learned in silence, in reflection, and in perseverance. Research does not reward speed. It rewards depth. It does not reward noise. It rewards clarity.
Over time, that persistence began to show results. I published more than twenty research papers and had the opportunity to present my work at international conferences across Europe, Australia, and North America. These experiences allowed me to engage with researchers from around the world, exchange ideas, and refine my perspective on accessibility, artificial intelligence, and human-centered computing.
Selected conference presentations and research travel included presenting at the 28th International Conference on Theory and Practice of Digital Libraries (TPDL 2024) in Italy (Conference Report), participating in the ACM SIGWEB Conference on Hypertext and Social Media (HT 2024) in Poznań, Poland (Conference Report), presenting at the ACM SIGCHI Conference on Engineering Interactive Computing Systems (EICS 2023) in Swansea, Wales, United Kingdom (Conference Report), and attending the International Conference on Intelligent User Interfaces (IUI 2023) in Sydney, New South Wales, Australia (Conference Report).
My research journey was also enriched by industry experiences, including a Summer Research Internship at ISG (Internship Report) and a Summer Data Analytics Internship at PRA Group (Internship Report). These opportunities allowed me to apply research ideas in real-world settings and strengthened my understanding of how academic innovation can create practical impact.
These experiences culminated in receiving the Best Paper Award at ACM W4A 2025 for our work on adapting online customer reviews for blind users, a recognition that remains one of the highlights of my doctoral journey. I shared reflections on this achievement and the award-winning work in this X post about the ACM W4A 2025 Best Paper Award.
Standing on international stages and presenting my research to global audiences was humbling. Each presentation reminded me that knowledge has no borders and that ideas can travel farther than we ever can.
Eventually, the moment arrived that once felt impossibly far away. I earned my Ph.D. in Computer Science from Old Dominion University. My dissertation defense marked the culmination of years of research in accessibility, artificial intelligence, and human-computer interaction. My dissertation is publicly available through Old Dominion University Digital Commons: http://doi.org/10.25777/767n-ra09. The defense presentation and selected photo from the event are included below.
Standing there, I did not just see a degree. I saw every late night, every doubt, every rejection, every lesson, and every person who supported me along the way. I thought about the sacrifices my family made, the mentors who guided me, and the friends and colleagues who encouraged me during difficult moments. I was reminded that every challenge had shaped the person I had become. What began as a dream in a small town had gradually unfolded into a journey that took me across continents, introduced me to remarkable people, and challenged me in ways I never imagined.
Looking back, I saw more than academic milestones and professional achievements. I saw a young student driven by curiosity, a researcher shaped by persistence, and a person transformed by every challenge encountered along the way. In that moment, I understood that success is never a single event. It is a collection of moments, sacrifices, failures, risks, and resilience stitched together over time. I also came to appreciate that the people we meet, the experiences we embrace, and the challenges we overcome often shape us just as much as our accomplishments. Each stage of the journey brought lessons that extended far beyond academics, teaching me perseverance, gratitude, and the value of continuous growth. The degree was only a symbol. The journey was the real achievement.
This Ph.D. is not the finish line. It is the beginning of a new chapter filled with opportunities to learn, contribute, and create meaningful impact. If there is one thing my journey has taught me, it is that no dream is too big, no struggle is too heavy, and no setback is final. Sometimes the longest paths lead to the most meaningful destinations, and sometimes the quietest beginnings lead to the loudest impact. For me, this journey has always been about learning, growing, and giving back, and I look forward to wherever that path leads next.
Thanks to the June release team: Galen Charlton (Equinox), Gina Monti (Bibliomation), Sarah Moody (ECDI), Andrea Buntz Neiman (Equinox), and Chris Sharp (PINES); as well as everyone who contributed fixes and testing to this release.
Anubis is about to get WebAssembly-based proof of work checks so that administrators can use a non-SHA256 proof of work method to protect their websites. Part of the implementation goals of this work is that the check logic is defined in one place on both client and server. The client and server will then hook into the WebAssembly in order to make sure they're running in lockstep.
However, one small problem comes up. What do you do when the client has WebAssembly disabled? I really don't want to de-facto lock people out of websites. Anubis exists in an impossible balance of user experience, administrator experience, and developer experience and any change to any of these factors disrupts the balance for other factors.
To work around this and also fulfill the goal of having check logic defined once, I decided to take inspiration from the legendary talk The Birth and Death of JavaScript and just recompile the WebAssembly to JavaScript. Sure, the resulting JavaScript will be slower than the equivalent WebAssembly (even more so because disabling WASM usually disables the JavaScript JIT, the thing that makes JavaScript fast), but it will finish eventually. Hopefully it will be more efficient than the existing JavaScript is on lower end hardware, but research is required.
Luckily enough, the tool I need (wasm2js from the binaryen project) is packaged in Linux distributions. The bad news is that distributions ship ancient versions of it that don't get the same output as the version on my development machine's copy from Homebrew.
In order to really make sure that the output of this is deterministic (essential for reproducible builds), I need to bundle a copy of wasm2js. So I did that by building a version of wasm2js compiled to WebAssembly with wasi-sdk. The rest of the article is the tale of reproducibility woe that lead to the implementation I ended up with. Buckle up and enjoy the ride!
Back up a sec, this doesn't make sense to me. If you have the same bytes of
input to a compiler, you should get the same bytes of output assuming
that the compiler flags, target, and other platform details are controlled
for right? A compiler is just a deterministic function of input source code
becomes output bytecode, right?
lol you'd think, but no, it's not. In theory it is (and for small scale
compilers it definitely is), but in practice compilers are strange and
complicated beasts containing multitudes that no mere mortal can fully
comprehend on their own.
There are a shocking number of ways to accidentally create nondeterministic output when doing C/C++ development. One of the easiest is to use the builtin __DATE__ and __TIME__ macros to stamp a build with the time the compiler was executed at:
$ make clean && make hello.wasm && wasmtime run -W exceptions=y ./hello.wasm
rm -f hello.o hello.wasm
wasi-sdk-33.0-x86_64-linux/bin/wasm32-wasip1-clang++ -O3 -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -c hello.cpp -o hello.o
wasi-sdk-33.0-x86_64-linux/bin/wasm32-wasip1-clang++ -O3 -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -fwasm-exceptions -lunwind --no-wasm-opt hello.o -o hello.wasm
Jun 18 2026 00:00:59
Another time it gets me this:
$ make clean && make hello.wasm && wasmtime run -W exceptions=y ./hello.wasm
rm -f hello.o hello.wasm
wasi-sdk-33.0-x86_64-linux/bin/wasm32-wasip1-clang++ -O3 -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -c hello.cpp -o hello.o
wasi-sdk-33.0-x86_64-linux/bin/wasm32-wasip1-clang++ -O3 -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -fwasm-exceptions -lunwind --no-wasm-opt hello.o -o hello.wasm
Jun 18 2026 00:01:11
Even though the source code had the same bytes, the output of the compiler was wildly different.
In order for users and packagers to trust the binaries of wasm2js I'm committing to the Anubis repo, I need to make sure that you can build the same version I built, down to the same bytes. For an added bonus, you should be able to build this on your machine and get the same bytes I got.
That sure does sound like a great ideal, it would be horrible if something
unforeseen came up to ruin it!
Clang silently runs wasm-opt from $PATH behind your back
Among other tools like wasm2js, binaryen has a bunch of other useful tools such as wasm-opt. wasm-opt optimizes WebAssembly compiler output to let you eke out more performance. This doesn't work in every circumstance, but when it does work it makes a huge difference. As such, clang shells out to wasm-opt when doing builds.
This normally makes sense, but in this case it caused builds to fail on my DGX Spark because its version of wasm-opt is too old:
$ uname -m && which wasm-opt && wasm-opt --version
aarch64
/usr/bin/wasm-opt
wasm-opt version 108
Compared to my workstation which installs wasm-opt from Homebrew:
$ uname -m && which wasm-opt && wasm-opt --version
x86_64
/home/linuxbrew/.linuxbrew/bin/wasm-opt
wasm-opt version 130
Turns out that wasi-sdk and binaryen rely on the WebAssembly Exceptions extension. This is a reasonable thing to assume given that wasi-sdk mostly assumes you're building things for web browsers and 93.86% of browser users have a browser engine new enough to support it. C++ is also one of the main places where exceptions are used, so I guess WebAssembly-native exception handling removes a lot of boilerplate here.
Both wasmtime and wazero require you to flag into exception support. This is fine; we can just pass -W exceptions=y to wasmtime and use a custom runner harness for wazero. The annoying part is what happens when my arm machine's anemic build of wasm-opt sees exception handling instructions, causing it to exit. This made the build fail.
The solution was to pass --no-wasm-opt at the linking step. This removed one angle of irreproducibility.
I guess in the future we could make it use the version of wasm-opt it just
built to optimize the output, but that may be a premature optimization for
now.
Clang relies on address layout for ordering things
The version of clang that I use to compile wasm2js has some address-sensitive code generation hiding in its exception handling path. Raw pointer values leak into the order a handful of try_table blocks come out in. This surfaces as every build differing from the next by about 29 bytes:
The computation is nearly identical, but the byte order is just different enough to also make the catch references differ. This also fires when you build this pinned version of wasm2js on arm64 machines because its pointer iteration order is different from it is on my workstation.
To work around this, I took two steps:
Disable address-space randomization for this build using setarch --addr-no-randomize.
Create known good sha256 checksums for both x86_64 and arm64 via building this program on machines I trust.
I also made a CI job ensure this:
-name: Ensure reproducibility
run:| cd ./utils/wasm/wasm2js
./build.sh
if sha256sum -c --status shasums.x86_64; then
echo "OK: rebuilt modules match the recorded x86_64 checksums"
elif sha256sum -c --status shasums.arm64; then
echo "OK: rebuilt modules match the recorded arm64 checksums"
else
echo "::error::rebuilt wasm2js/wasm-opt match neither recorded checksum set on ${{ matrix.runner }}" >&2
sha256sum wasm-opt_130.wasm wasm2js_130.wasm
exit 1
fi
To be extra sure, we have this job run on both x86_64 and arm64 hosts. I'd really love to have this be reproducible across hosts, but that's an upstream LLVM bug that I am not powerful enough to tackle. If you work on LLVM and are reading this, it would be nice to set a seed of some kind to ensure that this iteration order is fixed across architectures.
At the very least builds are deterministic within architectures. This may have to be good enough for now.
Collaboration. Serendipity. Diversity. These are the qualities that come to mind when I think about this year’s OCLC quilt and the community that created it.
The OCLC Quilters, a group of current and retired OCLC employees, have spent months creating a quilt of 120 cross-cut blocks to donate to the silent auction held during the ALA 2026 Annual Conference. The ALA BiblioQuilters annually host this auction as a fundraiser for the Christopher Hoy Scholarship, which awards a $5,000 scholarship each year to a U.S./Canadian citizen or permanent resident who is pursuing an MLS in an ALA-accredited program.
This is the fourth year in a row that the OCLC Quilters have donated a quilt to the silent auction. Their work inspired me to take up sewing about a year ago, and I’m proud to move from admirer to participant, contributing to the OCLC quilt for the first time. Although left-handed people are about 10% of the population, three of the 13 people contributing to the OCLC quilt, including myself, are left-handed. While that doesn’t affect the result, it requires a few adjustments in technique and having the appropriate scissors. Sharing advice on adapting equipment and shopping for left-handed supplies is one of the ways we support each other.
Nine of the 13 contributors to the OCLC Quilt for the ALA 2026 Annual Conference
Like all handicrafts, quilting is an activity with its own nomenclature. As a quilter and cataloger, I found myself wondering: “What controlled vocabulary terms could I use to describe the OCLC quilt?” There are several from vocabularies such as Library of Congress Subject Headings (LCSH) and Getty Art and Architecture Thesaurus (AAT). These are listed at the end of this blog.
A quilt is created from many elements that may not be individually significant but form a meaningful whole, just like a WorldCat bibliographic record. The blocks of the quilt function like data elements in a WorldCat record, with contributions from multiple individuals creating the larger work.
Assembling the quilt
OCLC quilters sewed 120 blocks, which are the fabric squares comprising the quilt’s front. The blocks are a cross-cut design—a pattern chosen because it is accessible for novice sewists and makes good use of small fabric pieces. Quilters often save these leftover pieces, called “scraps,” from other projects for future use. Reusing scraps makes quilting a sustainable craft, and quilters often share them with one another. An experienced OCLC quilter, who keeps her scrap collection organized in true librarian fashion, donated most of the fabric pieces used for the blocks.
Experienced quilters arranged and sewed the blocks together and cut the batting (soft material used between the front and back sides of the quilt). The next step, in which three layers are sewn together with a decorative stitch, is quilting. This is the strict definition of the term “quilting,” although it is often used to refer to the entire process of creating a quilt. The pattern used for the quilt stitching is called “modern ties,” and it looks a bit like tied shoelace loops.
An OCLC logo is incorporated into one of the quilt blocks
The final step is to sew a long strip of binding fabric around the edges of the quilt, which will keep the ends from fraying as well as being decorative. Two labels were sewn into the binding: “Made in OH” and “Is it perfect? No.” Both of these labels are accurate descriptions of this quilt, but unlike in bibliographic descriptions, a certain amount of imperfection is not only tolerated but may be considered part of the quilt’s charm.
A quilting tradition at ALA Annual
The OCLC quilt will be one of many available at the ALA BiblioQuilters silent auction during ALA Annual in Chicago, Illinois. The BiblioQuilters were founded at the 1998 ALA Annual Conference in Washington, D.C. Since 2000, the BiblioQuilters have had a silent auction of quilts every year except 2020 and 2021 (because of the pandemic). The quilts are usually available to view and bid on near the registration area. If you are attending ALA in Chicago, I highly recommend you visit the auction table to view them. After ALA, you may be inspired to browse the shelves of your local public library for 746.46, the Dewey Decimal number for quilting.
Subject vocabulary terms
For those readers who appreciate quilting and metadata, the following controlled vocabulary terms reflect concepts discussed in this blog. You might even find it fun to match the concepts to the natural language descriptions!
LibraryThing is pleased to sit down this month with groundbreaking author and poet Cynthia Pelayo, who in 2022 became the first Puerto Rican and first Latina to win a Bram Stoker Award after her Crime Scene took the prize in the Poetry Collection category. Her Into The Forest And All The Way Through was a 2020 nominee, also in the Poetry Collection category, while her Children of Chicago was a 2021 nominee in the Novel category. Pelayo earned a BA in Journalism from Columbia College Chicago, a MS from Roosevelt University, and a MFA in Writing from the School of the Art Institute of Chicago. She is currently pursuing a PhD in English. Her MFA writing thesis, Lotería, was republished in 2023, winning an International Latino Book Award Silver Medal in the Best Collection of Short Stories category. A co-publisher of Burial Day Books, which focuses on horror writing, she is the author of numerous other books, stories and poems, including novels such as The Shoemaker’s Magician (2023), Forgotten Sisters (2024), and Vanishing Daughters (2025). Her new novel, It Came from Neverland, a work of horror inspired by the classic Peter Pan, was published by Crooked Lane Books earlier this month. Pelayo sat down with Abigail this month to discuss her new book.
Tell us a little bit about It Came from Neverland. How did the idea for the story first come to you?
Like many people, I grew up watching the Disney version of Peter Pan, and then I remember watching Hook with Robin Williams and being captivated, seeing Peter Pan as an adult who had to remember who he was. There was an older Wendy in that film, and that always stayed with me because I really wanted to know what Wendy’s story looked like aged into young adulthood.
When I went back to J.M. Barrie’s Peter and Wendy and the original play, I worked out that Wendy would be in her early twenties at the start of the First World War. And then I learned that many young men at that time lied about their age to enlist, some of them were barely more than boys. It all felt like a perfect juxtaposition, these boys going off to war and Wendy’s trauma round caring for the Lost Boys from Neverland.
A woman of that time period would certainly not be believed if she tried to tell the truth about what she experienced as a child in Neverland, and so that certainly played into her experience. Then I thought well, Wendy at this age would certainly be in a position that reflected her character, and schoolteacher fit perfectly. The story wrote itself, because I knew that Wendy would do all that she could to protect those children and I also knew Peter Pan would surely return to whisk more children away to Neverland. So this story is that tale, what does she do to stop Peter Pan.
What drew you to Peter Pan, and what made you feel it was horror?
Peter Pan without Wendy Darling is just a boy screaming into the dark. The story only works because Wendy agrees to go with him to Neverland, and she goes because she is sweet and kind and she believes him. Wendy’s only failure here was that she had a good heart, which is just so sad because her being nice is why she was taken advantage of. She trusted someone who was manipulating her. Peter told her she was special, but what he really meant was that she was useful. She was given the role of mother to the Lost Boys, not because she was truly loved or valued, but because someone needed to do the mending. This is not fantasy. This is a domestic horror story dressed in fairy dusty.
In Peter and Wendy we’re also essentially told that growing up is a curse, but I push back on that. Growing up is the adventure, becoming yourself, and gaining autonomy is the gift.
Peter’s entire pitch was stay here, never change, never leave me. Shrink. Lost yourself to praise me. That’s not love. That’s control.
The horror was always there. I just removed the glitter.
What is it about fairy tales that speaks to you?
Fairy tales were the very first stories I was told as a child. “Little Red Riding Hood,” “Hansel and Gretel,” “Cinderella,” more. I hold all of them dear, even though many of them have a thread of terror, but I suppose that’s why I’m the writer I am today.
What I’ve come to understand is that fairy tales are an early societal warning system, in a way. They prepared us for danger, and that’s why they still work. Little Red Riding Hood is everyone who has been told not to talk to strangers on their way home. Bluebeard is everyone who has been warned to be cautious with suitors. Snow White is every person who has fallen victim to the cruelty of jealousy. These stories survived centuries because beneath them there is some truth that can be applied to many of our experiences today. They encode the things that we should say out loud, but don’t because of all of those strange polite society rules, things like – don’t trust the stranger who flatters you, the beautiful thing is likely the trap, or even, the person who promises you forever can very well be the one who seeks to destroy you.
When looking at all of these through a horror lens, they echo to the horror writer what is our job – and that is to tell the truth. Horror is the genre of truth, to highlight the danger, to be a witness to survival, more. So much of what fairy tales do speak to this.
Are there other classic works you’re interested in transforming?
Yes, and the one upcoming is a Frankenstein retelling titled Everina from Union Square & Co. I have more, but I can’t mention those quite yet.
Tell us a little bit about your writing process.
I generally write in the early morning. In the evenings that’s when I tend to answer email or work on lectures for any workshops I’m teaching or work on any of my own homework.
In terms of my actual writing sessions, I read before I write, generally I will read some poetry and then start writing. If you’re asking about the big questions regarding how do I create something, I think I’m a pretty methodical writer in that yes, I allow discovery to happen, but as of recent, there is a lot of researching, planning, and pre-writing that goes into my actual writing. Then there is editing, and that is an entirely different process. I tell writers to think of these processes as three separate demands, research and preparation requires one aspect of your brain, editing requires a different aspect of your brain and the actual writing, which is a completely different process. When you are writing you are creating, allow yourself to have fun and explore when you’re actually writing.
What comes next for you?
Something Followed Us Home: Tales of Latiné Horror comes out September 29 from Simon & Schuster. It’s an anthology I edited that features Mariana Enríquez, Agustina Bazterrica, Mónica Ojeda, Isabel Cañas, Daniel José Older, Zoraida Córdova, and others, with a foreword by Brenda Lozano. Latiné horror isn’t a subgenre, it’s a tradition that I’m grateful to have had the opportunity to share with readers.
After that, Everina, which is my Frankenstein retelling.
Tell us about your library. What’s on your own shelves?
What have you been reading lately, and what would you recommend to other readers?
I am reading Piranesi by Susanna Clarke. I love world building, and here, we have a world that operates on its own logic, the architecture of the space, and the feelings it evokes. Clarke gives us infinite halls that become both prison and sanctuary, and it’s this tension that I’m drawn to as both a reader and writer.
Rockets, unlike other anthropogenic pollution sources, emit gaseous and solid chemicals directly into the upper atmosphere. We compile inventories of these chemicals from rocket launches in 2019 and projections of future growth and speculative space tourism activity. We incorporate these in a 3D atmospheric chemistry model to simulate the impact on climate and the protective stratospheric ozone layer. We find that loss of ozone due to current rockets is small, but that routine space tourism launches may undermine progress made by the Montreal Protocol in reversing ozone depletion in the Arctic springtime upper stratosphere. The BC (or soot) particles from rockets are also of great concern, as these are almost five hundred times more efficient at warming the atmosphere than all other sources of soot combined.
Note that even four years ago it was already clear that the space industry was both depleting ozone and aggravating global warming. But this was before the scale of the proposed mega constellations was evident.
So far, models of spacecraft reentry have focused on understanding the hazard presented by objects that survive to the surface rather than on the fate of the metals that vaporize. Here, we show that metals that vaporized during spacecraft reentries can be clearly measured in stratospheric sulfuric acid particles. Over 20 elements from reentry were detected and were present in ratios consistent with alloys used in spacecraft. The mass of lithium, aluminum, copper, and lead from the reentry of spacecraft was found to exceed the cosmic dust influx of those metals. About 10% of stratospheric sulfuric acid particles larger than 120 nm in diameter contain aluminum and other elements from spacecraft reentry. Planned increases in the number of low earth orbit satellites within the next few decades could cause up to half of stratospheric sulfuric acid particles to contain metals from reentry.
Much of the reentry burn happens above the stratosphere, and it takes time for the aluminum nanoparticles to drift down to the levels where they were collected. So the 10% number represents pollution from an earlier period with fewer reentries that the 2020s. Murphy notes that:
Most of the meteoric mass is deposited at altitudes between 75 and 110 km by a very large number of sub-millimeter meteoroids. Reentering spacecraft, which are larger and moving more slowly, ablate between 40 and 70 km over a ~300 km long footprint
This paper investigates the oxidation process of the satellite's aluminum content during atmospheric reentry utilizing atomic-scale molecular dynamics simulations. We find that the population of reentering satellites in 2022 caused a 29.5% increase of aluminum in the atmosphere above the natural level, resulting in around 17 metric tons of aluminum oxides injected into the mesosphere. The byproducts generated by the reentry of satellites in a future scenario where mega-constellations come to fruition can reach over 360 metric tons per year. As aluminum oxide nanoparticles may remain in the atmosphere for decades, they can cause significant ozone depletion.
Ferreira et al confirm the potentially long delay between reentry and the nanoparticles reaching the ozone layer and depleting it:
we find that these reentry byproducts may take up to 30 years to settle from the top of the mesosphere into the stratospheric ozone layer. Upon reaching an altitude of about 40 km, aluminum oxides catalyze chlorine activation which promotes ozone depletion. This suggests that concentrations of aluminum oxide compounds may start increasing in the mesosphere well before reaching the stratospheric ozone layer. This would introduce a noticeable delay between the beginning of the injection process when orbiting bodies are decommissioned and the eventual ozone-depletion consequences in the stratosphere.
A lack of observations and validated models of reentry demise limits our ability to simulate the complex aerosols associated with reentry, which makes estimating the climate impacts difficult. Aluminum is a primary satellite component and will likely be emitted during reentry vaporization in the form of alumina. Unmodified alumina is a useful approximation for metallic reentry aerosol. In this study, we simulate a potential yearly emission of 10,000 metric tons of alumina from reentering space debris. We investigate how the location of atmospheric accumulation, aerosol size distribution, and radiative properties of reentry alumina impacts the middle atmosphere. We find that 20,000–40,000 metric tons of alumina accumulates at high latitudes between 10 and 30 km in both hemispheres. Small changes in mesospheric heating rates lead to 1.5-K temperature anomalies in the middle atmosphere at high latitudes. These temperature anomalies are accompanied by changes in wind speed in the polar vortex.
So there are thermal effects on the climate as well as the effects on the ozone layer.
To understand if significant ozone losses could occur as the launch industry grows, we examine two scenarios. Our ‘ambitious’ scenario (2040 launches/year) yields a −0.29% depletion in annual-mean, near-global total column ozone in 2030. Antarctic springtime ozone decreases by 3.9%. Our ‘conservative’ scenario (884 launches/year) yields −0.17% annual, near-global depletion; current licensing rates suggest this scenario may be exceeded before 2030. Ozone losses are driven by the chlorine produced from solid rocket motor propellant, and black carbon which is emitted from most propellants. The ozone layer is slowly healing from the effects of CFCs, yet global-mean ozone abundances are still 2% lower than measured prior to the onset of CFC-induced ozone depletion. Our results demonstrate that ongoing and frequent rocket launches could delay ozone recovery. Action is needed now to ensure that future growth of the launch industry and ozone protection are mutually sustainable.
Note that this paper addresses only the ozone depletion from launches, not from reentry. But their 'ambitious' scenario of 5.6 launches/day is far short of Musk's ambitions, let alone the other planned megaconstellations. My understanding is that the 2040 launches/year in their scenario are of Falcon 9 class vehicles but "only 4.4% of launches are using vehicles designed for re-entry", which is implausible. But the mega-constellations can't be built or maintained with Falcon 9s.
To achieve that, they would need to launch 120,000 satellites per year. Over the 15 years, they would launch 1.8 million satellites, but 800,000 of them would fail (as part of our 9% failure rate), leaving a total operational fleet of one million satellites. This equates to 3,158 Starship launches per year, or nearly nine launches per day. For some context, the current launch rate for Starship is just five per year.
...
In order to keep a million satellites in the constellation, it needs to be maintained. So, each year, SpaceX would have to launch 90,000 AI Sat Minis to replace the roughly 9% of the constellation that failed. That equates to 2,368 Starship launches per year, or 6.4 per day.
That's 9 launches/day for 15 years then 6.4 launches/day indefinitely of a much rocket that is vastly bigger than Falcon 9 and is completely re-usable.
Of course, these claims are ridiculous - neither logistically nor economically feasible. But assuming Starship or a competitor such as Blue Origin does manage to create a reliable, reusable, 100 ton to LEO launch vehicle, there will be a lot more mass in LEO and a lot more of it reentering.
A 10-fold enhancement of lithium atoms was detected at 96 km altitude by a resonance lidar at Kühlungsborn, Germany, approximately 20 hours after the uncontrolled re-entry of a Falcon 9 upper stage. The upper-atmospheric extension of the ICON general circulation model, nudged to ECMWF, was used to calculate winds. Backwards trajectories, including wind variability as measured by radar, traced air masses to the Falcon 9 re-entry path at 100 km altitude, west of Ireland. This study presents the first measurement of upper-atmospheric pollution resulting from space debris re-entry and the first observational evidence that the ablation of space debris can be detected by ground-based lidar. The analysis of geomagnetic conditions, atmospheric dynamics, and ionospheric measurements supports the claim that the enhancement was not of natural origin. Our findings demonstrate that identifying pollutants and tracing them to their sources is achievable, with significant implications for monitoring and mitigating space emissions in the atmosphere.
The effect of lithium and other spacecraft ingredients on the ozone layer doesn't appear to have been studied compared to aluminum. To be fair, there will be a lot more aluminum.
We use a global inventory of launch and re-entry emissions covering the onset of the megaconstellation era (2020–2022), and project these to 2029 based on 2020–2022 growth rates. We implement this inventory into a 3D atmospheric chemistry model to determine the impacts of megaconstellations on the ozone layer and climate. We find that global stratospheric ozone depletion from all mission types is relatively small compared to surface sources and megaconstellation missions only account for about one-tenth of this depletion. This is because rockets launching megaconstellations almost all use kerosene, a large source of black carbon or soot particles, but not of chemicals such as chlorine that directly destroy ozone. Soot from rockets absorbs sunlight, warming the upper layers of the atmosphere and decreasing the amount of sunlight reaching Earth's lower atmosphere, causing it to cool. Megaconstellation missions are responsible for about half of this climate effect. In this regard, rockets launching megaconstellations and other missions are like small-scale stratospheric aerosol injection experiments without forethought for potential unintended consequences.
Again, this paper addresses only atmospheric impacts from launches, not from reentries. And, the launch rate for 2020-2022 is far less, and uses much smaller rockets, than the proposed "million satellite data center" and its competitors.
The open-source movement emphasizes the power of freely modifiable, flexible code to support transparency, collaboration, and building outside vendor lock-in. Open hardware extends that logic to the physical layer: chips you can read, modify, and build on. All software runs on hardware, and over the past few years, the ground under the hardware industry has been shifting. Since 2022, the United States, the Netherlands, and Japan have progressively tightened export controls on advanced chips and the equipment used to manufacture them; China has responded with a state-backed effort to reproduce every layer of that supply chain at home. Policy analysts now routinely describe the trajectory as a “fragmentation” or “decoupling” of the global semiconductor market into separate technology spheres. Hardware costs are climbing across the board, so accessing open hardware feels all the more relevant for a group building open-source software.
Open hardware doesn’t make the chips any cheaper. What it changes is what a chip you already own is allowed to become or what kinds of application-specific chips you can create. A single FPGA (Field-Programmable Gate Array) on a shelf can be a video codec today, a custom search accelerator the next, and a faithful copy of a decommissioned architecture the day after that. The unit cost is what it is; the value you can extract from that unit is no longer fixed by a vendor. For institutions whose time horizons stretch over decades, like libraries, archives, and public-interest research groups, that reconfigurability is the core of the open-hardware argument that compounds.
There are no known open-source hardware implementations of Google’s TPU, the in-house chip family Google designed to accelerate neural network math. The silicon is proprietary and not directly purchasable by consumers except in edge TPU form (e.g., Google Coral). This field note reports a small experiment porting the OpenTPU project, a Python simulation of Google’s TPU published by UCSB’s ArchLab, to an inexpensive FPGA board to explore the pros and cons of using more open hardware. To keep the experiment lightweight, most of the code was written by AI coding agents, with a human directing the work.
Why FPGAs, For A Lab Like This One
An FPGA (Field-Programmable Gate Array) is a chip whose internal logic can be reconfigured. You describe the circuit in a hardware description language, SystemVerilog, compile it to a bitstream, and load it onto the board. A CPU runs your program. An FPGA becomes your program. FPGAs are the obvious place to start, because they’re the one piece of reconfigurable silicon a small lab can actually buy and program today.
The practical difference lies in the shape of the problems they solve. A CPU is a generalist reading a manual one step at a time. A GPU is a factory floor of thousands executing the exact same standard math in unison. An FPGA is a machine whose gears are configured to fit exactly one algorithm. They excel at problems with strange shapes. If your workload involves multiplying massive, uniform matrices to train a language model, you want a GPU. But if your work requires parsing millions of irregular text strings as they stream, finding exact bit-level matches across a sprawling archive, or piping data through a custom hash without ever pausing to fetch instructions from memory, an FPGA is arguably the more elegant approach. A dataset is sometimes only as legible as the software that reads it, and that software is only as runnable as the hardware underneath. An open FPGA design can preserve a faithful copy of obsolete circuitry, thereby preserving the means to read data, not just the data itself.
For an institution like the lab, that distinction matters. Libraries, archives, public-interest research groups, and smaller labs deal with workloads and questions that are awkwardly sized: too large for a laptop, too specialized to deserve a recurring cloud bill, too long-running for any one grant cycle. For a well-resourced lab, the answer is cloud GPUs. For everyone else, the answer has historically been to wait or to scale down the question. That is why open hardware matters here: it gives smaller institutions a path to specialized computing without waiting for ideal market conditions.
A $300 board on a desk can run a custom-designed circuit, tailored to one workload, indefinitely, without anyone’s permission and without a metered bill. A physical circuit sheds the overhead of an operating system and the constant fetch-and-exec cycle, drawing a fraction of the power of a standard CPU. For a public-interest lab, this efficiency makes running some workloads both financially and environmentally sustainable.
TPU-style architectures are particularly well-suited to this kind of work because of the systolic array at their core. A systolic array is a grid of small multiply-add units that pass partial results to their neighbors on every clock tick, making it efficient for matrix math because data flows through the grid rather than being fetched repeatedly from memory. That structure is designed for exactly the dense-matrix operations that underpin embedding generation, similarity search, and the neural network inference behind modern document analysis. This is the kind of regular, spatial structure FPGAs are built to host. A grid of identical small units, wired to their neighbors, all ticking together, is close to a literal description of what an FPGA’s fabric already is.
Designs published openly in SystemVerilog are reusable across institutions, as open code is. What has kept this out of reach was never the silicon; it was the labor: months of vendor-tool learning, a small group of knowledgeable practitioners, and debugging cycles unique to physical systems. That cost is what AI coding agents have started to chip away at, making the open-hardware case more practical.
Porting OpenTPU and the Silicon Boundary
OpenTPU is a published academic re-implementation of Google’s first-generation TPU implemented in Python code that models the hardware’s behavior, not software meant to run on it. The hardware target of this experiment was the Alchitry Pt v2, a roughly $300 board built on an Xilinx Artix-7 chip, with an add-on that exposes USB 3.0 to a host PC. I worked with AI coding agents to describe goals in plain English, review edits, and iterate. A sandbox repository came first: blink an LED, echo bytes, talk to the USB chip. That groundwork paid off within hours of starting the real port. The OpenTPU translation itself — the systolic matrix unit, the weight memory, the instruction decoder, the activation logic, and the host interface — went through seven planned phases. A few days of wall-clock time later, the SystemVerilog testbench ran the same matrix-multiply program as the original Python simulator and produced the same answer.
Source: Jenevieve Haggard, HLS LIL
Translating Python that describes hardware into SystemVerilog that synthesizes hardware turns out to be something AI agents are somewhat capable of. The source is unambiguous, and the testbenches give instant feedback. The hard part was always the silicon boundary: a physical board, a vendor toolchain with subtle caching behavior, a USB chip with several gotchas. What worked was a scaffold around the agent that provided deterministic simulation tests for everything testable in software, plus on-board LEDs wired to specific finite-state-machine states, so a human eye could see what the testbench could not. A small notes tool called “cq” (by Mozilla) recorded what each session learned and made future sessions read those notes first. By the end, the store held 48 entries, almost all painfully, expensively earned.
Performance Realities and the USB Latency Bottleneck
By the end, the FPGA produced output that matched a NumPy reference lane-for-lane on a 200-vector benchmark. End-to-end, it was about 2x faster than the original Python simulator; on compute alone, about 4x. It was also comfortably slower than a CPU running optimized BLAS on small inputs. The point of the result is not that the FPGA wins everywhere, but that it shows where open hardware can be useful.
At this workload size, USB round-trip latency dominates the FPGA’s time budget. FPGAs win when data is moved to the device once, stays there, and is processed many times. Tiny inputs in, tiny outputs out, on every call, is the worst case for this design. We are running the worst case since we’re just at the “make it work” stage. PCIe-attached FPGAs sit much closer to the CPU and avoid this bottleneck entirely; with batched workloads on that kind of board, the compute-side 4x advantage we already see should carry through to the end-to-end number. They’re the natural next step for any workload where the dev-board numbers are encouraging enough to justify the cost.
Open Hardware and the Lowered Cost of Specialization
The lab occasionally runs computations large enough to be uncomfortable: searches over case law corpora and analyses across millions of documents. A pattern for designing a small piece of custom hardware that does those tasks well is a real option for problems that do not fit on a laptop and do not deserve a cloud bill.
More than preservation, open hardware offers freedom of access and the power to control your own collections, your own work, and your own computing. That opens up questions we are only beginning to ask. As archival media like silica and DNA-based storage mature, could open hardware lower the cost or complexity of building the readers required for those formats? As AI model architectures keep shifting, could a reconfigurable board keep pace in a way fixed silicon can’t? FPGAs already take on inference tasks at places like CERN (see their FPGA Developers Forum), adapting to software advances with matching hardware; could FPGAs do the same for our tasks?
AI coding agents are reducing the cost of specialized work that used to require a dedicated team. Custom hardware has historically been among the most specialized. If a small library research lab can produce a working SystemVerilog port of a real architecture in a few weeks, the question of what else has quietly come into reach is suddenly much broader.
The author examines the migration of Indiana University Libraries’ interlibrary loan platform, ILLiad, from a locally-hosted server to OCLC hosting through the perspective of a new department head inheriting this critical technology decision. He explores how staffing changes, lost institutional knowledge, recurring system instability, and limited technical capacity prompted a reassessment of long-standing local practices. The piece outlines research, consortium consultation, approval processes, implementation challenges, authentication and workflow issues, and post-migration tradeoffs. Ultimately, the author offers practical guidance for new leaders tasked with managing inherited systems, vendor relationships, imperfect information, and strategic change in complex academic library environments.
While incarcerated students face many challenges when commencing higher education, a lack of access to the internet is a considerable barrier. This technological exclusion has implications for the delivery of course materials, most of which are offered only electronically. A project team from Curtin University Library sought to understand and address the challenges faced by incarcerated students in accessing library services, particularly ebooks and audiovisual content. It was found that restrictions related to contract terms, digital rights management, and copyright contribute to a reactive and uncertain situation for library services. This article outlines the state of the problem and offers possible pathways academic libraries can take to improve the state of information access for incarcerated students.
Countless research questions arise when investigating connections between library resource discovery and student success. Existing literature explores best practices of database description language and style, the usability of database A–Z lists, and library resource jargon. Academic libraries continue to grapple with these challenges in resource discovery, even as online searching behavior evolves and new research tools emerge. A research team at the University of Arizona Libraries builds on the literature by examining these topics with a focus on the impact of a user’s academic discipline, university affiliation (faculty, staff, or student), and research experience on their understanding of database terminology, resource content and applications, and A–Z list type filters. The authors conducted an environmental scan of library websites along with several usability tests to identify and reduce library and disciplinary jargon on their A–Z list to make databases more understandable and approachable to all users. This article presents the results of these assessments as a case study for exploring external and internal factors that impact users’ understanding and discovery of databases.
By April 2027 and 2028, institutions covered by Title II of the Americans with Disabilities Act are expected to be legally required to ensure that digital content created or used at the institution is accessible as defined by Web Content Accessibility Guidelines (WCAG) 2.1 Level AA. The new law strongly emphasizes accessibility of course materials—including PDFs. This case study demonstrates how an R2 academic library staff can enhance the accessibility of PDF course materials by improving the accessibility of electronic reserves (e-reserves) PDFs at Hunter College Library (HCL).
Processes described here can be adapted by other libraries. Supporting campuses’ work to make course readings accessible may be a natural role for academic libraries. Locating or procuring the best quality version of a text available to the institution is a critical task for which libraries are optimally equipped. Furthermore, when readings are available only in print format, libraries can create higher-quality scans than those typically produced when the task is left to individual faculty members.
HCL began improving the accessibility of e-reserves PDFs in 2020. This article shares the knowledge acquired, established processes, limitations, and future directions. The workflow comprises checking each e-reserves reading. For those deemed poor, we locate an HCL collection or open access copy, purchase a digital copy, or remediate. Remediation involves optical character recognition (OCR), fixing errors therein, correcting reading order, removing repetitive headers and footers, and tagging. Literature the authors found on libraries proactively correcting OCR and tagging PDFs—that is, preceding a user’s request—was sparse, with the exceptions of the University of Toronto and the University of Michigan. Literature about proactively doing so for e-reserves was even narrower. This case study is intended to help fill the gap.
This study evaluates the performance of four generative AI models—ChatGPT, DeepSeek, Gemini, and Copilot—in generating descriptive metadata for bibliographic resources. Models were tested on a small, diverse set of resources using four prompt types: a basic prompt, a basic prompt with an example, a detailed prompt referencing Resource Description and Access (RDA) guidelines, and a detailed prompt with an example. Results show that both detailed RDA guidance and the inclusion of sample outputs improved metadata quality, particularly in formatting and field structure. While DeepSeek and ChatGPT showed better performance on the tasks, all models displayed limitations in parsing and following the prompts, using descriptive metadata fields, analyzing subject headings, and assigning URIs. These findings suggest that while generative AI holds potential to assist in metadata creation, its current capabilities fall short of meeting cataloging standards without human review.
One of the generative artificial intelligence tools developed for use in libraries, including academic libraries, is the AI Primo Research Assistant. Of the 65 academic libraries in Poland, only 19 have access to software that supports this tool. In practice, only 9 libraries have implemented it (data from March 2025). For the purposes of this study, original research was conducted to assess the implementation status of the Primo Assistant in academic libraries in Poland. Two anonymous surveys were developed for this purpose and sent to libraries that had implemented the feature, as well as to those with the capability to run the Primo Assistant (i.e., the Primo VE Discovery admin role), in order to gather information on why they had chosen not to implement it. The analysis revealed several positive aspects, mainly a reduction in the workload of staff tasked with preparing publication lists on topics requested by library users. Some concerns were also raised by library employees, mainly regarding the reliability of the metadata provided and the accuracy of the recommended publications. The study also revealed a general lack of awareness and a need for further implementation. This paper presents the first scientific study focused on the implementation of the AI Primo Research Assistant in Polish academic libraries.
Effective information technology (IT) governance is essential for the University of Riau (UNRI) Library to achieve its research and educational objectives. This paper presents a qualitative pilot study investigating the library’s current IT governance processes, focusing on two COBIT 5 processes—DSS01 (Manage Operations) and DSS05 (Manage Security Services). These processes were selected in consultation with library and IT leadership due to their direct relevance to ensuring operational reliability and safeguarding the library’s information assets. COBIT 5 principles and capability models guide the assessment, emphasizing regulatory compliance, performance monitoring, and stakeholder collaboration. Using a detailed questionnaire and capability model, the study evaluates base practices and work products for DSS01 and DSS05. Results indicate varying proficiency levels, with DSS01 at level 0 and DSS05 at level 1, highlighting significant gaps between current and desired capability levels. Recommendations include implementing standard operating procedures, enhancing security measures, and optimizing resource management. In conclusion, the findings underscore the need for standardized processes, continuous monitoring, and alignment with established frameworks like COBIT 5. By addressing identified gaps and implementing recommended improvements, the UNRI Library can strengthen its IT governance, enhance operational efficiency, and better support its academic mission.
This study critically explores the transformative potential of human-computer interaction (HCI) in reimagining African public libraries as dynamic, user-centered, and culturally grounded spaces. Based on a literature review and comparative analysis of libraries across several African countries, the research investigates how HCI principles can enhance user engagement, usability, and inclusivity, particularly in multilingual, resource-constrained, and postcolonial contexts. The paper situates libraries as sociotechnical infrastructures that mediate between technology, local knowledge systems, and community needs, and argues for the importance of participatory and culturally responsive design approaches in library digitization efforts. The findings highlight significant gaps in current implementations of HCI within library services, including the lack of localized interfaces and limited user involvement in design processes. The study concludes by offering practical recommendations for integrating HCI into library development strategies and advocating for the co-creation of digital public spaces that reflect and empower Africa’s diverse knowledge ecologies. In doing so, the paper contributes to the growing discourse on decolonial approaches to technology and the future of public libraries in the digital age.
Writing has been light around here recently for a wonderful reason: our twins graduated from their respective colleges over the past month, and we have been in nearly nonstop revelry (and packing, and schlepping…). We are so fortunate to have two great kids; I’m super proud of them.
Speakers at our kids’ commencements, thankfully and remarkably, said little about artificial intelligence, but they did talk a lot about the complex circumstances and especially the psychology of this rising generation, and offered advice on how the graduating seniors should move forward in life given significant headwinds. I suppose it’s tempting to describe and analyze the troubles facing each graduating class, and provide sage guidance in response to the historical moment, but I’m not sure that my kids, their friends, and their generation overall are so very different from any other, or that any distinct advice is needed.
The Great Class of 2026 is, I’m afraid, just like every graduating class: happy and sad, confused and hopeful about the future, striving and procrastinating. Young adults, in other words. Sure, they seem to be impacted by new technology and our dreadful national politics and nerve-racking global challenges, but hasn’t it always been so? My college class graduated into a recession, the rise of the internet, the fall of the Berlin Wall, the chaotic end of the Soviet Union, and a messy war in the Middle East — all of these dominoes falling after a childhood in which we were fairly sure we would perish at any moment in a nuclear war. That was a lot to absorb! Back then, commencement speakers picked up on our anxiety, which had apparently morphed into excessive irony and a general lack of motivation, epitomized by the title and content of a Richard Linklater film: Slacker.
It may have taken some time, but we muddled through. So did the generation another turn of the clock back from ours (Vietnam, stagflation, etc.) and the generations before that (pick your World War and/or the Great Depression, etc.). History is, unfortunately, a procession of horrible developments, but also a showcase of astonishing resilience and creativity. Is it so Pollyannaish to simply say that Gen Z will also find a way forward, and frankly might be better off without pithy advice from the olds? Must we unconsciously mimic the opening of Woody Allen’s fictional commencement address, raising the graduating class’s blood pressure by declaring, “More than at any other time in history, mankind faces a crossroads. One path leads to despair and utter hopelessness. The other, to total extinction. Let us pray we have the wisdom to choose correctly”?
Instead, I saw hope in every joyful row of begowned seniors, students who, despite all of the radical changes and stressful tensions around them, had nevertheless maintained their curiosity and maybe even cultivated a passion during college. Students who found their special niche in music, writing, art, or science, who felt compelled to listen to it all, read it all, see it all, or experiment late into the night, regardless of the requirements of the classroom. I have a feeling that this kind of deep and abiding engagement, born not from careerism but from genuine profound interest, will serve these graduates well in the years ahead. As it always has.
Books I Have Not Written
The class-action lawsuit of authors against Anthropic and its subsequent settlement have helpfully informed me of the many, many other writers named Daniel Cohen, because the settlement administrators, in their quest to match authors and texts, have sent emails and letters asking if I am the Dan Cohen who wrote this or that book. There are too many volumes by The Daniel Cohens to list in full here, but as a public service to a handful of special fellow Dans, I hereby declare:
I am not the Daniel Cohen who wrote The Monsters of Star Trek, but I would wager 100 quatloos on Triskelion that I would greatly enjoy meeting that Dan Cohen.
I am #$%@# mad I am not the Daniel Cohen who penned Famous Curses, because my family is on a mission to bring back the useful exclamation “Gordon Bennett!”
I did not write Southern Fried Rat and Other Gruesome Tales, but, based on the delightful cover of this not-me Daniel Cohen book, I probably read it at camp the year it was published.
My final confession: The settlement administrators believe there is a Daniel Cohen who authored a book titled Final Confession, but, alas, I am not the one.
English Edition: floppy disks, hard drives, CDs, DVDs, SSD drives - no
matter what you choose to store your data on - ultimately they all
decay. With my guests Callum McKean, Leontien Talboom and Adrian
Page-Mitchell, we’re going to talk about what kinds of data we find on
old drives, why we want to get them in the first place, and what can go
wrong with the storage media. To all of you who love all things retro -
we’ll be talking about floppy disks a bit.
I run a RAG application for Italian pension and tax consultants. Users
ask questions about INPS, professional pension funds, laws and
regulations, and the app answers using a knowledge base of uploaded
documents.
For a long time the app used the classic single-shot RAG pipeline: take
the question, search the database, stuff the results into a system
prompt, ask the model. It works, but it has a hard limit: the retrieval
happens once, before the model has any chance to reason about the
question. If the first search misses, the answer is bad and there is
nothing the model can do about it.
So I rebuilt the pipeline as an agent. Now the model drives the
retrieval itself: it decides what to search, reads the results, searches
again with different terms, follows cross references between documents,
and only then writes the answer. All in plain Ruby, with RubyLLM and
Rails. No LangChain, no Python sidecar.
In this article I will show you exactly how it works, with the real code
from my application. One note before we start: since the app serves
Italian consultants, all the prompts, tool descriptions and user-facing
strings are in Italian in the real codebase. I translated them to
English here so you can follow along, but the structure is identical.
Wikimedia and GLAM institutions share a challenge. How do we make
cultural heritage collections accessible at scale without sacrificing
quality, provenance, sustainability, or community control? The
International Image Interoperability Framework, IIIF, is now used by
thousands of institutions to serve high-resolution media through open
standards. Wikimedia does not currently integrate IIIF in its core
architecture. Should it?
Since 2023, Montgomery Planning staff have been working on the Eastern
Silver Spring Communities Plan, drafting recommendations on zoning and
land use, transportation, housing, parks and the environment, economic
development and urban design. The plan is expected to set a vision for
the area’s future development for decades to come. The plan is bordered
by Colesville Road, University Boulevard and New Hampshire Avenue and
will include three future Purple Line stations, the Piney Branch Road,
Long Branch and Manchester Place
Design is broken. Young and not-so-young designers are becoming
increasingly aware of this. Many feel impotent: they were told they had
the tools to make the world a better place, but instead the world takes
its toll on them. Beyond a haze of hype and bold claims lies a barren
land of self-doubt and impostor syndrome. Although these ‘feels’ might
be the Millennial norm, design culture reinforces them. In conferences
we learn that “with great power comes great responsibility” but, when it
comes to real-life clients, all they ask is to “make the logo bigger.”
On our strictest tests, Gemini 3 achieved a CER of 1.67% and a WER of
4.42%. On these tests, any difference between the ground truth and test
texts counts as an error. WER is thus almost always a bit more than
double the CER because if a single character in a word is wrong,
including leading or trailing punctuation like commas, single quotes vs
double quotes, etc, the whole word is marked as an error. On this
measure, Gemini 3 performs nearly 50% better than the best, fine-tuned
specialized models and achieved performance comparable to an early
career, professional human typist.
FacilMap is a privacy-friendly, open-source versatile online map that
combines different services based on OpenStreetMap. FacilMap offers the
following features:
Show different map styles, for example maps optimized for driving,
cycling, hiking or showing the topography or public transportation
networks.
Search for places
Show amenities and POIs
Calculate a route, optionally showing the elevation profile.
Find out what is at a particular point on the map
Open geographic files, for example GPX, KML or GeoJSON files
Show your location on the map
Share a link to a particular view of the map.
Add FacilMap as an app to your device.
Change the language settings in the user preferences.
FacilMap is privacy-friendly and does not track you
SQL makes sense. But when it breaks, you reach for EXPLAIN. Vector
search offers no such comfort. Multi-thousand-dimension embeddings,
approximate nearest-neighbour indexes, and quantisation tradeoffs make
it hard to know what your system is doing, and harder still to diagnose
when results quietly degrade. Through interactive visualisations, Simon
Hearne shows what embeddings look like in high-dimensional space, what
quantisation does to your recall, and how to catch retrieval failures
before your agents do. You’ll leave with a sharper mental model and a
diagnostic toolkit for the production problems hardest to see.
Once again I am reminded that modern web tech is amazing, and web
browsers are incredibly capable.
There’s a Screen Capture API to record the screen. You can select a tab,
a window, or the entire screen. The feature has limited browser support
so I don’t think I’d use it in a big web app, but it’s fine for a
one-off screen recording. (I wonder how browser-based video conference
apps like Google Meet do screen sharing? Do they use this API, or do
they use something with wider support?)
TL;DR if you have a TASCAM 788 backup and don’t know how to get the
audio out of it this
script might help. Also: AI tools work best when paired with
expertise.
I needed to take a very personal excursion into digital preservation
recently as I attempted to listen to some audio recordings my brother
John had made about 20 years ago. John died recently,
and is sorely missed by his friends and family.
John was a continuous source of inspiration for me, because of his many
varied interests and projects. One thing he did consistently since he
was a teenager was perform music as a singer-songwriter.
As my family and I went through the very difficult process of emptying
his apartment, we discovered a set of recordings he had made on CD-R.
Three of these CDs were clearly conceived of as albums, and easily
mounted as CDDA
when I popped them in my CD player.
However he also left a binder of CD-Rs, where each CD was neatly labeled
with a song title and a year. All in all there are 108 of them, from the
2003-2008 time period. There is a lot of material on these CDs that is
not present on the three albums. However, when I popped these in my CD
player all I saw was a macOS error dialog box saying:
The disk you attached was not readable by this computer.
John’s binder of CD-Rs
At first I thought they might be damaged or corrupted. But it seemed
unlikely that so many of them would be. After some asking around I got
pointed to two excellent guides to working with CDs:
These guides were great, and did help me extract the raw data from the
CD-R with cdrdao, but
ultimately I was unable to determine what format the data was in using
tools, like file, Siegfried and Droid.
In a fit of desperation I spent some time in Claude Code trying to see
if it could help me identify what format the data was in. Despite
several forays, it kept going round in circles, burning tokens.
One of those forays led me on a wild goose chase installing an old
version of macOS in order to see if an old version of Retrospect
might be able to read the CDs (it didn’t).
During this time I got some excellent advice over in the Fediverse at
digipres.club. One of
those messages was from Ross Spencer who took a look
at a sample raw CD image. He was able to spot some markers that pointed
to it possibly being a backup from a TASCAM DAW,
specifically a TASCAM 788. Ross
wrote up more
details about his process, which highlights how important knowledge,
skill, documentation and web search are to this type of work.
TASCAM 788
Unfortunately, after poking around in various user forums, I discovered
that there were not really any tools for working with TASCAM 788
backups. Everyone seemed to be recommending the purchase of a TASCAM 788
and its CD Burner, since the data was in a proprietary format, and there
were no emulators.
Before dropping some money on Ebay I decided to roll the dice with
Claude Code again, but this time with the more specific
guidance that this was likely a TASCAM 788 backup, and asking about
options for recovery. If you are interested you can read the
transcript for this session. The key part of the back and forth for
me was:
The 2488 stores audio as raw 16-bit or 24-bit PCM at 44.1kHz in a
proprietary block structure. Once you identify the byte offset where
audio data starts, you can use Audacity’s “Import Raw Data” with 24-bit
signed big-endian PCM, 44.1kHz, to listen and verify.
I prompted it to try to identify the offset, so I could attempt the
import in Audacity. It did some work writing Python snippets and
executing them for a few minutes, and then output a likely offset. The
first time I read it in I only heard white noise. But after twiddling
some of the import options in Audacity I saw some promising waveforms
appear in the Audacity display. And when I pressed play ✨✨✨✨ instead
of white noise I heard John’s guitar and voice!
Audacity screenshot of imported raw data
What appeared to be a single track turned out to be multiple tracks
created with the TASCAM, that were joined together. The final segment
was the completed mix.
I continued to work with Claude on a program that would identify the
offset in the raw CD data, then extract a WAV file, and then extract the
separate tracks, as well as the complete track. It did this by looking
for gaps inside the audio. I put the program here:
Here is the guitar / vocal first track (there are a few seconds of
silence at the beginning):
And here is the mix including percussion and keyboards:
These recordings are Copyright John Summers CC-BY-NC
I have since been able to find John’s TASCAM 788 at my brother Matt’s
house–although it doesn’t have the SCSI external CD burner anymore. So
there’s no way to read the CDs with it.
These CDs and songs are important enough to me that I want to see if the
actual hardware can do a better job of preserving John’s work. So I’ve
got a bid one of the external CD-Recorder devices I found on Ebay.
John clearly spent a lot of time and care taking a snapshot of these
songs he used to perform in coffee shops around Bucks County
Pennsylvania. I plan to release some of them on his Bandcamp, with some
of his artworks as album covers. I want to share them with people who
knew him, and put these songs out into the world in a way that respects
his memory and creative work, while also being something that he just
wasn’t focused on as an artist. For John it was the creative process
itself that mattered most.
None of this will bring John back of course. He’s gone now, and at
peace. But he will always be remembered by those who loved him. Look for
more posts here after I’ve been able to extract these songs in total.
If you manage to have most of your input tokens be cached, you save a huge amount, in this case $0.20 per million tokens. What does this mean though? What does caching do that makes you save so much, in some cases upwards of tens of kilodollars?
Someone explain the cached vs not thing to me for how this is $10,000
worth of savings lol
I'm gonna be totally honest, I barely understand the basic outline of the math
involved here. Where possible I am to not be completely wrong here, but I'm
not going to emit something 1:1 accurate with the mathematical truth of large
language models' inner workings. Bear with me.
When you make an API call to large language model services, you make an API call like the following:
curl http://localhost:11434/api/chat -d'{
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "why is the sky blue?"
}
]
}'
That messages element is the key bit. Every time you accumulate messages from the initial system prompt, initial user request, AI responses and any tool use requests/responses, you add to that array and make it grow bigger and bigger.
A good way to think about this is that sending a conversation to a large language model is like having a pair of people share a roll of paper on two different typewriters. Every time you finish your message, you send the roll of paper back to the AI model and it has to re-read through the entire conversation in order to start typing on the end with its response. As the conversation gets longer, this gets more and more expensive because the model has to recalculate its internal state all over again for every additional message.
However, large language model inference is complicated but deterministic. Given the same inputs, you will always get the same output. This means that you can use a technique called key-value caching (KV caching) in order to save that intermediate state and use it for next time. Most of the time this cache is a prefix cache because that allows you to just add on more messages to the end of the request pretty easily and be fine.
Imagine something like this:
curl http://localhost:11434/api/chat -d'{
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "why is the sky blue?"
},
{
"role": "assistant",
"content": "The sky is blue because of a phenomenon..."
},
{
"role": "user",
"content": "But I am looking outside right now and it is orange!"
}
]
}'
If the model has already processed the question about the sky being blue and generated the response about Rayleigh scattering, it doesn't need to process both of those messages again to answer the user's question about sunsets. In production AI model deployments you would put that generated intermediate state into the KV cache so that the model doesn't need to run twice for the same data. This saves time and effort on the side of the AI model provider, and currently model providers decide to pass that savings onto API users in the form of cheaper inference costs for cached lookups.
As you develop an application with AI in it, try to avoid changing any inference settings or previous messages between prompts. This makes your application's queries much more likely to read from the cache, making it faster, reducing the environmental impact, and saving you(r users) money.
This is the first installment of a three-part series on global library leadership engagement, contributed by Ellen Hartman, OCLC Leaders Council Manager. We’re grateful to Ellen for sharing her perspectives on this topic.
Proof we engaged face to face
At a recent gathering of the OCLC Leaders Council, something happened that I always hope for but never take for granted. Connections were being made, there was laughter, sidebar conversations over lunch and dinner, and a willingness to challenge each other’s ideas, honesty about what people were struggling with, and genuine curiosity about what others are doing. All of this was built on a foundation of trust that made these in-depth conversations possible.
These moments don’t happen automatically. In my experience, they take time—and often, the opportunity to meet in person. Meeting online can be very efficient, but it can feel rushed and impersonal—it’s hard to truly get to know each other through a screen. Being in the room together over the course of a few days, in a small enough group that you actually get to speak to everyone, creates a solid foundation for future opportunities to meet again, online or in person, to build on the connections, themes, and conversations that started there.
What made this gathering particularly significant was its global dimension. Library leaders do come together regularly, but often within their own region, or among peers from the same library type. Academic and public library leaders, for instance, don’t always get the opportunity to meet for in-depth conversation, even though there is much they can learn from each other. Conversations organized by library type or region have real value, of course, but there is something additional that comes with a broader perspective that is still rooted in the library ecosystem while extending beyond your usual network. Every perspective in the room adds something, regardless of what an institution has or hasn’t yet achieved. The value of these conversations comes from the range of experiences present.
Across international leadership spaces, a remarkably consistent vocabulary tends to surface. Terms recur across sessions, regions, and formats, and their repetition signals that we are all on the same page: a reassurance that participants are engaged with the same broad challenges and moving in a broadly similar direction.
The problem is that shared language doesn’t necessarily mean a shared understanding or a shared reality. One of the things that becomes apparent, watching these conversations unfold, is how often the same word lands differently depending on who is in the room.
Take efficiency, a term that surfaces regularly in conversations about how libraries operate and plan strategically. In some contexts, efficiency encompasses decisions about workforce size and structure. In others, those decisions are shaped by employment frameworks that lead to a very different kind of conversation, shifting the focus instead toward technology, software, or finding different ways of working within existing structures. The word is the same. The need it describes, and the range of solutions available, are not. This is why you need a deeper understanding of each other’s context to find out where you are using the same words but aren’t speaking the same language.
Glimpses, not full pictures
Even with that understanding in place, international leadership conversations can only ever offer glimpses of each other’s reality rather than the full picture. You see enough of someone else’s context to recognize the challenge, but rarely enough to understand all the constraints behind it.
This matters because those constraints are often what make the difference. Take something many library leaders struggle with: making the case for their library’s value to the broader institution or community they serve (for more on this topic, see OCLC Research’s latest report!). Some leaders have, through long-term effort and considerable perseverance, managed to position the library as visibly central to their institution’s priorities and a key part of its success. For others, making that same case remains difficult. The reasons could be structural or personal: the physical or organizational distance between the library and the part of the institution that makes key decisions, the data available to demonstrate the library’s impact, or the library leader’s own position, voice, and access to the right conversations at the right time.
In international settings, what tends to surface is the success story. What is harder to showcase is the full path to that success. The years of lobbying, the hundreds of stakeholder conversations, the incremental steps that made this outcome possible. A leader who has achieved that recognition may share what they did in good faith and genuinely want to help others reach the same goal. But because the conditions that made their success possible are often invisible in how the story gets told, it can be hard for them to understand why the same challenge feels insurmountable to a peer.
The value outside of the program
International leadership meetings are often evaluated by what happens in the formal program. But some of the most valuable exchanges happen elsewhere. Recognizing that is part of understanding how these spaces work in practice.
In smaller gatherings, it’s the time outside the formal agenda where a lot of the magic happens. When a group of library leaders meet for the first time, they are still in the process of getting to know one another. This is why you can’t expect them to immediately share their biggest challenges or most acute pain points. There is a measure of trust building that happens as a gathering takes place, especially over multiple days. It’s often after the official program ends, and there is room for leaders to relax and reflect together (for example, during dinner or at the bar) that the more personal and complex topics get discussed.
That kind of conversation requires enough prior exchanges that people feel safe being a little vulnerable. Admitting that your library is struggling to secure its position, or that you haven’t found a way to make your value proposition tangible enough to institutional leadership or other stakeholders that control funding, is not something most people are willing to do in a room full of peers they’ve just met. It becomes possible when the group has had time to become something more than a collection of strangers.
This is one of the reasons smaller, sustained gatherings tend to produce a different quality of exchange than large conferences. It is also why the informal spaces within those gatherings deserve to be nurtured rather than left entirely to chance.
No neat resolutions needed
One expectation worth setting aside is that international leadership conversations should resolve into clear conclusions. They rarely do, and that is not a failure.
Conversations like these do not need to end in consensus or a neat step-by-step path forward. It’s often the process of sharing and reflecting on both differences and commonalities that provides the greatest benefit. It might be an idea you hear and want to incorporate in your own library. A perspective that’s truly new to you and makes you see a topic in a different way. Or simply the opportunity to take a subject that was discussed at surface level and deepen the conversation in future gatherings.
That is why continued engagement matters more than resolution. Understanding accumulates across multiple conversations, multiple gatherings, and sometimes multiple years. It cannot be compressed into a single meeting, however well designed. The friction and the moments of genuine surprise are part of the value. Smoothing those moments away or rushing toward consensus risks losing exactly what makes international exchange worthwhile.
Conclusion
International leadership spaces are often judged by the ideas they surface or the alignment they appear to produce. But their deeper value lies in the glimpses they offer into realities that are different from our own. Those glimpses don’t tell the full story of what other library leaders are experiencing, but taken together, they help form a better understanding of what experiences are out there.
When designed well and when opportunities for informal interactions are cultivated, global library leadership spaces create the conditions for the kinds of conversations that go deepest. Those conversations rarely happen on the agenda, but rather emerge when enough trust has been built that people are willing to be open and candid with one another. That is not something that happens automatically: it requires continued investment in bringing people together, and repeated exposure to each other’s contexts, experiences, and points of view over time. Trust is not built overnight.
The next post in this series takes a closer look at what global engagement actually involves beyond the conversation itself and why showing up, in every sense of the phrase, costs more for some than others.
I have a problem with RSS. Not RSS itself, RSS is great!
The problem is that I subscribe to more feeds than I can possibly read,
so the unread count in FreshRSS climbs faster than I can bring
it down. Some days I skim titles, declare bankruptcy, and mark
everything as read. Other days I let it pile up and feel guilty.
I’ve tried to using newer tools like Current which was
definitely an improvement, but still didn’t quite do it. My friend Dan
has been working
on a new RSS tool that works a bit like a personal newspaper, that seems
like it could be extremely helpful, and I’m keeping my eye on it. But
meanwhile the list of unread posts grows…
Now, I’ve been very reluctant and slow to introduce LLMs into my daily
work. But even from under my rock, in a cave, down by the river, I’ve
heard that LLMs are good at text summarization.
I thought maybe, just maybe, I could try using one to summarize
my unread posts? It seemed like a good fit for an experiment since the
impact of getting things wrong is basically zero (in theory).
I wanted to try routing my unread RSS posts through an LLM to get a
daily digest. From under my rock I’d also heard about
Model-Context-Protocol (MCP),
and how it is going to change everything. So I thought it would
be a good exercise in seeing how that works in practice with a tool like
Claude Code. I’d use Claude Code’s MCP support to connect directly to
FreshRSS and ask Claude to summarize what I’d missed. Yeah, that’s the
ticket.
This is the Way?
The first thing I tried was ChrisLAS’s
freshrss-mcp server, which wraps the FreshRSS GReader API and exposes
it as a set of MCP tools. The idea is that you drop it into your Claude
configuration and Claude can then call those tools to fetch and read
your articles.
I gave it a try, and it worked! But the results were… mixed. Claude
would usually fetch articles. But then it would produce a lot of
diagnostic chatter alongside the actual summary: narrating its own tool
calls, noting what it was about to do, explaining why it was skipping
certain things, asking for permission for this and that.
And more frustratingly, it would sometimes take strange detours:
executing inline Python code, and Unix tools to do things it could have
done by calling the MCP tools more directly, wandering into unnecessary
computation. The experience felt noisy and unpredictable, and (frankly)
just a bit scary.
I started by creating some “skills” and some scripts for those skills
thinking it would make things a bit more deterministic. It kinda did?
I thought maybe my problem was that the skills weren’t bundled together,
so I built my own plugin: freshrss-claude. This
version bundled the MCP server as a Claude Code plugin with a set of
“skills”, the structured prompts to guide Claude through fetching and
summarizing in a more controlled way.
It seemed better? Not needing to start the MCP server was definitely
better. But ultimately it wasn’t as big an improvement as I’d hoped for.
Claude still exhibited strange behaviors: writing and executing Python
scripts unnecessarily, going off-script in ways that were hard to
anticipate. The summaries themselves were fine when they arrived, but
the path to getting them there was erratic and unpredictable.
The last straw for me was the idea of running this Rube Goldberg machine
from a cron job to generate the summary for me automatically. To run it
automatically I needed to grant it all kinds of permissions to ensure it
ran through. This scared the shit out of me, given it was giving it
permission to run arbitrary Python programs and reach out to the web,
and interact with the filesystem. Running it once or twice manually was
ok. But sticking it in my crontab and forgetting about it? Forget about
it. I exprerimented briefly with putting things in a Docker container,
and Claude Cowork’s sandboxing, but then…
Turning it inside out
I stepped back and rethought the problem. The thing I’d been trying to
do, have an LLM orchestrate a set of tools to accomplish a task, is one
(seemingly popular) way to use an LLM. But it turns out to be kinda
demented. You’re asking the model to plan, to sequence, to decide.
You are asking it to be An Agent. Sure models can do this, but they are
not reliable in the way a simple program is. They wander. They
improvise. They sometimes decide to take a detour. Do I really benefit
from this runtime model in this little RSS digest app? Nah, not really.
So the alternative, and this is the inversion that made things click for
me, is to write a deterministic program that calls the LLM as a
component, rather than letting the LLM drive the program as an Agent. My
code fetches the articles. My code shapes the prompt. My code writes the
output to a file. The LLM does exactly one thing: it reads the content I
hand it and produces a summary.
Take Two (or Three, or Four?)
I threw it all on the fire and started over by writing rss-digest instead. Well,
truth be told, Claude and I wrote it. Ok, ok, mostly Claude.
It’s a small Python CLI that connects to any GReader API-compatible
RSS reader (FreshRSS, Miniflux, Tiny Tiny RSS, The Old Reader), fetches
your recent unread articles, and asks an LLM to produce a digest.
Because it uses LiteLLM under the
hood, you can point it at any compatible model: OpenAI, a local model
running in LM Studio, whatever you prefer.
The output is a Markdown file (or HTML with –html). I have
a cron job run it in the morning and drop a file on my desktop for me to
read. Here’s an example
of what it looks like.
For smaller batches (≤25 articles) it gives you a structured list. For
larger ones it produces a curated prose summary grouped by theme. You
can pass a custom system prompt file if you want to tune the style or
grouping. You can pass –mark-read if you want it to mark
everything as read afterward.
The tool is on PyPI and the code is on
GitHub. I’ve just
started using it, so it quite possibly has problems. The prompt that is
used for doing the summarization is configurable. If you have a
different take on the prompt or want to extend it, please send me a pull
request so I can add it as an alternative.
So…
What I keep coming back to is the design lesson underneath all of this.
There’s real value in being thoughtful about which part of your
system is deterministic and which part is probabilistic. There’s no
doubt that LLMs are magical things, but it’s not a reliable program. It
shouldn’t always be the thing making decisions about what to fetch, when
to stop, or how to structure output. Hand it a well-formed input, ask it
a clear question, and (hopefully) it will return something useful.
Everything else, the plumbing, the sequencing, the file I/O stays in
your code that you can look at, and test and run directly.
I’m not saying all programs using LLMs need to take this approach. I’m
just saying maybe you don’t need MCP, Agentic AI, etc, etc all the time.
Experiment with it, but don’t forget to turn it inside out when you need
to.
Once again I attended most of the library of Congress' Designing Storage Architectures workshop remotely. I apologize for the delay in posting this; domestic duties have kept me very busy recently. Below the fold notes on the talks that caught my attention, based on my now somewhat memory and the slide decks for the talks from the Library of Congress website.
As usual, IBM's Georg Lauhoff provided an invaluable overview of the storage industry as of late 2025, co-authored with Sassan Shahidi. They make an important point that I have been making since at least 2018's Archival Media: Not a Good Business:
Challenges of Alternative Archival Technologies
• Alternative archival technologies face technical and economic hurdles.
This justifies their focus on flash, hard disk and tape. Their "exabytes shipped" graph shows that indeed Hard Disk Unexpectedly Not Dead; the dramatic decline in HDD's share since 2008 reversed in 2024.
The key metric for technological progress in traditional storage media is areal density:
Lauhoff and Shahidi's graph shows that tape, which has the easiest path because of the relatively large size of the bits, has continued its steady growth, although one could argue both that their 24% annual growth exaggerates the period since 2017, and that INSIC's projection of 28% is optimistic.
It is clear that HDD areal density progress slowed dramatically about 2010 to around 11% per year. But the developments Jon Trantham reported, see the next section, could lead to a significant acceleration in HDD areal density.
Flash has continued a steady 30% per year growth since about 2010, thanks to stacking cells vertically and storing multiple bits in them. Both of these have limits, into which the industry will eventually run.
As regards the relative cost per TB of the three media, the big picture is that since around 2010 change has been very gradual. Tape and flash have both become cheaper relative to HDD, but the rate of change has been much lower than predicted.
Lauhoff and Shahidi conclude that:
Tape Storage: continues to evolve.
HDD: improvements slow down but recently high demand.
NAND: well-suited for hot storage but not for archival purposes.
Lack of Alternatives: Within the foreseeable future (within 10 years), there are no viable alternatives to Tape, HDD, and NAND storage.
AI leads to storage demands across the tiers
This last point was a theme for the entire meeting. But it is important to note that the meeting was too early to capture the full impact of AI on the cost and availability of media and systems.
He also announced that they have started to ship their 40TB HAMR drives. Their roadmap to 100TB/drive presents some significant challenges, as shown in Trantham's slide. The history of HAMR shows that Seagate can surmount major technical challenges, but it may take longer than they project.
One of Trantham's slides vividly illustrated the technology challenges the HDD industry faces, showing to scale to evolution since 1997 of the sizes of the bits on the media, the reader, and the writer. Note the 1610-fold decrease in the area of the writer, the 305-fold decrease in the area of the bit, and the 289-fold decrease in the area of the reader.
Fifteen years ago, Ethan Miller, Ian Adams and I published Using Storage Class Memory for Archives with DAWN, a Durable Array of Wimpy Nodes. It was inspired by work at Carnegie-Mellon from 2009, FAWN: a fast array of wimpy nodes, which argued that implementing fast storage using large numbers of small nodes built from cell-phone technology could save two orders of magnitude in energy per query. We argued that it would be possible to build low cost, low energy archival storage systems using a similar approach.
Our idea was ignored, but at this meeting Ethan Miller revived the idea of using flash as an archival medium. He argues for a rack-scale system storing 500PB/rack built from 5U shelves, similar to Backblaze's, each holding 216 of Pure Storage's 300TB DFMs (direct flash modules) stacked vertically.
There are three big challenges:
First, if all the DFMs were actively I/O-ing the rack would draw 45KW. Supplying the rack with that much power and cooling it would be very difficult (see the design of Nvidia's racks). But, just as with Facebook's hard disk cold storage, this can be mitigated by scheduling accesses so that only a small proportion of the drives are active.
Second, flash cells gradually leak electrons, so must be regularly refreshed by reading and re-writing them. This task must be scheduled along with the application's reads and writes, but doing so is fairly easy since the refresh timing isn't critical.
Third, flash is more expensive per TB than hard disk or tape. As I have argued for a long time, in the archival storage market the time value of money makes it difficult to justify trading increased capex for decreased opex:
The opex savings are significant, with essentially no mechanical failures, more benign failure modes, and much higher bandwidth for erasure code recovery.
Miller argues that the capex isn't as bad as the cost of the media makes it look, because at 0.5EB/rack there are savings in space, power and cooling. He doesn't point out that the lower latency for read access potentially allows for the elimination of an entire warm layer of the storage hierarchy.
But he acknowledges that AI is driving up the media cost. This is probably only relative to tape, since hard drive prices are also skyrocketing.
Miller argues that, over time, flash costs will come down. The scope for further shrinkage of the cells, and the addition of more layers, is limited. Once that happens the fabs that manufacture flash will gradually fall behind the leading edge and become depreciated.
Although I'm naturally biassed, I think Miller's case for archival flash is worth a detailed investigation.
Fourteen years ago in Cloud vs. Local Storage Costs and More on Glacier Pricing I started writing about the way the complex and somewhat opaque pricing models of cloud storage platforms made it difficult to estimate how much you would end up paying. People are just now figuring out that AI has the same problem. Neither is an accident; these pricing models serve two goals important for the platform's business model. First, the purchase decision is based on the "Low, Low" advertised price. Second, once you discover how much more you're actually paying, you face the lock-in created by egress fees. In 2019's Cloud for Presevation I wrote about how egress charges implement vendor lock-in.
David Boland of Wasabi presented a current analysis of this issue. He reports that about half of all the organizations they surveyed exceeded their budget for public cloud storage.
The budget overruns were caused by the fact that the actual spend was about double the sticker price for the storage. Fees were the culprit, which by design are much harder to project.
Using AMAzon's cloud services for long-term preservation always suffered from the fact that, to confirm the fixity of the preserved content, it had to be read and thus incur fees. Finally, two advances have improved things. First, it is now possible to use SHA-256 and SHA-512 schecksums when uploading data. Second, it is now possible to use an S3 batch job to validate the checksums on objects without reading them.
AI is one of those generational tech topics that isn’t going away soon. But the signal to noise (or hype to reality) ratio can be truly overwhelming. There are just so many links, opinions, new resources that are getting lost in the mix. And that’s for us information and tech nerds – we can only [...]
In the Spring 2026 semester at Old Dominion University (ODU), I taught CS 450 (Undergrad) / CS 550 (Graduate): Database Concepts. The course was fully online, with synchronous live Zoom sessions held twice a week. The attendance was not mandatory but strongly encouraged. All lectures were recorded and made available for students to access whenever needed.
Figure 1: Canvas course page for CS 450/550: Database Concepts
Through this blog post, I want to share my experience of teaching a senior-level undergraduate/graduate course for the first time, the behind-the-scenes realities of course preparation through to the end of the course, and how student feedback actively shaped the course as it progressed.
Since the course had been taught previously by other instructors, materials were already available, which made things easier. Rather than building everything from scratch, I started by copying over the existing course structure and then carefully updating it to align with the current semester. The more time-consuming part was setting everything up, cleaning up the Canvas course, especially updating deadlines and revising the syllabus, while ensuring the topics were properly aligned with assignment deadlines. If you are instructing for the first time, it is very important to make sure you get access to the course in time, so you can set everything up without a rush. Throughout the semester, to make the most of class time, I spent a couple of hours before each session preparing things such as reviewing material, planning examples, and thinking through how topics would connect. I tried to debug issues during the class in real time whenever possible. If something took longer than expected, I pushed it to the end of class or moved it to the office hours. It helped me to continue the flow of the topic without interruptions.
I was able to experience first hand how handling a class of 50 students without a teaching assistant (TA) was, honestly, a lot more work than I expected. Grading labs, homework, quizzes, and discussions while also preparing for lectures and responding to emails required a constant balance. I wasn’t always perfect, but I made a steady effort to stay on top of it. Grades were returned as quickly as I could manage, and emails were typically answered within 24 hours, often sooner. Again, it reinforced something I had already noticed as a student: timeliness matters. Things do not have to be instant, but when there is a clear effort to respond and follow through, it builds trust and keeps students engaged.
One of the first challenges I faced as an instructor to this course involved managing classroom dynamics. After a few classes, a student shared a concern that some well-intentioned peer engagement (jumping in to answer questions or adding explanations during lecture) was becoming distracting to follow along. It was a fair concern, and an important one. At the same time, I didn’t want to discourage participation. Active engagement is something every instructor hopes for, and it was clear that students were eager to contribute. My challenge was to find the right balance. I responded by acknowledging the concern and assuring the student that I would make adjustments so that participation remained helpful rather than overwhelming. Before taking action, I also reached out to a mentor for advice, which helped me approach the situation more thoughtfully. I thanked students for being engaged and willing to contribute, but also clarified expectations: participation was welcome, but lectures and question answering would be primarily instructor-led, with designated moments for peer discussion. I also reflected on something I had noticed during the class introductions: students were coming from a wide range of backgrounds. Some had prior experience with databases, while others were encountering these concepts for the first time. Because of that, maintaining a consistent pace and structure was important. I believe that framing it this way helped convey the message to the students that my goal is not to limit participation but to support a better learning environment for all. There were no further concerns raised afterwards and the students remained engaged while being supportive of the entire class.
Midway through the semester, I conducted an anonymous check-in survey to better understand how students were experiencing the course. To encourage participation, I offered a small amount of extra credit, which resulted in a strong response rate.
Overall, the feedback was encouraging, most students agreed or strongly agreed that assignments were clear, the workload was manageable, and the pace was appropriate (Figure 3). But what mattered more were the written responses. They highlighted patterns that helped me see the course from the students’ perspective (full set of responses).
A few consistent concerns stood out:
Some students said they weren’t always sure what to prepare before class or whether a session would lean more toward lecture or lab. That feedback pushed me to be more specific in my announcements, clearly laying out what each class would cover.
Several students pointed out that while their answers were marked incorrect or partially correct, the reasoning behind it wasn’t always clear. This was a fair point, and a difficult balance when grading at scale. Still, I made a more conscious effort to leave clearer comments.
Even when students understood the concepts, many struggled to translate them into SQL queries or ER diagrams. That reinforced something I kept coming back to: the need for more in-class examples and live coding, which I continued to prioritize.
Interestingly, a lot of students said the challenge wasn’t the material itself, but managing their time. A few students shared situations where missing a single assignment significantly impacted their grade. This feedback later influenced my decision to allow requests for reopening missed work.
At the same time, there were plenty of positive notes that helped confirm what was working:
Students consistently appreciated the clarity of explanations and examples.
The labs and live coding sessions were frequently mentioned as highlights.
Many felt the course structure was organized and manageable.
Some even described it as one of the best online courses they had taken.
I also asked students a simple question: what’s one thing I should keep doing, and one thing I could do better? Here are some of the responses that stood out:
“The instructor is great. Instructions are clear, vibes are good, I would recommend this class. The homework is work intensive but not unreasonable.”
“You have been doing a great job and this has been one of the best online courses I have taken at ODU”
“very good at explaining things, even when the students dont seem to get something she fines a new way of explaining it so they get it.”
“The instructor is accommodating to students within reason and I believe that is something they should keep doing.”
“keep being a great teacher :)”
Figure 3: Summary of student responses to four questions: assignments, workload, grading, and pace
At the mid-semester point, once the grades were up-to-date, I started reaching out to students who had missing work or were falling behind. The intention wasn’t to penalize them, but to give them an opportunity to catch-up. At the same time, I made a point to recognize those who were consistently performing well and allowed all students the same opportunity to request the opportunity to catch up on any missed assignments to maintain fairness. Many students responded well to that nudge.
One practice I intentionally carried forward from my own experience as a student was leaving comments on graded work, not just when points were deducted, but also to acknowledge strong submissions. It is a small effort from my end, but it helps students feel seen and motivates them to keep improving. As a student, those were the moments we looked forward to, knowing the instructor noticed good work.
As the semester came to an end, the focus shifted to final evaluations, especially grading the course projects and submitting final grades to the university. One thing I did not fully anticipate during this phase was the time needed to carefully evaluate student projects. Each submission reflected a significant amount of effort, and I wanted to give them the attention they deserved. As a result, grading ran later than I had initially expected, although it was still well within the official deadline.
Teaching this course taught me some important things. Good teaching is not about getting everything perfect, it’s a way to strengthen your own knowledge while sharing that knowledge in a way others can truly grasp. It is also about being responsive, thinking about what’s working and what isn’t, and being willing to adjust along the way. Managing a full class without a TA was basically a one-person band situation (except I was the entire percussion section, keeping tempo, fixing the rhythm mid-performance, and still trying not to miss a beat while everyone else expected a flawless show). But throughout the semester, I focused on doing the best I could and continuously improving based on student input. Overall, this experience was incredibly rewarding and reaffirmed my plan to pursue a career in academia.
Acknowledgements
I sincerely thank my advisors, Dr. Michele C. Weigle, Dr. Michael L. Nelson, and Associate Professor & Assistant Chair of the Department of Computer Science, Dr. Steven J. Zeil for providing me with this invaluable opportunity to gain teaching experience as a PhD student. I am also grateful to my advisors and my colleague Dr. Bhanuka Mahanama, for always being available to answer questions. Special thanks to Dr. Santosh Nukavarapu for his mentorship throughout the semester and Syed R. Rizvi for providing the course slides. Credit for establishing and continuously refining this structure should go to the instructors who have taught the course over the years, including but not limited to Drs. Irwin Levinstein, Jian Wu, Vikas Ashok, Syed Rizvi, and Santosh Nukavarapu.
And finally, a very special thank you to my husband, Skanda Siva, for being endlessly flexible with his schedule and for his constant support, and to Yara Siva, who may not know it yet but was my tiniest companion through it all.
In the hours following the release of CVE-2026-45447 for the project OpenSSL, site reliability workers
and systems administrators scrambled to desperately rebuild and patch all their systems to fix a heap use-after-free in PKCS7_verify(). This is due to the affected components being
written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes
these things just happen and there's nothing anyone can do to stop them," said programmer Prof. Fabian Greenholt, echoing statements
expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have
occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can
we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to
write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities
regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."