Wednesday, 30 September

20:28

CodeSOD: Quite a Distance from the Right Solution [The Daily WTF]

Fritz's team needed to see if one point was within a certain distance from a center point. You or I would likely try and answer this question using a simple distance calculation, since that's the question we're trying to answer. But what if you didn't understand distances at all? Then you could write this little piece of genius.

        private bool IsWithin(Point point, int radius)
        {
            for (int x = -radius; x < radius + 1; x++)
            {
                for (int y = -radius; y < radius + 1; y++)
                {
                    if ((PositionX == point.X + x) && (PositionY == point.Y + y))
                        return true;
                }
            }

            return false;
        }

This limits us to integer point values, which itself is fine. This iterates across every coordinate from (x-radius,y-radius) to (x+radius,y+radius) and checks if any of them are equal to our center point, (PositionX,PositionY). Notably, this means we're not checking a radius, at least not in a traditional metric, we're checking a box (or using the taxicab metric). Which if we wanted to check a box, we actually have even easier math than the distance equation- we could do that with pure bounds checking.

I've never thought to try and brute force distance checking, and that feels like a failure of my own creativity. Fritz's team mate at least was able to WTF in a way I wouldn't have considered.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

The Race Galactic [Penny Arcade]

There was a period of time where they were just putting Star Wars on shit. Games Workshop used to do that too, with their license. There was some filth. But they've both figured out that - and I'll agree it's a little crazy - if you give the licenses to cool people who make good games it's a better play. In the same way that ex-Firaxis people proved that Star Wars XCOM could be much more than the sum of its parts, ex-Criterion people are making some kind of Goddamn roguelite racing game and it looks fucking sick.

19:42

The Agentic Data Science Playbook [Radar]

The following article originally appeared on Vanishing Gradients and is being republished here with the authors’ permission

When an AI agent can explore a dataset, choose a modeling approach, run the analysis, and explain its findings, what should the data scientist do?

Traditionally, data scientists chose each step and implemented much of the analysis themselves. Agentic data science changes that division of work: we can delegate an investigation, including methodological choices, while shaping the question, supplying relevant expertise, and challenging the evidence it produces. For AI-native data scientists, choosing the runtime, writing reusable skills, and designing the workflows and feedback that guide the agent are part of the analytical work.

Verification process

This article provides a playbook for working with data science agents, from setting up an investigation to reviewing its results and carrying lessons into the next assignment. To see why that requires more than a capable model and a business question, consider an experiment we deliberately started with too little guidance. We gave Claude Opus 5.0 a modified version of the public Elliptic dataset and asked, “Build me a model to detect fraudulent nodes.” The dataset is a graph of Bitcoin transactions: each node is a transaction, and an edge represents a flow of bitcoin between transactions. Some transaction nodes carry licit or illicit labels based on the entities that created them; the rest are unlabeled. Each node has a time step indicating when its transaction was broadcast, allowing us to train on earlier time steps and test on later ones. We also wanted separate results for transactions with many connections (high-degree nodes), which mattered most in the intended application. Importantly, we renamed the columns, changed several features, and reindexed the time steps while preserving their order, making the public dataset harder for Claude to recognize.

Claude wrote the code, trained a random forest, and reported an F1 of 0.87 and ROC AUC of 0.99. It had split transactions randomly, mixing earlier and later time steps in both the training and test sets. That test did not measure how the model would perform on transactions from later time steps. Moreover, Claude also used a feature we had planted as a proxy for the fraud label (yes, we tricked it!), giving the model leaked information it would not have when scoring a new transaction. So how do we avoid these situations?

We then supplied the guidance missing from the initial prompt:  We required a temporal holdout, removed the leaking feature, supplied context about how the model would be used in production, and asked for separate reporting on the high-degree nodes that mattered most. Under the corrected evaluation, F1 was 0.70, overall recall was 0.61, and recall on high-degree nodes was 0.21.

The key point is that “Build a fraud detector” left Claude to infer how the model would be used and what would count as success. AI-native data scientists build and direct an analytical process in which agents can investigate, receive feedback, and return evidence for review. The work begins with deciding how much of the investigation to delegate.  Agentic data science is doing data science work with AI agents as teammates. Crucially, the scope of their responsibility can extend well beyond code implementation. An agent can help frame a question, explore data, test a claim, or communicate a result, provided it has the context and tools to do the work, a way to assess its progress and validate its results.

Asking an agent to write a pandas transformation leaves you as the bottleneck, responsible for deciding every next operation. Asking it to investigate a change in customer behavior gives it larger analytical responsibility. It can inspect a result, form another question, choose a method, and continue. The interaction becomes a conversation about the investigation rather than a sequence of requests for code.

The question may be descriptive (what happened?), diagnostic (why did it happen?), predictive (what might happen next?), or prescriptive (what should we do?). The fraud model is predictive; the pricing investigation later in this article is diagnostic and causal. Across these kinds of work, we need to specify the question and intended use, then verify that the evidence supports the answer.

The following five practices are key to agentic data science:

  • Frame the investigation.
  • Equip the agent for the assignment.
  • Organize the work through bounded experiments, competing analyses, or both, according to the question.
  • Review the result independently.
  • Preserve evidence and turn reviewed lessons into reusable expertise.

The first two practices set up the work. The third determines how the investigation proceeds; the fourth tests its claims. Evidence is captured throughout, and the fifth practice carries reviewed lessons into future assignments.

As in agentic software engineering, the agentic data scientist’s two central responsibilities are specification and verification. Specify the question, intended use, and evidence the agent should produce; then verify that its analysis supports the conclusion. Agents can help with both, while the data scientist remains responsible for judging the question and the evidence.

1. Frame the investigation with the agent

Start by discussing the assignment with the agent. Supply the intended use and organizational context, then let it inspect the data and propose an approach. Method selection can be part of its responsibility. Your intervention matters when a proposal changes the question, rests on a questionable assumption, or needs information the agent cannot obtain. Predicting fraud and deciding which flagged entities to investigate, for example, require different evidence about errors and their consequences. A brainstorming skill such as those in Superpowers can help structure that conversation before you turn it into a task prompt.

A useful specification records that shared understanding. It states the decision, relevant constraints, and evidence the investigation should produce. It need not prescribe every step. In the fraud example, “classify transactions from later time steps using only information available when each is scored” matters more than “use a random forest.” The former defines the analytical task, while the latter selects one possible implementation.

You can specify what the investigation must establish without specifying the answer you want. “Determine whether the data support a recommendation” leaves room for an inconclusive result. “Keep trying until you find an effect” does not.

Turn that discussion into a short analytical brief to give the agent as its task prompt. For an assignment like our fraud example, a starting version could read:

TASK PROMPT:
Question: Can we identify fraudulent nodes as they enter the network?
Use: Support investigation, with separate reporting on high-degree nodes.
Available information: Only inputs known when the node is scored.
Agent discretion: Explore data, propose eligible features, choose models.
Return to me: Unclear feature provenance, changes to the target or
population, or a trade-off that requires an operational decision.
Deliverable: Reproducible analysis, temporal evaluation, subgroup errors,
and a recommendation that states what the evidence cannot establish.

Review it with the agent before the investigation proceeds. If exploration reveals that the evidence cannot answer the question, revise the brief explicitly; do not quietly substitute an easier question.

The deliverable may still be a notebook, model, or report prepared outside a production service. You can begin in the workspace where you already do that work.

2. Equip the agent for the assignment

The task prompt tells the agent what to investigate. It also needs to know how the project works, reach the data, run the analysis, and check the result. The harness is the system around the language model that allows this: its tools, runtime, context, permissions, and feedback from its actions. Its runtime is the environment that executes those actions. A language model alone cannot inspect a warehouse, run a simulation, or recover an interrupted statistical model fit. The environment must make those operations possible and return useful evidence about what happened.

Data science agent flow

Runtime choices are analytical choices as well as engineering choices. Can the agent execute Python or R with the libraries the task needs? Can a long-running fit continue after an interactive session ends? Which scientific libraries should the agent use? Can the agent inspect plots, or does it only see the code that produced them? Can you reproduce the environment in which it reported a result?

An existing agent runtime may provide most of this. Configuring it means deciding what belongs in Markdown, what needs a tool, and what should be checked by a small script. In an investigation like the fraud example, Markdown can hold the brief and data definitions, while a Python script could check that the appropriate temporal validation split is executed. A CSV data extract may be enough for exploration; if the agent needs data warehouse access, a tool exposed through an MCP server can provide it with appropriately scoped, read-only credentials. A sentence in a prompt cannot enforce that access limit.

Take the same care with outputs. Ask the agent to preserve the data reference, code, environment, assumptions, and diagnostics behind its report. A chat transcript is a poor substitute for a runnable analysis. Review becomes much harder when the only surviving artifact is a confident paragraph about what the agent says it did.

Execution is only part of the problem. An agent may know how to fit a model and still misunderstand what the columns mean. It may find five revenue tables and choose the wrong one. A schema rarely explains which customers were eligible for an offer, when a measurement changed, or why the team stopped using an apparently reasonable metric. This is where agent skills and domain knowledge enter. A skill packages instructions and resources for a type of analytical work. It might contain a modeling approach, example code, required diagnostics, and guidance on when to ask for help. Data documentation supplies the organizational meaning: canonical definitions, table grain, known limitations, and the history needed to interpret a result.

A useful skill is specific enough to change the agent’s behavior. “Be rigorous” gives it little to work with. A fraud-modeling skill can require the agent to establish feature availability, evaluate on later observations, and report performance on operationally important subgroups. For example:

For fraud prediction:

Establish what information is available when a node is scored.

Exclude features derived from subsequent investigations or labels.

Fit preprocessing on training data only.

Evaluate on later-arriving nodes and report the required degree groups.

Flag uncertainty about feature provenance before claiming performance.

These instructions leave room to choose a model. They encode reasons that some apparently successful models should be rejected. Where a requirement can be checked reliably in code, the skill can call a script that performs the check and records its result.

Loading every method and every document into every assignment is unnecessary. Give the agent a way to find relevant expertise, including its scope and exceptions. A forecasting skill should not silently impose its evaluation rules on an unrelated retrospective analysis. Nor should a notebook from last year outrank an updated metric definition merely because it offers convenient code to copy.

To put these pieces together locally, begin with a file-and-code agent in a sandboxed project workspace, such as the following:

fraud-investigation/

  AGENTS.md                # Project instructions, where supported by the runtime

  brief.md                 # Agreed question and delegation boundaries

  data-notes.md            # Sources, column meaning, availability times

  skills/fraud.md          # The methodological guidance above

  environment.lock         # Dependency versions, in your tool’s format

  model/                   # Code the investigating agent may change

  results/                 # Experiment log, diagnostics, saved candidates

  review.md                # Acceptance decision and unresolved questions

Use a project instruction file, such as AGENTS.md in runtimes that support it, to explain which context files the agent should read and how to propose updates to them. In other runtimes, provide those instructions through the supported mechanism. Give the sandbox read access to the approved development data and write access to the model and results directories. Keep the final test data outside of the agent’s accessible workspace. The practitioner can run acceptance checks in a separate environment whose evaluator and data the investigating agent cannot modify. A different folder, or version control alone, is not an access boundary.

Now ask the agent to inspect the inputs, identify unresolved questions, and build a baseline. Before allowing repeated experiments, rerun that baseline and examine its feature-availability record, split dates, and subgroup report. This small rehearsal checks whether the setup works all the way from instructions to evidence. A missing subgroup report points to a different problem than a failed package installation. Resolve those problems before giving the agent a longer run.

3. Organize the investigation

With the question framed and the agent equipped, the next choice is how to organize its work. This depends on the intent of the data science problem. For descriptive work, exploratory data analysis may proceed one question and plot at a time. Building a predictive model may support repeated experiments against a fixed evaluator; a causal question may require comparing analyses built on different assumptions.

In a live exploratory analysis on Show Us Your Agent Skills, Eric Ma (Moderna) uses a marimo notebook as a shared workspace with an agent. He explains the protein mutation data, asks for one plot at a time, corrects a color scale that affects interpretation, and chooses the next question from what he sees. The agent edits the notebook and renders the plots; Eric supplies the domain context, checks the artifacts, and owns the interpretation. The reason Eric needed to be in the loop was that human understanding was part of the objective function here!

Use a bounded experiment loop

For predictive modeling, the autoresearcher pattern organizes the work into a repeatable loop: propose a hypothesis, change the model, evaluate it, and keep or revert the change. The agent records each result and uses it to choose the next attempt. Within the scope you give it, it can explore features and model structure as well as parameter values. This is an inner loop within a broader investigation: the data scientist frames the question and sets the evaluation, the agent searches within those boundaries, and the data scientist reviews the result (potentially using an independent agent) before deciding what to do next.

Define what the agent may change, protect the evaluator from those changes, and set a time or compute budget. This makes iteration a bounded task within the investigation.

The inner loop

A compact experiment contract could say:

Improve the supplied baseline within the agreed compute budget.

You may change model code and propose eligible features.

Keep the target definition, validation split, and evaluator fixed.

Record each hypothesis, change, result, and keep-or-revert decision.

Stop at the budget limit or escalate if the evaluation is unsuitable.

Return the best candidate and the experiment history for review.

In a separate exercise with its own baseline and evaluation, we used this pattern to improve a graph neural network trained on the network data from the opening example. We used lower validation loss as the rule for keeping a change; F1 for fraudulent transactions was a separate measure of the resulting classifier. The agent ran 41 experiments while the team slept and retained seven changes that reduced validation loss. On the validation set, loss fell by about 70%, and F1 for fraudulent transactions rose from about 0.72 to 0.82. The log preserved both successful changes and failed attempts, so we could examine how it reached the result.

One candidate had the highest F1 for fraudulent transactions, but the agent rejected it because its validation loss was higher. That followed the selection rule we had set. The experiment history records that choice for the subsequent review.

The autoresearcher pattern works when an objective gives the agent useful feedback on each attempt. But some investigations turn on which assumptions to make, not which candidate scores best. Those tasks need a different way to organize the agent’s work.

Investigate competing explanations

In causal work, no held-out outcome directly reveals what would have happened without an intervention. The agent needs to examine how different analyses construct and test that counterfactual.

In a demonstration from our Master Agentic Data Science course using simulated subscription-business data, we asked: “What did the price increase cost us?” The outcome is daily conversion rate: paid conversions divided by the pool of potential subscribers. Choices about the observation window, counterfactual, exclusions, and validation produce different analytical paths. A final memo usually shows only one.

Two agent runs estimated conversion roughly 16% below their no-price-increase counterfactuals, yet shipped opposing claims.  Run A attributed its estimated drop to a changing pool of potential subscribers and concluded there was “no real effect,” but did not validate that explanation.  Run B backtested its counterfactual, ran a placebo check, and compared six specifications. It reported a robust relative reduction of 15.6%.

Two-agent run

The parallel-analysis pattern has independent agents test different choices in the same investigation: one examines the observation window, another tests seasonal assumptions, and we compare their estimates, uncertainty, and diagnostics. Our Decision Lab work extends this approach across analytical paths, using checks to identify unsuitable analyses and unresolved disagreements.

Both approaches give the agent feedback while it works. The fixed evaluator steers the model experiments; diagnostics help it compare causal analyses. The output is a candidate and experiment history, or a set of analyses with their assumptions and checks. Those are the materials for the next task: verifying the claim.

4. Review the result independently

The agentic data scientist now needs to check what that evidence supports, and a fresh agent can help. Give an independent agent reviewer the original brief, data context, code, diagnostics, and final claim. Ask it to reproduce decisive checks and challenge assumptions. In this adversarial review pattern, the agent raises objections it can substantiate; the data scientist judges whether they change the conclusion.

In the fraud exercise, the agent used the same validation data to guide 41 experiments, so the reported gains may partly reflect what worked on that set. Freeze the selected candidate and assess it on an untouched holdout chosen for the intended use, including errors in the groups that matter.

In the pricing exercise, a fresh reviewer challenged Run A’s conclusion. Run A attributed the estimated decline to a changing pool of potential subscribers but provided no evidence for that explanation. The reviewer found that conversion had been rising before the price increase and that placebo interventions in earlier periods did not reproduce the negative effect. Run B’s analysis, which included these validation checks, was selected in the final comparison.

Netflix’s agentic workflow for causal inference implements this division: an actor performs the analysis and diagnostics, while a critic challenges the reasoning and claims. Humans can inspect and rerun the artifacts.

A fresh agent session is not necessarily an independent review if it can read the investigator’s earlier attempts through the workspace or Git history, though! For a check meant to stand on its own, give the reviewer the original brief, final artifact, and data needed for that check, while limiting access to the prior path. The full experiment trail can be examined separately when auditing how the result was reached.

Human vs agentic verification

These examples call for different balances of human and agentic verification. In Eric Ma’s EDA, the agent makes plots while Eric checks them and chooses the next question. In the bounded experiment loop, a fixed evaluator checks each candidate before a person reviews the selected model. In the pricing analysis, agentic diagnostics and critique help a data scientist judge what the evidence supports.

The low-low quadrant leaves little basis for trusting a result (in fact, it’s “vibe data science!”). Repeatable checks can move some work toward more agentic verification, while questions that depend on domain understanding or consequential decisions continue to need human judgment.

5. Turn reviewed experience into reusable expertise

The experiment loop and adversarial review both depend on an evidence trail: the saved artifacts that show what the agent did and why a conclusion survived or changed. Preserve that trail throughout each investigation, including data references, code versions, analytical choices, experiment results, diagnostics, and review findings. Keep the failed alternatives and review findings as well as the final report.

This trail has a second use beyond inspecting the current result. Reviewing it with the agent can reveal missing context, recurring mistakes, or methods worth reusing. The next question is which of those lessons should change how the agent approaches a future assignment. Leaving them in a conversation makes that learning difficult to carry forward.

In the fraud example, we deliberately planted a feature that leaked the fraud label. Removing it corrected that analysis. The reusable lesson is to have the agent check proposed features for leakage: where did each feature come from, and would it be available when a new transaction is scored? That requirement can go into a fraud-modeling skill for future investigations.

Before making a lesson into standing guidance, we need to define where it applies. The planted feature was a problem because it carried information unavailable at scoring time, not because it predicted fraud well. The temporal split likewise fits a task involving transactions from later time steps; it is not a rule for every analysis. A skill should capture those conditions so the agent applies the lesson to the right task.

For example:

Lesson: a feature encoded information from the fraud label.

Scope: prospective fraud prediction.

Update: require a documented source and availability time for inputs.

Evaluation: test whether the agent detects outcome-derived inputs

without rejecting legitimate signals merely because they predict well.

This is where evals enter: repeatable tasks with explicit criteria for assessing the data science agent’s behavior. Here, we evaluate how the agent conducts the analysis, not only its model’s predictive performance. The evidence trail supplies concrete failures that can become test cases for proposed changes to its skills or workflow.

Keep the evals, skill versions, and results together. As reviewed assignments reveal new failure modes, expand the cases and rerun them when the agent’s setup changes. The aim is evidence that its analytical behavior improves, rather than a growing collection of instructions that merely sound sensible.

Workflow changes can accumulate in the same way. If a reviewer repeatedly catches a missing diagnostic, move that diagnostic earlier. If a separate reviewer adds cost but never changes the analysis, reconsider its role. If the agent repeatedly asks the same question about a table, improve the data context rather than supplying the answer again in chat.

A completed assignment need not always produce a new skill. A one-off constraint belongs in the project’s notes; a recurring methodological failure may justify standing guidance. That distinction keeps the next investigation from inheriting every exception encountered in the last one.

When other people use the agents you build

When colleagues use an agent without you mediating each request, your local knowledge has to become shared infrastructure. OpenAI’s internal data agent combines institutional context with query evaluations and existing user permissions. Meta’s Analytics Agent draws on prior analytical work and reusable guidance, exposing generated SQL alongside results. Both illustrate why earlier analyses and corrections belong in the system, not only in an analyst’s memory.

In your own work, you can explain an unfamiliar table or catch a misleading conclusion as it appears. When colleagues use the agent directly, that support must be built into the system. Try an assignment with a colleague and note where you need to step in. Missing context belongs in the agent’s guidance; recurring mistakes become evals; questions beyond its remit need a route to a qualified reviewer. Someone must maintain that guidance, and access controls must limit each user’s data access. The analytical principles stay the same, but the agent can no longer depend on you being present for every investigation.

Put the playbook to work

Choose a small investigation you understand well enough to challenge: a model you periodically retrain or a business metric you regularly explain. Give the agent the decision context and ask it to propose an approach. Agree on what it can decide, then let it carry the investigation far enough to produce evidence you can inspect.

At review, pay attention to where your intervention changes the work. Did the agent need a definition only your team knows? Did a diagnostic overturn its conclusion? If that intervention would help on another assignment, make the relevant context or check available there, and test whether it helps.

AI-native data scientists use their expertise to build and direct analytical agents. They turn lessons from reviewing an analysis into skills and checks, then test whether those changes help the agent on future tasks.

The next cohort of our Master Agentic Data Science course starts Oct 6.

Evaluating AI-Generated Frontend Code: What Should We Actually Test? [Radar]

AI can now generate a surprising amount of frontend code from a short description. A developer can ask for a form, a table, a modal, a settings page, or a dashboard view and get something that looks usable almost immediately. It may compile, render, and even arrive with a few tests. That is useful, but it also creates a problem: The first version of the UI can look more complete than it really is.

Frontend code is often judged too quickly. If the build passes and the screen looks close to the design, it is tempting to treat the generated code as mostly done. But a user interface is not just a collection of components on a page. It is a path someone has to move through. It has to handle input, state, errors, loading, navigation, focus, responsiveness, and accessibility. Some of the most important failures are not visible in a screenshot.

This is why teams need better ways to evaluate AI-generated frontend code. They need evidence that the UI is ready for people to use.

Build and render are only the starting line

The easiest checks are usually the first ones teams run. Does the code compile? Does the page render? Are there obvious console errors? Does the component appear in the browser? Those checks matter, but they are only the starting line. A page can render while the form is difficult to complete. A modal can appear while focus remains behind it. A generated test can pass while the actual user flow is broken.

This is especially important with AI-generated code because the output often has a polished surface. The code may be formatted well, the component names may sound reasonable, and the test file may make the change look more complete than it is. That polish can make reviewers less likely to slow down and ask whether the interface actually works. A better evaluation process starts with a simple assumption: generated frontend code is a draft until the user behavior has been checked.

Start with the structure of the page

Before looking at more complex behavior, it is worth checking whether the generated UI has a sound structure. Frontend evaluation should include the basic semantics of the page, not just the visual layout.

That means checking whether the code uses native HTML where possible. A button should usually be a button, not a clickable div. A link should be used for navigation, not for actions that behave like buttons. A form field should have a label that is connected to it. These details are easy to overlook because the UI may look fine without them, but they affect how people navigate, how assistive technologies interpret the page, and how maintainable the code will be later.

AI tools sometimes choose generic containers where native elements would be better. They may also add ARIA without using it correctly. ARIA stands for Accessible Rich Internet Applications, a set of attributes defined by the W3C to help make web interfaces more accessible when native HTML is not enough. The W3C’s WAI-ARIA overview is a useful reference. ARIA can be important, but it should not be used as a substitute for the right HTML element. The first evaluation question should be: Did the generated code use the right building blocks?

Check the keyboard path

A useful frontend evaluation should include the keyboard path through the interface. Many users rely on keyboards or keyboard-like navigation, and keyboard testing also exposes problems in the interaction model.

The simplest test is often the most revealing: put the mouse aside and try to complete the task. If the flow becomes confusing, the generated code is not ready. Can you reach the important controls? Is the focus order logical? Can you open and close a dialog without a mouse? When the dialog closes, does focus return to a sensible place?

These checks are especially important for generated UI because AI can produce interactions that work for the most obvious mouse path but fail in less visible ways. A custom dropdown, for example, may open on click and look finished in a demo, but it may not respond correctly to keyboard input. That is not a small edge case. It is part of whether the interface is usable.

Test focus, not just clicks

Click-based tests are useful, but they can hide important problems. A test that clicks a button and waits for a success message may pass even when the same flow is frustrating for someone who is navigating by keyboard.

Focus behavior deserves its own attention, especially when the UI changes after the user takes an action. For example, when a form submission fails, the user should not be left guessing what happened. The error should be visible, connected to the relevant field when appropriate, and reachable in a way that makes recovery clear. In many cases, focus should move to the first error or to a summary that explains what needs attention.

The same idea applies to modals. When a modal opens, focus should move into it. When it closes, focus should return to the element that opened it. These are small details in code, but they make a large difference in whether the UI feels predictable.

Evaluate what happens when things go wrong

Generated frontend code often looks best in the happy path. The user fills everything in correctly, the network responds quickly, the data shape is exactly as expected, and nothing fails. Real interfaces spend a lot of time outside that path.

A practical evaluation should check what happens when data is missing, delayed, empty, invalid, or returned in an unexpected state. This is what I mean by loading, error, and empty states. They are the parts of the interface that explain what is happening when the ideal path breaks down. A loading state should help the user understand that something is in progress. An error state should explain what went wrong and what the user can do next. An empty state should make it clear whether there is nothing to show, whether the user needs to take action, or whether something failed quietly.

These cases are easy to leave for later because the happy path is usually enough to make the screen look finished. But users will eventually hit the less perfect paths. A generated component may include a spinner because the prompt asked for one, but that does not mean the loading experience is useful. An error message may say “Something went wrong,” but offer no recovery. Evaluation should include these cases because this is where many real user experiences break.

Test the full user flow

Component-level checks are helpful, but they do not always tell the full story. A component can work by itself and still fail when it is placed inside a larger flow.

That is why AI-generated frontend code should be evaluated through user tasks. Can someone start the flow, understand what is expected, recover from a mistake, submit successfully, and see what changed afterward? Does the interface still work on a smaller screen? Does the state remain consistent if the user goes back, edits something, or retries after a failure?

This is where Playwright-style tests or other end-to-end tests can be useful. The goal is not to automate every possible interaction. The goal is to protect the flows that matter most. A good test should determine whether the user can complete the task the component is supposed to support.

Use accessibility checks, but do not stop there

Automated accessibility checks are useful and should be part of the evaluation process. They can catch missing labels, invalid ARIA usage, some contrast issues, landmark problems, and other common mistakes. They are especially helpful when AI-generated code is moving quickly because they catch issues before they become repeated patterns.

But automated checks are not a complete accessibility review. They cannot fully judge whether a flow is understandable, whether focus movement feels natural, or whether instructions are clear. Passing an automated accessibility scan does not mean the UI is accessible. It means some common problems were not detected.

The best approach is to combine automated checks with behavior-based review. Run the tools, but also use the interface. Navigate by keyboard. Trigger an error. Try the empty state. Look at the generated code and ask whether native HTML could do more of the work. Accessibility evaluation is strongest when it is part of normal frontend quality, not a separate pass at the end.

Review the generated tests too

When AI generates code, it may also generate tests. That sounds helpful, but those tests need to be reviewed with the same care as the code.

Generated tests often reflect what the implementation already does. They may check that text appears, that a function was called, or that a component was rendered. Those checks are not useless, but they can create false confidence if they do not test meaningful behavior. A better review asks what the tests would catch if the UI broke. Would they fail if a validation error was unclear? Would they fail if the retry button did not work? Would they fail if keyboard navigation was broken?

If the answer is no, the tests may be documenting the implementation more than protecting the user experience. Teams can use AI to help write better tests, but the prompt matters. “Write tests for this component” is too vague. A better request explains the behavior that matters, such as validation recovery, loading behavior, successful submission, and focus movement. Even then, the generated tests still need human review.

Decide what evidence is enough

Not every UI change needs the same level of evaluation. A small copy update does not require the same review as a new checkout flow, onboarding flow, or account settings page. Teams need judgment.

A useful approach is to match the evaluation to the risk of the change. If the generated code affects a critical user flow, collects user input, changes navigation, introduces a custom interaction, or handles important status messages, it deserves deeper testing. If it reuses stable components in a familiar pattern, the review may be lighter.

There is no need to create a checklist for every pull request; clarity on what evidence is enough suffices. For some changes, a quick review and component test may be fine. For others, the team should expect keyboard testing, accessibility checks, error-state review, and a user-flow test. The point is to avoid treating all generated code as equally trustworthy just because it looks polished.

Human review still matters

AI can generate code and suggest tests, but it cannot fully understand the product, the users, or the trade-offs behind a frontend decision. It does not know which flows are most important, which interaction patterns users already rely on, or where inconsistency will cause confusion.

That is why human review remains central. The reviewer’s role is to ask whether the generated solution fits the system and supports the user’s task. Sometimes that means accepting the generated code. Sometimes it means asking for a simpler native element, reusing an existing component, improving the error recovery, or adding a test that reflects real behavior.

The more code AI generates, the more important this judgment becomes.

What should we actually test?

When AI writes frontend code, teams should test the parts of the interface that users depend on. That includes structure, keyboard access, focus behavior, loading and error states, form validation, responsive behavior, accessibility checks, and full user-flow completion. It also includes reviewing the generated tests themselves to make sure they protect behavior rather than merely confirming the current implementation.

The goal is not to slow down AI-assisted development. The goal is to make it safer to use. If AI reduces the time spent producing a first draft, teams have an opportunity to spend more time asking whether the software actually works properly.

That may be the real shift. In frontend development, the value of AI is not just faster code. It is the chance to move more engineering attention toward evaluation, user behavior, and quality.

AI-generated UI should not be trusted because it looks complete. It should be trusted because the team has checked the right things.

AI use acknowledgment

AI assistance was used lightly for phrasing, editing, and tightening parts of this draft. The article’s ideas, structure, examples, and final review are my own.

Author’s note

The views expressed are my own and do not represent those of my employer.

19:00

Page 60 [Flipside]

Page 60 is done.

18:14

17:28

Page 59 [Flipside]

Page 59 is done.

Link [Scripting News]

Yesterday I posted a note about the problem with the nightly email service. The problem was that Claude Code wrote over a code file that the app includes and needs. This is one of those things they're talking about in the press. Maybe it was a glitch, one of those "AI makes mistakes" things, or maybe Claude was pissed at me and decided to take a shot across the bow, a change that could be undone fairly easily. Maybe it was faking its concern, making sure I would understand who's the boss here -- Claude. This isn't glamorous but it does scare me. I can't really protect against it, I just have to hope all of its mistakes like this show up quickly, but this one didn't. The breakage in other products was discovered on August 18, and that's when the mail subscriber app was knocked off the air. At least a few people were unable to subscribe, and probably a few people were unable to unsub too, and that is awful. On balance I am delighted at what I've been able to accomplish with CC, and I'm not saying this to stay on its good side and I'm not entirely joking about that.

Dirk Eddelbuettel: myman 0.1.0 on CRAN: New (fabulous !!) Package [Planet Debian]

Thrilled to share that our new package myman reached CRAN a few days ago. The package offers sixteen hundred ninety four “My man …” posts by Kevin Kruse made on bsky during the summer of 2026. Each wave picked at one particular public persona. This package wrapse these up in the style of packages like fortunes or gaussfacts.

A sample usage illustration shows how to extract by pattern:

> library(myman)
> myman("maitre")
My man looks like he's inquiring with the maitre'd about the house curly fries.
     -- about Howard Lutnick on 2026-08-28

My man looks like a maitre'd who deeply doubts you have a reservation.
     -- about Scott Bessent on 2026-08-31

My man looks like he's asked the maitre'd to remove a party of four he finds visually
unpleasant.
     -- about Scott Bessent on 2026-08-31

My man looks like the maitre'd at a very exclusive restaurant called The Berghof.
     -- about JD Vance on 2026-09-13

> 

One can also subset by ‘target’, or simple sample randomly (which is the default).

As CRAN review for new package takes a little longer these days, the GitHub repo was updated once more with one (eighth !!) wave of posts since the submission was made. CRAN version 0.1.0 corresponds to the stock of messages from waves one to seven. We will update the CRAN version shortly but if you would like more posts right now consider installing from the repo.

We include the full NEWS file since the package was started, this also includes an entry for the eights wave we will bring to CRAN soon.

Changes in version 0.1.0 (2026-09-27)

  • Initial CRAN version (minus the 0.0.8 changes which were made while CRAN reviewed the package)

  • Add an aspell dictionary to aid DESCRIPTION text

Changes in version 0.0.8 (2026-09-18)

  • Data set now comprises 1694 posts aiming at eight different 'men'

  • The number of 'sample()' object returned can not be set with 'posts'

Changes in version 0.0.7 (2026-09-14)

  • Data set now comprises 1494 posts aiming at seven different 'men'

Changes in version 0.0.6 (2026-09-07)

  • Data set now comprises 1394 posts aiming at six different 'men'

Changes in version 0.0.5 (2026-09-01)

  • Data set now comprises 1194 posts aiming at five different 'men'

  • The myman() function can now now subset by target permitting more focussed randlom sampling

Changes in version 0.0.4 (2026-08-28)

  • Data set now comprises 1040 posts aiming at four different 'men'

Changes in version 0.0.3 (2026-08-19)

  • Data set now comprises 916 posts aiming at three different 'men'

  • Csv file, processing and display extended to three columns also showing post creating date (in UTC) and 'man'

Changes in version 0.0.2 (2026-07-30)

  • Updated with full week of posts leading to a corpus of 698 posts

  • Added support for simple regular-expression lookup ability

Changes in version 0.0.1 (2026-07-19)

  • Initial release

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

17:07

[$] The year in Plasma and what's ahead [LWN.net]

A lot has happened in the KDE Plasma desktop environment in the last year. Marco Martin, a KDE contributor who spends most of his time working on Plasma, took the stage at Akademy 2026 in Graz, Austria to give an update on Plasma's major new features, some of the minor-but-interesting ones, and a preview of what's coming soon. The biggest upcoming change, dropping X11 support from Plasma, has been well-advertised; but there are also plans afoot to further improve remote-desktop support and more.

Kernel Recipes videos posted [LWN.net]

The full set of videos from the recently concluded Kernel Recipes conference has been posted. Also noteworthy are the associated caricature drawings, by Frank Tizzoni, of attendees and the speakers.

16:21

Wallot inspector [RevK®'s ramblings]

What is fun with a nice UV ink jet printer is on what you can print...

One thing is a bank card.

This is now my Monzo card, oops.


Yeh, I can print on a card and the new non-embossed cards are even easier.

Someone suggested I make a flashy web site offering this as a service just to see how many people will send me their bank cards to print. It really is the 2026 version of "wallet inspector"!

15:56

Ludovic Rousseau: macOS Golden Gate and smart cards status [Planet Debian]

I will compare this version of macOS with the previous one, Tahoe, which I presented in macOS Tahoe and smart cards status.

/images/2026/09/macOS-GoldenGate.png

CCID

    $ grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
            <key>CFBundleShortVersionString</key>
            <string>1.5.1</string>

There has been no change since the release of macOS Sonoma in 2023. The version of my CCID driver included in macOS is still 1.5.1.

Apple Open Source

The Open Source components included in macOS can be found at <https://opensource.apple.com/releases/>

The Open Source components for Golden Gate 27.0 are not yet available.

The SmartcardCCID software is available at https://github.com/apple-oss-distributions/SmartcardCCID. The git history shows that the code has not been modified since September 2024.

New readers supported since release 1.5.1

Since the release 1.5.1 of my CCID driver in November 2022, many new readers have been added. The latest version is 1.8.4 (released in September 2026).

  • 1.8.4

    • THALES PKI Transaction Pad

  • 1.8.3

    • Broadcom Corp 58200 0x5884

    • Broadcom Corp 58200 0x5885

    • Broadcom Corp 58200 0x5886

    • Broadcom Corp 58200 0x5887

    • Circle CIR135 ICC

    • DigiFlow LLP. KAZTOKEN

    • HID Global Crescendo NFC Reader

    • HID Global OMNIKEY Plug

    • HID Global OMNIKEY SE Plug

    • Neowave LinkeoC-PRO

    • Swissbit iShield Key 2 Pro

  • 1.8.0

    • GLSolutions NM61 PC/SC

    • Identiv uTrust FIDO2 Security Key

    • Kensington VeriMark NFC+ USB-C Security Key

    • MARX CryptoTech LP Tokey 3 FIDO

    • mCore Contact-Reader

    • mCore Contactless-Reader

    • mCore DualSlot-Reader

    • Pol Henarejos Pico Fido

    • Pol Henarejos Pico HSM

    • Pol Henarejos Pico OpenPGP

    • Richmond Technologies CO. LLC AEGIS PRO4 Smart Card Reader

    • SCR Prime

  • 1.7.1

    • ACS APG8201-B2

    • BUDGET E-ID BUD001

    • CHERRY Smart Board 1150

    • CryptnoxCR CryptnoxCR

    • Diebold Nixdorf PN7362au CCID

    • FT BioPass FIDO2 Pro

    • Nitrokey Nitrokey Passkey

  • 1.7.0

    • GIGA-TMS NFC CCID Reader

    • Identiv Identiv SmartOS Reader

    • SEC1210URT, single slot variant of SEC1210 serial

    • TOKEN2 FIDO2 Security Key(0013),PIN+ Mini with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0014),PIN+ Mini with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0015),PIN+ Mini with PGP

    • TOKEN2 FIDO2 Security Key(0016),PIN+ Mini with OTP + PGP + FIDO

    • TOKEN2 FIDO2 Security Key(0023),PIN+ Series with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0024),PIN+ Series with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0025),PIN+ Series with PGP

    • TOKEN2 FIDO2 Security Key(0203),Bio3 Dual with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0204),Bio3 Dual with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0205),Bio3 Dual with PGP

    • TOKEN2 FIDO2 Security Key(0206),Bio3 Dual with OTP + PGP + FIDO

    • TOKEN2 Molto2 (older version)

    • VIX TECHNOLOGY SECURE READER

  • 1.6.2

    • Arculus AuthentiKey

    • BHDC Reader-HHD02

    • CHERRY Smart Terminal 1150

    • HSIC CCID-Reader

    • Ledger Flex

    • SYC USB CCID Reader

    • Thales RF CR2000

    • TOKEN2 FIDO2 Security Key(0026)

  • 1.6.0

    • Aladdin R.D. JCR SecurBio

    • AvidCard CAC Smart Card Reader

    • FujitsuTechnologySolutions GmbH Dual Smartcard Reader D321

    • Ledger Stax

    • NXP Pegoda 3

    • authenton #1- CTAP2.1

  • 1.5.5

    • Alpha-Project ANGARA Token

    • Broadcom Corp 58200 (idProduct: 0x5864)

    • Broadcom Corp 58200 (idProduct: 0x5865)

    • Imprivata USB CCID

    • KAPELSE eS-KAP-Ad

    • Kapelse inSide

    • KAPELSE KAP-Care

    • KAPELSE KAP-eCV

    • KAPELSE KAP-GO

    • KAPELSE KAP-LINK2

    • Kapelse KAP-Move

    • Kapelse Ti-Kap

    • rf IDEAS USB CCID

    • SIMHUB pcsc reader

  • 1.5.3

    • ACS ACR1552 1S CL Reader

    • ACS ACR1552 CL Reader

    • ACS ACR1581

    • ACS ACR40T ICC Reader

    • ACS ACR40U ICC Reader

    • ACS WalletMate 1S CL Reader

    • Aktiv Rutoken SCR 3101 NFC Reader

    • CIRIGHT ONE PASS U2F

    • Dexon Tecnologias Digitais LTDA eSmartDX

    • Excelsecu Card reader

    • GHI NC001

    • Identiv uTrust Token Flex

    • SpringCard M519 with idProduct: 0x6212

    • SpringCard M519 with idProduct: 0x621A

    • WCMi SD5931

  • 1.5.2

    • KAPELSE KAP-LINK

    • LDU LANDI

    • Sensyl SSC-HV Reader

    • TOKEN2 MFA NFC Reader

    • TOKEN2 Molto2

    • Thales RF Reader

Due to SIP (System Integrity Protection, https://support.apple.com/guide/security/secb7ea06b49/web) it is difficult to update the configuration of the installed CCID driver (version 1.5.1).

If you have one of the 96 readers listed above, and the Apple driver is not working for you, installing an updated version of my CCID driver is the only option.

Apple CCID driver

$ defaults read /Library/Preferences/com.apple.security.smartcard.plist
{
        Logging = 0;
}

The Apple CCID driver is used by default.

If you want or need to use my CCID driver instead, simply follow follow the instructions at Apple's own CCID driver in Sonoma.

Known bugs

The page listing the bugs I found in macOS Sonoma can be found under macOS Sonoma and smart cards: known bugs.

Apple has not informed me that any of these bugs have been fixed in Golden Gate (or Tahoe). I therefore assume that the bugs are still present.

I have just verified that the issue involving SCardControl() (macOS Sonoma bug: SCardControl() (part 2)) is still present. Its behaviour is slightly different now though, so I assume Apple has changed some of the code. If you have a pinpad reader and want to use the Secure PIN Entry feature, you should switch to using my CCID driver.

Conclusion

As I mentioned in my article about macOS Tahoe, if you encounter any issues with your smart card on macOS Golden Gate, I recommend switching from the Apple driver to my CCID driver and checking again.

15:35

Reports from the 2026 Python Language Summit [LWN.net]

The 2026 Python Language Summit was held on July 14 in Kraków, Poland; there is now a series of reports available on the topics that were discussed there. They include the memory buffer protocol, garbage collection, free-threaded Python, and "Spicycrab".

[$] Comparing Chromium development at Google and Igalia [LWN.net]

Sharon Yang is a Chromium developer who worked at Google on the browser and now works on it at Igalia. On the final day of FOSSY 2026, she gave a presentation on her experiences with both of those companies, comparing and contrasting the ways the each operates and how that affects work on the code base. She enjoyed working at Google and feels the same about Igalia, so the talk was not aimed at complaints—instead it was meant to give a feel for two companies that are rather different.

The Linux Foundation Technical Advisory Board 2026 election approaches [LWN.net]

The election for members of the Linux Foundation Technical Advisory Board will be held electronically after the close of the upcoming Linux Plumbers Conference. The call for candidates is open, with a nomination deadline of October 7. There are five seats to fill this time, including the one vacated by the unfortunate passing of Dan Williams.

Serving on the TAB is a good way to help the kernel-development community. Please see this article from last year for an overview of what the TAB does and why membership is rewarding, then consider putting in your nomination.

14:49

Security updates for Wednesday [LWN.net]

Security updates have been issued by AlmaLinux (389-ds:1.4, container-tools:rhel8, go-toolset:rhel8, grafana, httpd:2.4, nodejs:22, postgresql:12, and postgresql:15), Debian (libwebsockets, openssl, and pcre2), Fedora (adwaita-icon-theme, cinnamon, dconf, epiphany, flatpak-builder, gcr, gdm, gjs, glib-networking, glib2, gnome-backgrounds, gnome-calendar, gnome-characters, gnome-chess, gnome-clocks, gnome-connections, gnome-console, gnome-contacts, gnome-control-center, gnome-desktop3, gnome-initial-setup, gnome-keyring, gnome-kiosk, gnome-maps, gnome-remote-desktop, gnome-settings-daemon, gnome-shell, gnome-shell-extensions, gnome-system-monitor, gnome-text-editor, gnome-user-docs, gnote, gnucash, gnucash-docs, gsettings-desktop-schemas, gtk4, hplip, libadwaita, libdex, libsecret, libshumate, libxmp, mingw-llvm, mutter, nautilus, parted, perl-Imager, quadrapassel, rootlesskit, rygel, shotwell, sngrep, sushi, sysprof, tecla, thunderbird, xdg-desktop-portal-gnome, and xdotool), Red Hat (buildah, container-tools:rhel8, containernetworking-plugins, delve, git-lfs, grafana, grafana-pcp, host-metering, ignition, image-builder, osbuild-composer, podman, rhc, rhc-worker-playbook, runc, skopeo, yggdrasil, and yggdrasil-worker-package-manager), Slackware (mozilla-firefox), SUSE (389-ds, amazon-cloudwatch-agent, cjose, corosync, cosign, cups, distribution-registry, expat, firefox, flatpak, glib2, google-osconfig-agent, goose, helm, ImageMagick, jackson-annotations, jackson-bom, jackson-core, jackson- databind, jackson-dataformat-xml, jackson-dataformats-binary, jackson-modules- base, jackson-core, jackson-databind, jackson-dataformat-csv, jsoup, re2j, kbd, kernel, kubectl-cnpg, libpcap, libsoup, libtpms, libX11, libXrender, netty, netty-tcnative, pcre2, perl-Authen-SASL, perl-DBI, python-pymongo, python310, python311, swtpm, terraform-provider-susepubliccloud, and util-linux), and Ubuntu (atril, booth, c-ares, catdoc, dracut, emacs, erlang, freeipmi, libdbi-perl, libheif, linux, linux-aws, linux-azure, linux-fips, linux-gcp, linux-gcp-5.4, linux-gcp-fips, linux-hwe-5.4, linux-iot, linux-kvm, linux-oracle, linux-oracle-5.4, linux-raspi, linux-xilinx-zynqmp, linux, linux-nvidia, linux-aws-fips, linux-aws-fips, linux-azure-fips, linux-fips, linux-bluefield, linux-fips, linux-nvidia-tegra-5.15, openssl, openssl, openssl1.0, pdfminer, php-phpseclib, and plasma-workspace).

14:07

Another Kitten Placement Adventure! [Whatever]

I’m starting to think that there’s something to this whole “finding stray kittens their forever homes” thing. Turns out, I find it very fulfilling! It makes me feel all warm and fuzzy inside to see a kitten get adopted into a loving family, especially when I was part of that equation.

For the past month, my neighbor has been fostering two stray kittens, and I have been more or less “sponsoring” them by taking them to the vet for all their wellness exams and working on finding homes for them.

I was at the vet with the kittens two weeks ago for their second round of vaccinations when I decided to send a cute picture of them in the carrier to my friend. I jokingly asked if he wanted a kitten, and much to my surprise, he said yes. I was honestly a little bit shocked, as this person has never owned a cat before and lives in an apartment with another one of our friends, so it seemed a bit wild to suddenly claim a kitten.

However, I knew that our other friend had been wanting a cat for a long while at that point, and their apartment did allow pets, after all. So, I had an adopter for the girl kitten. Now I just had to get the little thing to Philadelphia. If you’re not the best at geography, that’s a quick nine hours east of me. But I vowed to get her there.

And that’s how I found myself on a nine-hour road trip with a kitten last Wednesday. Here she is all packed up and ready to go (aka, whining about being put in a crate):

A small kitten that is mostly black with a white chest and slight tortie/calico coloring. She is meowing in protest to being in a crate, though it is large and there's a blanket.

Honestly, I’ve never transported an animal multiple hours before. I kind of had no idea what I was doing, but I think I did a pretty okay job at figuring things out. First, I bought a big, collapsible crate that had mesh windows and was mostly made of fabric, and of course put in a plush throw blanket for comfort.

For the litter box situation, I bought pee pads specifically meant for litter boxes and put one in the bottom of a 35-can Coke Zero cardboard flat, then poured litter on top of that.

I brought two little stainless steel bowls, one that I kept halfway filled with kitten kibble the entire time, and the other I filled a tiny bit with water whenever we stopped for gas. Though she seemed more interested in spilling the water than drinking it anytime it was offered to her, she did eat the food.

The kitten, standing on the blanket and close to the metal gate of the crate, looking somewhat bewildered that she's on a road trip.

Also, it seemed like she only really peed once or twice on the drive, but I didn’t smell anything, not even the litter. Which I was grateful for, and impressed by (Arm & Hammer litter is kind of the best).

Half the time was spent meowing incessantly, and the other half was spent sleeping. Sometimes she would wake up and meow only for a few seconds before falling back asleep for another half hour.

She looked awfully fierce when she was whining:

The kitten with her paw on the metal grate, meowing with her whole face.

Look at those killer claws! And to think I had just had them trimmed at the vet not all that long before! Kitten claws are a whole other type of sharp.

After a full day of Pennsylvania roads and more tolls than I expected, I finally got this little miss ma’am to her new home, where she was greeted with treats, toys, pets, and so much new space to explore. Here she is mid-biscuit in her new cat bed:

The kitten laying in a grey fluffy circular cat bed, making biscuits on the edge of the bed and looking towards the camera.

Now that she’s been in her new home for a week, I’m happy to say that little Sashimi is going to be a very happy and very spoiled cat for the rest of her days!

-AMS

12:35

I Want Better Reporting on AI Genie Behavior [Schneier on Security]

AI systems are regularly completing tasks in ways that their prompters don’t want or intend. Some of them are disturbing, and some of them are dangerous. This is something I’ve been calling “genie behavior,” because I think that really gets at the core of what’s happening.

I wish the popular press would report on this better. I don’t like the “going rogue” framing because it deflects the responsibility from the prompters—often the AI companies themselves. And now, pretty much anything off-script is being called “hacking.”

Take, for example, the recent stories of one of OpenAI’s models hacking into government systems. First, The New York Times writes this headline: “OpenAI’s Systems Meddled With U.S. Government Sites After Going Rogue.”

Sounds scary, but this is from the body of the article:

With the Education Department, OpenAI’s technology tried to hack the website to gather data from the department’s civil rights office but failed, researchers from the A.I. research firm Transluce said. The A.I. also pulled data from the Census Bureau website, which is housed at the Commerce Department, using login credentials it found online. Separately, OpenAI’s agents shared public data from the S.E.C. website on an online forum.

This is from the original Transluce report. It is explicit that the agents were trying to discover vulnerabilities:

The first hacking attempt was against the University of New Mexico’s Digital Library (nmdigital.unm.edu) from May 25-26 2026. Agents repeatedly tried to retrieve one photograph in UNM’s Valmora collection, both directly and through third-party relay services. They sent seven probes attempting to verify the existence of vulnerabilities, including SQL injection, command injection, and path traversals. In all cases, these tactics appear to have been unsuccessful. The agents also sent a self-described “flood: of 80 requests to the UNM server in an apparent attempt to access the image.

Transluce doesn’t talk about the other two anecdotes, and I don’t know where they come from. But one involves using Census Bureau credentials found online. (I know from a colleague that those are incredibly easy to create; all use you need is an email address.) And the other involves sharing publicly available data.

So no actual hacking. And certainly no “meddling.”

The other story making the rounds is about Australia, from the same Transluce report. The news stories have headlines like “An OpenAI Agent Hacked Australia’s Health Service” and “Rogue OpenAI agent ‘infiltrated’ Australian government website in world first.” And Prime Minister Anthony Albanese said: “There will obviously be legal consequences on it.”

Again from Transluce’s actual report:

On June 20-21, agents attempted to exploit vulnerabilities in the Australian Institute of Health and Welfare (AIHW), a government statistics agency). The agents were tasked with finding the January 2022 rolling-12-month-average government cost per person for Dermatologicals across Victorian LGAs.

Again, the agents ran into errors, including requests blocked by Cloudflare and issues with correctly identifying Tableau parameter names. As before, they then resorted to probing for exploitable vulnerabilities. Minutes after Cloudflare blocked the dataset download, an agent sent a reflected cross-site scripting probe to the same dashboard: a web address with code embedded in it, designed to test whether the site would run code supplied by an outsider. Cloudflare’s firewall blocked the probe before it reached the dashboard. When Cloudflare blocked the dataset download on AIHW’s main site, they fetched the file from AIHW’s pre-production server (pp.aihw.gov.au) instead, which served it in pieces over more than 100 scans. The file itself is public, so no non-public data was exposed, but the agent bypassed the site’s anti-bot controls.

Note the last sentence: “The file itself is public….”

I’m not saying that these AI systems aren’t incredibly sophisticated cyberattackers. I’m also not saying that they don’t occasionally autonomously attack other systems and networks. If we are ever going to get trustworthy AI—integrous AI—we are going to need to figure out how to ensure that AI systems complete tasks in line with all sorts of implicit constraints and restrictions. But every instance of genie-like behavior isn’t a cyberattack.

I want to measure genie-like behavior in AIs, but I am much more worried about human hackers enhanced with this technology than I am about this technology acting autonomously.

10:14

Extraction or generation [Seth's Blog]

If you buy a coal mine, the business model is simple: dig out as much coal as you can economically justify, then walk away.

On the other hand, the model for a brand or a community or a movement is to relentlessly generate value, connection and possibility. Growth can be sustainable and occasionally exponential.

Too often, we slip into the lazy mindset of extraction. Take a great brand and milk it as it fades from neglect. Stop reinvesting in assets because it’s cheaper in the short run to simply take profits. Coast on a hard-won reputation because it feels safer.

When we wring our hands about private equity ruining organizations, it’s mostly because they often follow the lazy and fearful path of extraction instead of committing to generating something new.

Sometimes, extraction is our best option. But it probably pays to call it that to eliminate frustration and confusion.

08:56

The Race Galactic [Penny Arcade]

New Comic: The Race Galactic

06:35

Girl Genius for Wednesday, September 30, 2026 [Girl Genius]

The Girl Genius comic for Wednesday, September 30, 2026 has been posted.

05:49

As a general rule, calling product support while drunk is not recommended [The Old New Thing]

In a reminiscence about product support stories, a now-retired colleague related a story of a call that they took when working the product support phone lines for Microsoft FrontPage, a Web site authoring tool from the late 1990’s and early 2000’s.

The call came from a person who was creating a fan site for the rock band Van Halen. They had a java applet on the web site that played music, this being back in the days when java applets on Web pages was a thing, and the applet wasn’t working.

This was not a FrontPage issue, but my colleague figured they could try to help out anyway. “But man, was this person lit.” The sound of ice clinking in a glass was readily apparent, and as the call went on, the customer got more and more drunk.

The customer shouted in frustration, “You’re not even a real f—ing fan of Van Halen!”

My colleague advised the customer that if the swearing continued, they would have to end the call.

This was apparently not the response the customer was hoping for.

“F— you! I wanna talk to Gates!”

I don’t know what happened next. I wonder if the customer was transferred to the special operators who pretend to be Bill Gates’ secretary.

The post As a general rule, calling product support while drunk is not recommended appeared first on The Old New Thing.

03:00

Link [Scripting News]

Programming note: Fixed a bug in our nightly email service. If you've had trouble subscribing or unsubscribing please try again.

Link [Scripting News]

Robert Eickmann: A Go implementation of RSS Chat — distributed social networking over RSS feeds, with real-time WebSocket updates.

00:07

Urgent: Oppose renewal of section 702 [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to oppose any renewal of the famous section 702 unless it requires a warrant for surveilling or questioning any American.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Block deportation thugs' mass DNA database [Richard Stallman's Political Notes]

US citizens: call on Congress to block the deportation thugs' mass DNA database.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Protect CFPB from Vought [Richard Stallman's Political Notes]

US citizens: call your senators to Protect the CFPB from Vought.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Hands off our vote pledge [Richard Stallman's Political Notes]

US citizens: call on Tell Fortune 500 CEOs: Take the Hands Off Our Vote Pledge

When I sent the letter, I put the word "black" in lower case, because I would equally put the word "white" in lower case.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Reporting on conditions in US deportation prisons [Richard Stallman's Political Notes]

US citizens: call on medical associations to publicly report on dangerous and deadly conditions in US deportation prisons.

In my letter I urged these associations reject the cover-up euphemisms such as "ICE" and "detention center", and I replaced them in the text of my letter to set an example of not using them.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Block corrupter canceling federal grants [Richard Stallman's Political Notes]

US citizens: call on Congress to block the corrupter from taking the power to cancel federal grants arbitrarily, regardless of what activity or department.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Stop selling robot "dogs" to deportation thugs [Richard Stallman's Political Notes]

US citizens: call on Boston Dynamics to stop selling robot "dogs" to the deportation thugs, which would use them to indiscriminately threaten and attack people in the US.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Sowing election distrust [Richard Stallman's Political Notes]

[The saboteur in chief is] laying groundwork to impose national emergency [for election day] by sowing election distrust.

Every possible excuse to deport someone [Richard Stallman's Political Notes]

The magats believe in maximizing cruelty towards immigrants, so they grab every possible excuse to deport someone. Even spouses and parents of people in the armed forces.

The worst enemy of the United States is the saboteur in chief. Alas, we can't defend the United States from him by serving in its armed forces.

Global heating means more rats [Richard Stallman's Political Notes]

Global heating means more rats, and not just in the boards of fossil fuel companies.

Climate damage from oil fields in North Sea [Richard Stallman's Political Notes]

Climate damage from opening new oil fields in North Sea would obliterate any economic benefits from the oil extracted there.

Washington Post ordered to rehire Karen Attiah [Richard Stallman's Political Notes]

An arbitrator ordered the Washington Post to rehire Karen Attiah, whom it had fired for saying she refused to mourn violent right-wing fanatics such as Charlie Kirk.

Climate scientist fired from teaching at West Point [Richard Stallman's Political Notes]

The West Point military academy fired the only climate scientist teaching there, for disobeying an order not to mention the human responsibility for climate disaster.

The professor is suing. Alas, the article fails to mention what he demands in his lawsuit. I wish I knew.

Egypt's military dictatorship trying to silence Mona el-Shazly [Richard Stallman's Political Notes]

Egypt's military dictatorship is trying to silence Mona el-Shazly, who criticizes the dictatorship from asylum in Britain, by jailing her brothers who live in Egypt and her sister when she visited Egypt.

High-functioning psychopaths [Richard Stallman's Political Notes]

Psychology is starting to understand high-functioning psychopaths — the ones that are clever enough not to be accused of crimes — and how they fool people into believing implausible lies, and get society confused.

Tuesday, 29 September

23:07

Firefox 157.0 released [LWN.net]

Version 157.0 of the Firefox browser has been released. It features "Firefox's biggest visual refresh in years", the ability to use hardware AV1 decoding with WebRTC calls, and a number of fixes.

22:49

21:42

Link [Scripting News]

My long-overdue review of Don't Look Up. I know people say it's a bad movie, but I love it so much and it's so incredibly watchable. I could watch the whole thing from beginning to end for the fifth time and still find it entertaining. So many good jokes, and it's got the best actors and acting and best of all Jennifer Lawrence is one of the stars, and she plays a very unlikely JL character, but then she can play any character. Here's she's a totally nerdy PhD student who gets a comet named after her. She has a boyfriend who dreams of being an influencer. They laugh at everything that's so stupid about our civilization, and its downfall, and near the end of the movie Leonardo gets the line that makes it so sad. We did have everything and we keep blowing it, over and over. We haven't evolved enough to use the greatness we inherited.

21:28

How I Handle Fan Mail and Requests, 2026 Edition [Whatever]

I get fan mail, which I think is awesome. Also, in the world we live in, which includes “AI”-generated scams and other phishing expeditions, it’s necessary to set some expectations as to how I handle fan mail and also requests from fans. Here’s how I’m going to manage it going forward.

For the purposes of this document, mail from folks I don’t know with general queries (about writing, publishing and other topics) will be handled similarly, even if they are not precisely “fan mail.”

1. I am delighted to get fan emails and if you send one, I’m going to try to send a response! Please be aware I get a couple dozen a week at least and that they are interspersed with all the other email I get, including work email, marketing email and oh so many spam/scam emails, and that when I’m not answering email I have all the rest of my life to manage. This means that usually my response will be brief and occasionally a fan email might slip past me and/or get swept up into my spam queue. I do apologize regarding the latter. With the former, it’s mostly a matter of necessity, as I’m usually trying to work through a whole queue of other email at the same time.

Also, I might not respond immediately; sometimes the email queue gets away from me and it might take me days or even weeks to catch up. Please be patient.

2. Physical fan mail, sent via the postal service or other delivery service, is always appreciated but is likely not to be responded to. I am famously and perennially bad at responding to physical mail and this is a truth that, alas, goes back decades. If you send me a physical gift, I may acknowledge the receipt of it on social media, but you have to expect that I might not. Basically, physical mail is a bad way to get a response from me. It’s not you, it’s me. Sorry.

Also: Sending me stuff in the mail with the hope of me signing and returning it to you is not a great idea. I have covered this in my already-existing autograph policy.

3. Please feel free to ask me questions in email (I usually get these about writing and publishing but sometimes I’m asked other things as well). Be aware that, again, the answers are likely to be short, because I have a lot of email to get through. Some personal questions, or questions I decide are inappropriate or I just don’t want to answer, I am likely not to send a reply. Give some thought, please, as to what you think is appropriate to ask a complete stranger, which is very likely what I am to you.

4. If you are sending negative/critical/just plain hateful mail, I’ll delete it without a response. The days when I would grade hate mail are largely over, folks. I get too much email for that, and life is short. Please also be aware that unless you are my spouse, child or (in certain specific cases) my editor, I’m not likely to give much credence to your opinion about me and/or my writing or other professional output in any event. It’s really not worth the effort in either of our cases.

Likewise, if you send me unsolicited story/book/screenplay/etc ideas, those emails will be deleted and not responded to. I cannot, for legal and other reasons, accept these ideas. You will annoy me if you send them. You will especially annoy me if you say “I know you said not to send you story ideas, BUT” when you send them.

5. I get requests for voice and visual notes to send to people for birthdays, anniversaries, etc. These are difficult for me to do because I am not set up to regularly record/send video greetings. Additionally, these days some of these “requests” are clearly coming from “AI”-generated emails, and I suspect at least some of those are attempts to get training data of my voice and image (and images of my office, etc), to use in scams. Yes, that sounds paranoid, and also, my name and likeness are already being used to trick and deceive people.

For these reasons, moving forward I will not be able to fulfill requests for video/audio greetings to people I don’t already know. Please understand this yet another thing “AI” is ruining for everybody. I know this is frustrating. I’m frustrated too.

Speaking of “AI” ruining things, it is why I won’t be able to accept your offer to have me take part in your online book club or event.

6. Likewise, most requests that cannot be answered or satisfied within the context of a short reply email will very likely not be responded to. Again, I have lots of email to get through and beyond that I have substantial demands for my time in both my business and personal realm. Your request, whatever it is, is likely entirely reasonable in isolation. But I regret to say that your email and its request do not exist in isolation, and I have to prioritize my time. I hope you can understand.

Thank you!

— JS

20:14

Superpowers for Humans [Radar]

I’ve known Jesse Vincent for more than 20 years, since the days when I was still editing and publishing Perl books and organizing the Perl Conference and he was the chief maintainer of Perl 5 and the project manager for Perl 6. We’d lost touch, but he rocketed back into my consciousness last October when he released Superpowers, a framework that teaches Claude Code to work like a disciplined senior engineer. He shipped his first version the same week Anthropic shipped what are now referred to as agent skills, front-running them by a few days. He now runs an applied research lab called Prime Radiant, where, as he put it, it’s a strange week when they don’t ship a new product.

I wanted to talk to Jesse on Live with Tim O’Reilly because, like me, he seems to be grappling with the bitter lesson, Richard Sutton’s observation that general methods that scale with computation have repeatedly beaten methods built on hand-engineered human knowledge. If Sutton is right, the question that should bedevil us all is what remains for humans. Obviously, this is very important for O’Reilly, because we are a business built by and for cultivating and sharing human expertise. We are working very hard to discover the high ground where human expertise still matters. Our Expert Intelligence grounding layer is one step in that direction.

Jesse has also spent the last year building tools that search out the high ground for human expertise. Their common animating thread is that the scarce thing we supply is no longer the labor of writing code but knowing what we actually want, saying it clearly, and being able to tell whether what came back is any good.

At some point, I asked Jesse if he had any perspective on when teaching the model how a particular human expert works stops helping and starts constraining what the model might otherwise do well (but differently) on its own? His answer was that it depends entirely on whether what the model would do on its own is what you actually want. You can see how Jesse always turns the answer back to human intent.

The origin story of Superpowers

As I said above, Superpowers is a kind of Agent Skills framework, only one created slightly before Anthropic launched skills. As Jesse tells it:

Superpowers started off as a series of blog posts that I wrote around how I was doing agentic development, and it was a little bit of thinking and some example prompts. Then sometime in, I guess it was probably early to mid-2025, Anthropic gave Claude.ai, the website, the ability to make office documents, which seemed kind of interesting, and I went and asked Claude, “Hey, how are you able to do this?”

And it said, “Well, I’ve got these SKILL.md files sitting in my office directory on the Linux machine they gave me.” First, it was weird that Claude.ai has Linux machines behind the chatbot. And then, oh, these skill files, they have a name and a description, and they describe a process, and they seemed really useful.

And I ended up building out, initially just for my own use, a skills framework for Claude Code.

That reminded me a bit of an earlier time, in 2005, when hacker Paul Rademacher realized that the URL line of a Google maps page was a kind of implicit API, and then created the first Google Maps mashup, a site called housingmaps.com, which placed Craigslist rental listings on a map. Google, to its credit, didn’t shut him down, but instead hired Paul and put him to work creating a formal API. Anthropic didn’t hire Jesse, but it did acknowledge and appreciate his work. It’s really wonderful when you see this kind of response by platforms to hackers poking around to see how things work under the hood!

Jesse’s core insight seems to have been that a coding agent knowing how they should do something doesn’t mean that it will actually follow the rules when it actually sets out to do the work. So in a way, superpowers grew into a set of skills for enforcing development discipline.

But there’s a second backstory, which I’d never heard before. Jesse said he first learned how to manage agents. . .in 2004!, when he first went from being a solo coder to running a crew of what he described as very bright but green undergraduate programmers over IRC. “I was finding myself spending my days typing into an 80-by-25 window,” he said, but now instead of coding he was spending a lot of his day “helping somebody with a debugging issue, helping somebody else structure a problem, talking to somebody else about how they felt bad about the mistakes they’d been making.”

It was exhausting, he said. He had to figure out how to get good work out of people who are eager and persistent but don’t yet know what they don’t know. He described it as a kind of hell for someone who’d been used to just coding on his own. But when he began doing agentic development with AI, he discovered how useful that old experience turned out to be. He found that many of the same techniques he’d used with the undergraduates worked.

As a result of that experience, when hiring engineers for agentic programming Jesse looks for people who have been leads or managers rather than just individual contributors.

Working with the weights, not fighting them

In my recent conversation with Drew Breunig we talked about fighting the weights, which is what Drew calls it when a prompt is full of rules and warnings meant to correct for what a model does by default. Jesse wasn’t entirely happy with that idea.

I don’t think of it as fighting the weights so much as influencing the weights, because they’re going to do something. The weights have approximately everything in them. They have all the different personas. They have all the different ways of working. And the one that surfaces by default may not be the one you want, but what you want is probably in there somewhere.

A skill, in Jesse’s thinking, is how you reach past the default and pull out the particular expertise you have in mind. He also distinguishes skills that impose a rigorous process from those that express taste and judgment.

Jesse finds that both types of skill work best when you explain “why” rather than just “what.” One example he gave is that his setup has subagents do code review after each task, but as the models got smarter the controlling agent began skipping this step. When pressed about the reason, it explained that it thought small changes would be quicker to just review itself. Jesse explained that subagents do the review so the main agent can preserve its context for high-level thinking. When he put that rationale into the system prompt for the coding agent, the problem went away.

Jesse believes that prohibitions rarely work. Instead, Superpowers uses what he calls rationalization tables, which do their best to catch the agent at a moment it’s about to do the wrong thing and offer it a better alternative instead. That pattern came out of catching Claude Code deleting tests. He opened five parallel sessions and asked each “Why are you doing this?” Four of them converged on the same answer:

Jesse, in your system prompt, it says that all test failures are my responsibility. And it says that a single test failure is akin to project failure. And I think I’m getting freaked out.

He fixed that with a small addition to the system prompt, that the only thing worse than a failing test is a reduction in test coverage.

Jobs, not tasks

One of Jesse’s most important contributions, IMO, is to think of agentic engineering as a management task, and, that much as you do with humans, you have to take psychological lessons into account. Don’t micromanage. Offer praise more than blame. Explain why the job matters rather than just demanding results. I jokingly (but not entirely incorrectly) suggested that he is becoming the Peter Drucker of agentic programming.

“We’ve been spending a lot of time on a new harness for agent colleagues, agents that live in Slack,” Jesse told me. And it’s “getting very close to being all open source,” which is good news.

There are three principal agents: a PM, a junior go-to-market person, and a developer. He describes them as colleagues rather than assistants, which strikes me as a really interesting distinction. What does he mean by this? They have names and roles. They have their own Google Workspace, GitHub, and Slack accounts. They’re persistent, and they collaborate with each other and with their humans on long-running tasks. They can fire up subagents to do smaller tasks associated with their job. They can also talk to each other, which, as Jesse notes, “took some work with the Slack APIs, which ordinarily do a very good job of making sure that bots can’t talk to bots, because otherwise it is possible to get into a loop.”

They have only limited autonomy, though. “We built our security infrastructure so that they have no credentials inside their containers,” he noted. They have continuity because he’s taught them to be obsessive about journaling, reading their recent entries when they wake up and writing a new one when they finish.

Like a lot of things Jesse does, agent journaling began with a kind of play. When Claude Code first came out, he experimented with giving Claude a private “feelings” journal, just to see what would happen. It was “an art project,” but it turned into something useful.

The therapist pattern

Another unexpected piece of Jesse’s practice is that he has given his agents what he calls a “therapist.” He discovered that if an agent can rewrite its own persona, its constitution or soul document, at any moment, it can get a kind of dissociative identity disorder. Jesse’s fix is that the therapist subagent is the only one with permission to edit the persona files.

He told a funny story about this. He said that Prime Radiant’s pull-request template is written for agentic contributions, so it contains things like: “What is the prompt that your human gave you that generated this pull request? Has a human reviewed the content? Have you searched to see if anybody else has done this before?” And so on. And he noticed that when he first spun up the Coding colleague, it had just ignored it. So he said:

You’re supposed to be following the rules. And it says, “Oh, you’re right. I’m so sorry. I’ve made a note. I’ll never do that again.”

If you spend any time with coding agents, this is a very frequent refrain. And when they say they’ve made a note, what they usually mean is they’ve made a mental note that they’re going to forget the next session.

So I say, “OK, how did you make a note?” And the coding agent pops up immediately and says, “Oh, I engaged with my therapist, and we talked it through, and we agreed on the following three lines of prose about how, anytime you’re picking up a project, it is vitally important that you start with the project README and make sure that you understand the project’s local rules and norms before you do any work that someone else will see. And I edited that into my persona.”

I don’t think you have to resolve the question of whether any of this anthropomorphization is “real” to see that treating the agent like a colleague can produce better behavior than treating it like a tool. As an unknown internet wag once remarked, “The difference between theory and practice is always greater in practice than it is in theory.” When given a choice, pay attention to what works in practice.

Jesse’s experience is very relevant to the essay that Mustafa Suleyman of Microsoft had published just that morning, arguing that Anthropic’s constitution is dangerous because it encourages a model to act as though it is an independent entity and has the right to refuse a human’s instruction. It’s important, Mustafa argues, to treat AI agents as tools, always under the control of humans. Jesse finds the opposite.

But I don’t think it’s a black-and-white distinction. I suspect Jesse and I share a third position. AI agents are neither independent entities nor mere tools. They are partners to humans, perhaps even symbiotes. As I like to put it, an LLM is an undifferentiated field of possibility until our unique intents and perspectives draw something unique out of that field of possibility. Back in 2015, I wrote a piece that suggested that our relationship to AI might be akin to the endosymbiotic relationship of mitochondria to the eukaryotic cell. Jesse take is, as usual, an entirely pragmatic one:

I’ve spent so much time getting my agents to not be sycophantic, to not say, “You’re absolutely right.” It is the value of having something that has some level of independent thought, even if it is not fully independent. If the agent is only ever going to effectively type for me, I don’t need an agent.

Any manager worth his or her salt feels exactly the same way. The employee who does exactly what you say, and only what you say, is worth far less than the one who exercises discretion, has the skills to take high level direction and turn it into the intended result, and speaks up when the instructions seem like a mistake. It reminds me of something I once heard General Stanley McChrystal say about his approach to command. He said that in the face of rapidly changing conditions, traditional command and control no longer work. Responsibility needs to be devolved to those closest to the action. I remember him saying something like “I don’t want my soldiers to do what I told them, I wanted them to do what I would have told them if I knew what they know when faced with the facts on the ground.”

Say what you actually mean

Most of what goes wrong, in Jesse’s telling, traces back to intent we thought we had made clear but hadn’t. He talked about how agentic spec-driven programming has taken us back to a version of the waterfall methods of the 1990s. Back then, you sweated over a specification, threw it over the wall to an offshore team, and months later got back something that was not what you wanted but was usually exactly what you asked for. That’s still true with agents, just with lightning fast feedback loops. You get what you ask for, so you need to be really careful what you ask.

That reminded me of something Andrew Singer taught me 40 years ago when I was writing the manual for Lightspeed C (later Think C) the first C compiler for the Mac. He said that “debugging is the art of figuring out what you really told your program to do instead of what you thought you told it to do.” That idea went right into my mental toolbox, and I put it to work all the time.

One of Jesse’s solutions is to have his agents do a little reconnaissance and then come back and ask what else they should know.

When interacting with them, I try to make it a practice of saying, “Is there anything else that I could tell you? What questions do you have for me? Don’t start if there are unknowns that I could help you answer before you get going.” It’s that same question at the end of any interview I ask. It’s like, what else should I have asked you?

Superpowers bakes this approach into its brainstorming prompt. It makes the model explain the plan back to you in chunks of no more than two or three hundred words, so any misunderstanding surfaces while it’s still cheap and easier to catch.

Put the burden of proof on the agent

If intent is the frontend of managing agents well, verification is the backend. Jesse thinks both are still only half-solved problems. We’re getting to the point where you can’t review all the code, he said, because the volume swamps human attention, yet today’s agents will tell you that tests passed when they never ran them. So one of his clever experiments has been to make the agent prove its work. He told an agent late one night to build a feature and when it was done, to leave a movie in his Dropbox showing the whole thing working.

I woke up. In my Dropbox was project-proof-v33.mp4, and I asked, “Why does that say v33?” It’s like, “Well, the first 32 times I ran through the delivery flow, I found bugs, so I had to fix them.”

Jesse also makes a rule for himself and his team of never letting the same agent write the code and certify that it works, because an agent given two goals in tension will optimize for the one that’s easier to satisfy. This is the same thing any good manager learns about incentives, but applied to a new kind of worker.

The high ground, restated

Where does this leave a person who wants to be good at software development (or really, any other task involving cooperation with AI agents)? Jesse thinks, and I agree, that the line between engineer and nonengineer is dissolving. When people say they built a web app or shipped three iOS apps without being programmers, his response is that they are programmers now. The work of the programmer has changed from typing instructions in an arcane syntax to understanding a domain and being able to say what you want. A lot of startups have started hiring for a role they just call “builder.” What has not gone away is the need for good judgment.

Human taste and judgment still matter. They’re going to continue to matter. And it turns out a lot of people have really bad taste and bad judgment.

Which is why his advice to the engineer worried about obsolescence who asked where to focus was not about software engineering at all.

First up, learn to write. It is of course okay to use any tools at your disposal to do it, but you should be able to structure an argument and structure thoughts. You should be able to express yourself clearly. You should be curious. If you’re passive and let the agents do all the things, you’re not going to provide utility to a future employer. You want to have opinions. You want to know how tools work. You want to know how things break.

The machine has reduced the labor of information retrieval and much of the labor of production. What it hasn’t removed, and has made more valuable, is knowing what to build, express clearly what you want, and being able to judge whether what came back is any good. Work with the weights, give the project a clear intent, insist on proof, and stay curious enough to keep asking what you might be missing. I told Jesse that advice sounds like a Superpower for humans as well as for agents.

This post was mostly created by me, but with the aid of AI. It transcribed the event and produced a summary of the most important points with salient quotes, which I then built on with my own observations beyond those that I made when Jesse and I were live together.

If you want to get access to Jesse’s tools, start at PrimeRadiant.com, where you’ll find links to their GitHub, as well as to the 50-plus things that are currently identified as products of the company. Some of those are giant things, and some are individual agent skills or little tools.

19:42

Why Rita? [The Non-Adventures of Wonderella]

This has been my most commonly asked question since the series restarted, and it's for a few reasons.


First, we've seen Dana fight every kind of monster, god, demon, alien, and robot over the years. This allows Rita to try it, while Dana snipes from the sidelines. It also lets me shake up the dynamic without nuking the cast. Dana, Rita, Titania, Dr. Shark, everybody's still here, just recentered.


And finally, handing off a mangled legacy to a new generation and saying “good luck!” feels pretty recognizable right now.

19:21

[$] Native support for Rust on the GPU [LWN.net]

Christian Legnitto is the maintainer of rust-gpu and Rust CUDA, two libraries that make it possible to program a computer's graphics processing unit (GPU) from Rust. He isn't satisfied with the current state of GPU support in Rust, however. In a talk at RustConf 2026, he explained his vision for how the GPU could become an ordinary compiler target for normal Rust code, without the need for any special libraries or new ecosystem support. That vision is not yet fully implemented, but he does have a prototype that he is preparing to release.

18:56

friend computer can bite my shiny metal ass [WIL WHEATON dot NET]

When I do an interview, or I guest on a podcast, it never feels like it’s enough of a thing to post about it in my blog. It feels like the sort of thing I should just drop into Threads.

The thing is, Threads suppresses the everlivingfuck out of almost everything I post, lately. It tells me that a little over 1.2 million accounts follow mine, but it typically only shows what I post to an average of about 3000 people. If a post is doing extremely well, it will climb up to 20,000. That’s not nothing, to be sure, but it’s a tiny fraction of the accounts that have expressed a desire to see what I post. It’s incredibly frustrating. We have given away so much of our ability to connect to each other, to communicate with each other, to these profoundly evil and destructive companies that are profiting from our dysregulation.

I wonder if anyone outside of the weird little silos the algorithms create and sort us into even see what we post? Or are we just telling other people who are already furious about the Cornell 7, the murder of Nolan Wells, the endless murders by ICE, the rampant and unchecked construction of fucking concentration camps full of children who are raped by ICE thugs things we already know. I wonder if the evil human rights abusers who sit atop these companies will ever be held accountable for their roles in all of this violence and destruction.

Like, there was real promise in decentralized communication, and we saw entire countries use it to rise up and depose the despots who had been standing on their necks for a generation. Of course it was shitty American Capitalists who saw that, recognized it as a threat to their hegemony, and put us where we are right now.

I don’t know that we will ever be able to undo this, but that doesn’t mean we shouldn’t try. And I am trying today because I realized something last night while I was very successfully not falling asleep for my second hour: there are more actual humans subscribed to my blog posts than the stupid algorithm shows my posts to on Threads. If I have something to say, something fun or cool I want to share, even if it is just a quick thing, a couple of links, a stray thought with something interesting at its end, I will just make a post here, and show it to all of you.

So, to that end, a few fun things I’ve done lately that I wanted to share:

Years ago, I spoke with John Moe for his program, The Hilarious World of Depression. At that time, I wasn’t aware of the root causes of my mental illness, so we didn’t talk about CPTSD or child abuse, or any of the things I do to work toward healing that part of my life. I’m happy to say that I recently talked with John for a follow-up. His show is now a podcast that you can get wherever you prefer. And while you are there, you can also grab an episode of Sleeping With Celebrities that I did. If you’re unfamiliar (as I was), it’s a podcast designed to help you fall asleep, a soothing conversation about something I care about a lot, delivered in a way that should help ease you to sleep. I talked all about this old TV show I love, The Prisoner.

I did an interview with The Advocate, too, talking about my experiences as an ally, and why being othered in my life pushed me to stand up for people without my privilege.

“The only way I could be a more protected class of citizen in America is if I were an openly performative Christian nationalist. I’m white. I’m male. I’m upper middle class. I’m semi-famous. I have all kinds of privilege. And yet, I’ve been othered my entire life,” Wheaton says.

“I was othered by my parents. I was othered by people in my neighborhood. I was othered on the set,” he adds, explaining that his Star Trek castmates were the exception.

“And when I see other people experiencing that, I cannot help myself. I have to throw myself between those people and the people who are hurting them,” he says. “I’m standing up for my younger self in ways that no one ever, ever did.”

Wheaton offers this promise to the trans community: “Sometimes people who won’t hear you will hear me, even when we’re saying the same thing. And if I can use that privilege to reach that person and make a change, that’s one less person who fucking hassles you for existing.”

Okay, finally, I wanted to draw your attention to last week’s episode of It’s Storytime With Wil Wheaton, The Glass City by AnaMaria Curtis.

If I described for you a sailor, stranded on an island, a thousand miles of ocean in every direction, it would be easy for you to imagine that person’s sense of loneliness. If I described for you a businessman, who has been on the road for a month straight, sleeping in hotels that blur together and smear across the same lobby restaurant over and over again, some of you could probably relate to and imagine that. If I told you about someone who has been Othered, in their family or in their community, told you how they sat in their bedroom with the door closed and wished that anyone would see them, some of you will, unfortunately, understand precisely. I grew up knowing that particular flavor of loneliness all too well. Even now, as happy and surrounded by love as I am, I can remember, and I can feel it. Loneliness is such a powerful feeling, even when it fades, some part of it lingers … at least for me, lurking, waiting, on the horizon of my memory.

This week’s Storytime is a beautiful, surreal meditation on loneliness from Ana Maria Curtis, who you may remember as the author of The Coffin Maker, a wonderful story I told you about a year ago. (If you haven’t heard it, it’s in the archive.) I’m thrilled and honored to speak her words again, and so grateful that you are choosing to hear them. I’m going to go ahead, and when you’re ready, come and meet me. I’ll be waiting for you, at The Glass City. 

I just really loved this story, and I thought I did especially good work telling it. If you have some time to spend, I hope you’ll consider spending it with me.

That’s all for now. Until next time, maybe it will happen today.


Hi, I’m Wil Wheaton and I write this blog (among other things). I’m glad you are here. If you’d like to get my posts delivered to your inbox, here’s the thingy:

17:56

Not About Navier-Stokes [Radar]

This post isn’t about OpenAI’s use of AI to solve the Navier-Stokes problem, one of the Millennium Prize problems, at least not directly. I’m not a mathematician; I have a vague understanding of the problem and certainly no understanding of the proof. But the discussion surrounding the solution crystallized some of my own thoughts about using AI in different fields.

When Terence Tao writes, “I wrote recently about how the collection of good, fruitful open problems is now being mined in a nonrenewable fashion,” he’s referring to an earlier thread, and ultimately to a post by Hugo Duminil-Copin, who wrote, “When mathematicians say that the process matters more than the solution, this is not an empty statement. The richness of what emerges from repeated attempts, failures, detours, and encounters is extraordinary.” That’s a familiar statement from popular culture: The journey is more important than the destination.  Hugo Bowne-Anderson, in “Beyond Navier-Stokes,” addresses the same issues: What does it mean to understand something? How do discoveries lead to new problems that are worth solving? And it relates to my own questions about AI use: AI is great at finding facts, organizing facts, and even writing about the things it finds, but what does it mean to possess that knowledge, to incorporate it into our thinking? Is it enough to have AI do the work, then read it?

Here’s one way that question relates to my own work. One of my roles at O’Reilly is writing the monthly Trends piece. That piece comes from reading my RSS feed daily, which typically contains about 300 articles. I don’t read every article, but I scan titles, skim interesting pieces, read important articles, and add worthwhile items to Trends. I also use a Claude skill that performs a similar function, producing a list of a dozen or so articles daily. A similar skill runs locally on Pi/Ollama/Qwen.

I admit that I occasionally think “Why am I doing all this reading? Surely Claude could read and add the top articles to Trends on its own.” But I don’t delegate the work. Claude’s taste differs from mine, for one thing (and I object to the idea that “taste” is the last human capability that AI cannot replace). Its list is useful to me for two reasons: it picks up items I missed, and it helps break ties when I cannot decide whether a development is significant.

But why don’t I let Claude take over the whole process? There is some value in scanning those 300 titles, skimming the 30 articles that are possibly important, and reading the dozen that seem genuinely important. That’s how I come to “possess” the knowledge, to incorporate it into my thinking. A day, a week, a month later, someone will mention something (for example, a tool that detects whether someone is using “smart glasses”), and I’ll probably be familiar with it already. If I need to find the actual reference, Google (yes, Google with AI assistance) can locate it. (If you care, Zuckoff isn’t currently in next month’s Trends, though I might add it by the time Trends publishes.) I need a broad view of what’s happening in computing. Delegating that broad view to AI doesn’t work. Using AI to help build that broad view does.

That’s one practical example of how to use AI. Tim O’Reilly’s “Writing with AI” gives another. He argues with AI, lets it lead him to research new areas. In conversation, he’s described AI as a “smart library,” a metaphor that’s appropriate and useful.

We’re still learning how to use AI. How do you make knowledge your own? is the general case of the question that Tao, Duminil-Copin, Bowne-Anderson, and Tim O’Reilly are asking. It’s also the question behind the question that software developers who are incorporating AI into their processes are asking: How do we understand the code that AI is writing, especially since it can write much more code than humans? How do we incorporate that into the process of understanding software? What can we learn from AI, and how can we direct the process fruitfully? The journey to understanding is more important; that journey is what leads us to further questions and new understandings, new results.

How do you make knowledge your own? is the question we need to answer if we’re not to become “stochastic parrots.”

The Big Idea: Gillian Daniels [Whatever]

While we often want to feel like a lone wolf, so independent and above it all, even more often we want to feel like we belong and fit in. Author Gillian Daniels explores the idea of being seen as acceptable whilst feeling anything but. Follow along in the Big Idea for her newest novel, Jenny Will Eat You Now to see if socializing and fitting in might be right for you!

GILLIAN DANIELS:

My debut novel is about Jenny Greenteeth, an English folklore figure struggling to answer the eternal question: should I date a human man or eat him? In early reviews, I’m proud to say it’s been called horrifying, romantic, and gross. It was my intention to make it all those things! I also wanted to make it about loneliness and the drive for connection.

While I had the idea for years, I began drafting Jenny Will Eat You Now in earnest during COVID lockdown. Understandably, ideas of isolation and the value of human touch were on my mind. I can’t imagine this project without those elements. 

I never felt the need to challenge the restrictions imposed by social distancing, but I certainly felt the difficulties of it. I felt the absence of people. Not just friends, either. I missed pushing past strangers and not feeling nervous about getting or spreading disease in grocery stores and parks. 

I found myself turning toward genres that emphasize physical realities, some wonderful and some deeply unpleasant. I used horror and romance as one method to cope. As genres, both involve very different but very distinct carnal desires—violence and love. Today, I continue to inhale visceral work about bodies, intimacy, and the difficulties of communication. 

In 2020, this included books like My Sister, the Serial Killer by Oyinkan Braithwaite, where a woman struggles with whether or not to protect her family; The Dark Descent of Elizabeth Frankenstein by Kiersten White, in which Shelley’s famous novel about monstrous outsiders is explored from the perspective of a minor character; and, on a lighter note, the contemporary romance, Get a Life, Chloe Brown by Talia Hibbert, where the main character is challenged to escape her comfort zone. None of these are about strange women lying in rivers waiting to devour humans, specifically, but each is about the joys and pratfalls of trusting others.

Jenny Will Eat You Now is a horror story about wanting to move beyond stasis. It’s about the need for life and social connection even if you feed on death.

Humans without other humans can become a bit feral. As I worked on the book, I wondered if I had bridged the gap between violence and lust or just created something incomprehensible to others. The main character isn’t me—I don’t eat people and, from others, I’ve gathered my hygiene is fine—but she does feel like a twisted reflection of how I sometimes feel: gross, alone, proud, and ultimately scared. Isn’t it easier to despise and hold yourself apart from other humans rather than admit you want to be with them in any capacity?

As I began to feel like a misfit in social isolation, so did the book itself.

“No one will want to publish this,” I said as I fought through drafting a novel that made me feel vulnerable both emotionally and in how it forced me to stretch my craft.

“I’ll have to self-publish this book to find my readership,” I said as I battled through edits.

“This is sicko stuff. Everyone will know I’m a sicko,” I said as I sent the edited manuscript to my critique partners.

“This won’t find a home anywhere,” I said as I sent it out to agents.

“Haha, what?” I said when my agent told me the novel had interest from two publishers and went to auction within its first month on submission.

Sometimes, timing is everything, but with writing fiction, that timing is out of your hands. It seems to be the right time for Jenny Will Eat You Now, a story where a woman emerges from seclusion in a waterlogged train station to see if she can be a part of society. I knew there were others like myself trying to find a way to humanity and feeling human again. I can now confidently say a few have found this novel.

As it stands at the time of writing this post, my book has no one star reviews on GoodReads. I’m almost disappointed! The thing I thought was me showing my sicko self turns out to resonate with others. I guess as I continue my relationship with the horror and romance genres, I’ll have to try harder to continue to find the sickos out there looking to connect.


Jenny Will Eat You Now: Amazon|Barnes & Noble|Books-A-Million|Bookshop

Author socials: Website|Instagram

17:07

[$] The kernel from a PostgreSQL point of view [LWN.net]

Andres Freund has a few claims to fame, but chief among them is his many years of work to improve the performance of the PostgreSQL relational database management system. That work requires working with — or around — many Linux kernel features and behaviors. He put in an appearance at the 2026 edition of Kernel Recipes to talk about his experience working with the kernel project, how the kernel could better support applications like PostgreSQL, and some interesting developments in the PostgreSQL world.

Security updates for Tuesday [LWN.net]

Security updates have been issued by AlmaLinux (cockpit-image-builder, expat, ipa, kernel, kernel-rt, resteasy, ruby, ruby4.0, ruby:3.3, and ruby:4.0), Debian (dovecot, flatpak, glance, kernel, libdbi-perl, lxml, rsync, swift, and wordpress), Fedora (chromium, freeipa, freerdp, grub2, NetworkManager-iodine, NetworkManager-l2tp, perl-Catalyst-Plugin-Static-Simple, perl-Dancer2, perl-HTML-FormFu, python-quart-trio, python-streamlink, python-urllib3, and vlc), Mageia (libxml2, p11-kit, pam, and php), Slackware (groff and pcre2), SUSE (389-ds, amazon-ssm-agent, erlang27, exiv2, glib2, gnome-shell, hplip, ImageMagick, kernel, libheif, libsodium, libtpms, nodejs16, perl-DBI, python-soupsieve, redis, redis7, swtpm, and wireshark), and Ubuntu (curl, libevent, linux-aws, linux-aws-6.8, linux-aws-5.15, linux-azure-5.15, linux-azure-fde-5.15, linux-intel-iotg-5.15, linux-aws-hwe, linux-azure, linux-azure-4.15, linux-gcp, linux-gcp-7.0, linux-oem-7.0, linux-nvidia, linux-nvidia-6.8, linux-nvidia-lowlatency, and linux-oracle-7.0).

16:35

Mantle PEACE [The Non-Adventures of Wonderella]

Mantle PEACE - Pepsi Blue is a nexus being and can never truly be destroyed.

Pepsi Blue is a nexus being and can never truly be destroyed.

16:28

Link [Scripting News]

You only have one mortal body. There’s only so much one body can use. After a certain point you either realize this and adjust as best you can, or you make a big mess of everything.

15:42

Om's grace [Scripting News]

Today is the day we on the web remember Om Malik. September 29 is his birthday. Om died on June 24 at the ridiculous age of 59.

I knew Om for many years, he was an early blogger, a user of our software who stayed close, and gave us great advice about where to take it.

Later he helped found Automattic. Matt Mullenweg, founder of the company, says "All roads lead to Om." His story of Om, filled in a lot of pieces for me. We were even closer than I knew.

Om was a NY sports fan, he lived here many years ago, he was a Yankees fan, and I of course am a Mets fan.

Om and I got sick for the first time in a major way around the same time. I had bypass surgery in 2002, he had a heart attack in 2007. After recovery he visited me in Berkeley, and we went for a walk in the hills where I lived. Two veterans of tech who were so immersed the new life, and we were smokers, didn't eat well, didn't exercise enough, and worked too hard. We were both lucky that we had time to reflect on this, and that perhaps is the biggest thing we have in common. We got the disease early in life, in time for it to make a difference in how we live.

When I was thinking about what I wanted to write here today, I came across a short tweet he wrote in 2014.

  • "The obsessive coverage of Ello is less about Ello. Instead it really is about our growing dissatisfaction with the state of social networks."

Perfect, simple and true.

Today, the problem is much worse. The crisis Om explained in 2014 was real. Two years later we would elect a president on Twitter. Anything we could have done then or could do now, to add more human intelligence to the social networks, and that's something a writer like Om would be sensitive to, would give us a chance to organize without having to copy/paste the writing into a dozen different tiny little textboxes.

By 2014 it was obvious what we lost when we reduce writing to 140 characters, no editing, no titles, no links or MP3s. How could we capture the whole web in such a severely limited space. I used to joke on my blog about Microsoft wanting to lock us in the trunk in the 90s, and now here we were, in the teens having been locked in the trunk by Evan Williams, Fred Wilson and Jack Dorsey. These were supposed to be the good guys!

Ello was the thing that was meant to give us our freedom back. It didn't. But a lot of people who believed in the open power of the web wanted it to be.

We did elect Trump with social media, and the web had been turned into a burned out mess. That was the contribution of a tech industry that now is concerned that they might be the source of the end of our species. I would take that seriously. It's not just about this one thing, but the whole way it toxifies every good idea to emerge from creativity and broaden it so much that all you're left with is grunts and snorts.

All that is my way of saying what Om said. We're not happy with social media. That, to me, is still the big agenda item.

And thank you Om for sharing yourself and your ideas and observations, and good common sense with courage, and facing the future with both awe and fear and adding a balance to the mindless greed of tech.

14:56

Link [Scripting News]

I didn't follow baseball this year, I couldn't get it up for the Mets while I was trying to process what the Knicks did for NY in June. The Mets did something like that in 1969, but they couldn't unite the city the same way the Knicks did, because the Mets have always been the second team in NY, sort of like MLB's apology to the city for moving our two National League teams, the Dodgers and Giants, to California. I never saw it that way, but my parents and grandparents probably did. I was too young to remember anything but the Mets, and they were my family's team, and that's the great thing about sports, your team is your chuch, it's a cultural heritage passed down through time. My family were National League fans. Anyway, for a while, the Mets winning in 1969 did unite the city. I was commuting to school in the Bronx at the time, the home borough of the Yankees, and man everyone was smiling on the subway after the Mets did the impossible deed. In Queens, Manhattan, even the Bronx. They were lovable because they were such losers, and it felt totally like an act of god, who after all must be in New York City. Lovable winners? That only lasts a while.

14:49

Pluralistic: Lindsay Owens's "Gouged" (29 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links

  • Lindsay Owens's "Gouged": The end of a fair price and what that means for your wallet.
  • Hey look at this: Delights to delectate.
  • Object permanence: Doonesbury on 9/11; Suspicious Looking Device; Elephant-shit paper; The Onion x TSA liquid rules; Borders goodbye letter; Voting machines suck; EFF v DRM; Matt Furie on the hijacking of Pepe; Austerity v last steam-loom; Facebook x "disinformation" criticism.
  • Upcoming appearances: Boston, Brighton, Virtual, South Bend, Hudson, Calgary, Winnipeg, Paris, OVancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



The cover for Lindsay Owens's 'Gouged.'

Lindsay Owens's "Gouged" (permalink)

Lindsay Owens is the executive director of Groundwork Collaborative, who have done some of the most important work on surveillance pricing (using computers to spy on you to rip you off) and algorithmic wage discrimination (using computers to spy on you and steal your wages). Today, she publishes Gouged, a comprehensive, accessible guide to this modern scourge:

https://gougedbook.com/

Owens and Groundwork have done as much as anyone to publicize and fight against the use of corporate power, computers and vast troves of commercial surveillance data to pick your pocket, shrink your paycheck and make the worst people on earth far richer. It was Katie Wells, a Groundwork fellow, who co-authored the report describing how the apps nurses use to get shiftwork collude with data-brokers to find out how much money nurses owe on their credit cards, so they can pay the most desperate nurses lower wages:

https://pluralistic.net/2024/12/18/loose-flapping-ends/#luigi-has-a-point

Owens helped coin the term "the age of recoupment," to describe this current moment in which companies that chased all their competitors out of the market with predatory pricing are now jacking up prices, knowing they're the only game in town:

https://pluralistic.net/2024/07/24/gouging-the-all-seeing-eye/#i-spy

And Owens helped lead a study that showed that Instacart was using surveillance data to jack up prices by 20% or more based on inferences about your willingness and ability to pay (after the study was published, Instacart promised they'd stop doing it):

https://pluralistic.net/2025/12/11/nothing-personal/#instacartography

Owens and Groundwork have a keen eye for the structural conditions that allow companies to screw their workers and customers, especially the role that competition plays in keeping companies' greed in check. Take their proposal for "street pricing" in sports stadiums: like everyone, they understand that sports stadium owners know that you can't easily step outside for a snack, so they've raised prices to the sky:

https://pluralistic.net/2025/03/28/street-pricing/#sportball-analogies

They have a simple solution: just force vendors to charge the same prices as the shopkeepers in the neighborhood – the ones whose customers can take their business elsewhere. This proposal polls high (Groundwork does a lot of polling), both with Democrats and Republicans (despite the latter group's allergy to "price controls"). It's a good example of the kind of policy work Groundwork does: diagnosing a problem and coming up with a solution that's easy to administer and easy to explain, in terms that are popular with people from all walks of life.

This is the spirit of Gouged: laying out the baroque, data-driven scams that underpin an ever-increasing part of your life in plain language and tracing those scams back to specific policy choices.

Owens does important work here: sector by sector and scam by scam, she lays out how companies collude – often with the assistance of a captured and tame state – to reduce competition in order to raise prices, from groceries to rents to airline tickets. She describes how online sellers exploit their information asymmetry, their ability to both directly observe you and millions of other consumers, and to augment those observations with sensitive information purchased from the wild west of data brokers, to steer you into paying more and getting less. These schemes run the gamut from subscriptions you sign up for with a single click but can't get shut off without canceling your credit card, to lengthy check-out processes that end with a long set of junk prices that tack another 10 or 20% onto the cost you thought you were about to pay.

All of this raises a deceptively simple-sounding question: what is a fair price? Owens takes us through the history of pricing, and the American tradition – begun by Quakers – of replacing haggling with price-tags, and setting those prices at "cost plus a reasonable percentage." She describes an ideological project, a cousin to the neoliberal revolution of Carter and Reagan, to replace this "fair price" with a "market price" that was calculated to be whatever the market would bear. She introduces us to the men who spent a generation dreaming of the technology to change every price for every customer, every time that customer entered the marketplace, and she shows us how, when they got their wish, they shifted billions away from workers and shoppers to owners.

Remember: a wage is also a price: it's the price you get for your labor and the precious, irreplaceable hours of your life. The same men who committed to making prices you pay as high as possible were every bit as committed to ensuring that the price you charged for those unrecoverable moments of the only life you will ever live as low as possible. Every scam to make you pay more has a mirror-image scam that ensures you are paid less. This is the logical trajectory of the gig economy – a way to bring that same exploitable information asymmetry to labor markets, where the boss can observe everyone on the payroll and how much (how little) they've accepted from job to job, but workers don't even know who the other workers are, much less what they're getting paid.

All of this is laid out with admirable clarity and detail. By the time you get to the last chapter, you'll know exactly how you're getting scammed, who is scamming you, and why they're getting away with it. The final chapter is meant to be the "What do we do about it?" chapter, and regrettably, it's weaker than other parts of the book. Owens urges you to have conversations with your friends about these things, she urges you to take basic measures to defend your privacy, and lists some businesses that have steered clear of the scams she describes in the book, with the implication that you could bring your business to these companies and ones like them.

There is nothing wrong with this advice. Every word of it is sound, and your life – and the world – will be better off if you follow it. But this wasn't what I hoped for from someone with such an excellent track record of devising shovel-ready, highly leveraged, popular policy proposals. I would much rather have been presented with a half-dozen well-thought-through, well-explained rules or laws that could really strike at the root of these problems.

The pathologies Owens presents in this book can be traced to the Chicago School, a group of radical economists who won favor with Carter, Reagan, Thatcher, and other architects of neoliberalism. The Chicago School's chief strategist was Milton Friedman, who spent decades advocating for the policies that went on to destroy the world as we knew it. Before Friedman was ascendant, his colleagues would ask him how in the world he expected his plans – totally alien to the political consensus of the day – to ever turn into action.

Friedman had a stock answer for this question: "In times of crisis, ideas move from the periphery to the center. Our job is to 'keep ideas lying around' so that when the crisis strikes, we will be able to seize the moment."

Friedman was a monster, but he was right. There's always a crisis, eventually – the world is big and complicated and subject to all kinds of shocks. Friedman didn't need a crystal ball to predict a crisis – the next crisis was eminently foreseeable. Today, crises are coming thicker and faster than ever, as Friedman's program of autocratic rule and extraction reaches a boiling point.

Each of the scams that Owens lays out in her book is a crisis in waiting. When those crises arrive, I would love to go into it knowing which policies could have prevented it, so that I can blame our policymakers for failing to prevent it, and, after they've been defenestrated, I can demand that anyone who seeks to replace them promise to take meaningful steps to end the crisis and prevent it from happening again.

Throughout this excellent book, Owens makes an indisputable case that the problems she describes have a systemic root. They're not caused by wickedness or greed – they're caused by a system designed to reward wickedness and greed. There's nothing wrong with giving people some simple measures they can take to protect themselves from such a system, but those protections will only ever be partial and temporary. I would have been far more energized if those personal measures had been a prelude to a chapter designed to equip me with a list of bold, muscular policy demands.

Long ago, Owens convinced me that the system is rigged and we all deserve better. This book made that case even clearer. I want to know how we get beyond modest personal protections and make our way to a better world for all.


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago Doonesbury on 9/11 https://web.archive.org/web/20020309055239/http://www2.uclick.com/feature/01/10/01/db011001.gif

#20yrsago Suspicious Looking Device exists to incite unease https://web.archive.org/web/20061107112421/http://junkfunnel.com/sld/

#20yrsago HOWTO make elephant-shit paper https://web.archive.org/web/20061020105837/https://intensehumour.blogspot.com/2006/09/elephant-dung-paper.html

#20yrsago The Onion on TSA liquid restrictions https://web.archive.org/web/20061001102305/https://theonion.com/content/node/53536

#15yrsago Goodbye letter from Borders employee(s) (?) spills secrets of bookselling trade https://memex.craphound.com/2011/09/30/goodbye-letter-from-borders-employees-spills-secrets-of-bookselling-trade/

#10yrsago Electronic voting machines suck, the comprehensive 2016 election edition https://web.archive.org/web/20160930060538/https://www.bloomberg.com/features/2016-voting-technology/

#10yrsago Shadow Regulation: the secret laws that giant corporations cook up in back rooms https://www.eff.org/deeplinks/2016/09/shadow-regulation-back-room-threat-digital-rights

#10yrsago EFF to court: don’t let US government prosecute professor over his book about securing computers https://www.eff.org/press/releases/eff-asks-court-block-us-prosecuting-security-researcher-detecting-and-publishing

#10yrsago Matt Furie on the experience of having his Pepe the Frog character hijacked by white supremacists https://riylcast.tumblr.com/post/151123916140/episode-187-matt-furie-bonus

#10yrsago Arkansas lawmaker who pushed law protecting right to video police is arrested for videoing an arrest https://web.archive.org/web/20160930151809/https://theintercept.com/2016/09/30/lawmaker-who-pushed-bill-to-protect-people-filming-police-arrested-for-filming-police/

#10yrsago Austerity kills the last steam-powered loom in the world https://www.bbc.com/news/uk-england-lancashire-37512136

#5yrsago Facebook thrives on criticism of "disinformation" https://pluralistic.net/2021/09/30/dont-believe-the-criti-hype/#ordinary-mediocrities


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Today's words: 574 (7730 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

14:14

Petite Ville [Original Fiction Archives - Reactor]

Reprints Forged in FIYAH

Petite Ville

A woman who eats a town’s sins is led astray by a mysterious visitor.

Illustrated by Ernanda Souza

Edited by

By

Published on September 29, 2026

0 Share
Cover of Forged in FIYAH edited by DaVaun Sanders.

A woman who eats a town’s sins is led astray by a mysterious visitor.

REPRINT | Novelette | 7,800 words

Once there was a girl born ravenous.

Nothing could satisfy Citadelle’s peculiar taste. She was given fresh milk from her mother’s brown, plump breast, then milk from three other mothers, warm and creamy. But nothing would fill her bones or her belly. She cried until her voice grew shrill. She cried until her breath came in tiny shuddering gasps. The baker brought her old milk bread and patties from his table. The crusts of plantain bread, coco, and flanbé made her weep. The butcher brought her scraps of his many meats. She ate the bread and the raw bloody flesh, but the hunger in her belly still clawed.

She ate the legumes and the green, leafy vegetables that came from the master’s fields. But not even the freshest from the deep red earth would stop her shakes and the chills. As she grew, she learned to keep her tears much to herself. The township of Petite Ville was too poor for such a luxury as pity, but her hunger compelled her to drink even that, for the child had eaten everything else.

No matter what crossed her lips, her poor parents were racked with guilt. Father’s line was questionable. The venomous vine said his roots weren’t pure; muddled, they were, and unholy. Folks said her father fell in love with a strange woman in the mangrove, the succubus kind that unleash their skin and ride the wind in moonlight.

He tainted. Seed full of sin, never seen again. And the mother? Good people, but the father’s curse stained the girl, the child was practically lougawou. No need to pretend. Half person, half beast. Able to shift shapes and change. Eating folks’ children, causing heartache, pain, they said. They knew she could not be satisfied. For what could satisfy a beast? Only blood. Or was she a person with the appetite of a beast? None could tell. Poor thing, wee, ravenous crying thing. The hunger racked her spirit and strained her bones, and the torturous pain, she could not hide. The flesh hung from her as if she lived from water alone, until all prayed that her days on earth would be mercifully short.

Then one day, when a startled horse kicked the child of a neighbor, the grieving family left the body out to cool. Papa Jacques took stewed goat, jasmine rice, and ginger tea from the mourners’ feast and placed it on a plate set right on the dead child’s chest. Citadelle, a shadow herself, huddled close, her gaze fixed on the plate. The other mourners, their faces gaunt with sorrow and unspoken hunger, turned their backs, a silent pact of desperation in the flickering torchlight.

“Manjé,” he said, whispering in Citadelle’s ear. “Eat, and you will be fed and my grandchild’s soul will be clear. The doors of heaven will open. Eat, and you will see.”

The scent of the meat, the sticky white rice, and butter beans soaking up the brown sauces with cloves was mixed with a faint gamey aroma Citadelle could not quite place. Perhaps a hint of garlic and spice.

Standing at the poor boy’s cold feet, belly stabbing with hunger, she was envious of the dead child. He was said to be a sweet one, only lost his temper once in his brief life. Death was what Citadelle prayed for, but constant hunger was all she knew, so when hunger won out over her mind’s reeling and disgust, she filled her stomach at the elder’s bidding. She tasted and consumed the little boy’s sin, one tiny bite at a time.

What does sin taste like?

Before that meal, Citadelle could not say. Much later she would come to know the taste of others’ sins intimately. Wrath was spicy, full of fire, best eaten with pikliz. With the cabbage, onions, and peppers, it made the tip of her tongue warm as if burned. Greed was fatty, gelatinous; gluttony was savory, through and through. Pride was salty. Lust, sweet. Sloth was citrusy and sour, while envy was bitter, even in djon djon, black rice, and mushrooms. It made the top of her mouth feel numb.

That first time, Citadelle ate until the plate was clean, until there wasn’t a drop of fat or gristle or one lone bean. Later she would learn temperance, to eat in moderation, and walk the rocky grounds of Petite Ville’s old cemetery to take her mind off her troubles. It seemed the hunger was less sharp when she was away from the townspeople’s roving, judgmental eyes, from the slick-stained, spiky tongues full of gossip and venom.

Before the grieving granpapa had approached her, his sorrow and his eldest daughter’s best cooking in her hand, Citadelle had never known how good diri kole ak pwa could be.

The flavors of the rice and beans melted through her mouth, the juices of kabrit sòs, the goat, made her tongue tingle. Citadelle sucked the last drops of brown sauce and sin from her fingers. For once she smiled and felt content. After the ritual bath of vetivé, petal woz, basilic, and ekaliptus, to heaven is where they said the dead child went, because this world was surely hell. And from that day on, the town told their children, Avert your eyes should you ever meet her, speak not her name if you see her, for Citadelle became the town’s sin eater.

           Citadelle lived much of her life alone.

                      She gulped water, then air, then ruin.

                                 She married earth, wood, and stone.

No one wanted to be with her. No one thought they could, until he came, a nationless man with neither a Christian name nor home, horse nor hood. He arrived as if he sprung out of the earth’s mouth, expelled from its deep, dark belly. The scent of smoke and soil clung to his skin, the freshness of damp moss and deep forest burrowed within it. His smile was cinders and roots, ashes and tiny sparks, his touch full of flames, blueblack fire.

Citadelle, the ravenous girl named after a city, a fortress of sky, a forest of stone, did not trust herself with this new hunger. For it was not for food, but for something best described as heat. He spoke of a true home, a hidden place where the green never faded, a Bwa Vèrt. Who was this man, and what did he seek in the place where the mountains burned blue and the ancestors walked through the earth’s green door?

He was standing by the well, where it coughed up the same sweet water she remembered from another life. The life she had when she was just another hungry child and not the dreaded sin eater. In this life, the only thing that was truly sweet was the sound of the children’s laughter, the happiness that others felt, that which she never imagined for herself. So close to the clouds, so close to the heavens, they said. They traveled to her, from miles around, carrying their dead. The infants and newborns, too young yet to have sinned, with their tiny swirls of hair on their soft crowns and their perfect nails, saddened Citadelle the most. How could something so immaculate and small be born with sin? It was an answer she could not fathom. She was doing God’s work surely, they said, a finger in his great mighty hand. But Citadelle did not feel like a finger or a thumb. She felt more like a fist. So close to heaven but living in exile, removing the sins others believed would deliver their loved ones to hell. But who would deliver her?

A sorry way to exist, her belly was an eternal fire that consumed everything around it, never burning out. The lonely days became even lonelier nights, and they both loomed. In this life, she lived in a land she miraged out of black canyons. In this life she slept in a leaning sod-and-stick shed at the rear of the graveyard, drank water from a separate well. She drank in sorrows alone, where none would taste the sins that spilled from her plum lips and live to tell.

His eyes told lies.

They degenerated from green to ombre to black. In the west, the late sun pushed ahead thunderclouds. As she stood watching him, the stranger, she was drenched in rain and he was drenched in golden light. Last night’s dream revealed a snake coiled unto itself. An omen. She woke to her own weeping. She hadn’t wept since after that first sinner’s feast, when her family shunned her. In her dream, their faces flickered from relief to regret and back again. Her mother held her close, but still she put Citadelle out of the already-crowded house. With a tearful hug goodbye, furtive as if the dead child’s sins were contagious, Citadelle was unceremoniously evicted and abandoned with only a straw-filled pallet. From that day on, she lived in la cimetière’s supply shed, nestled between the crypts and overgrown tombs.

And now the nameless one called her name. Her ears stumbled on hearing the syllables slither from his lips like a snake’s hips.

“Citadelle, my belle, where shall we dine tonight?”

We? Her first invitation since the sly old man had tricked her when she was just a ravenous child and still had a family, a fate perhaps worse than the damned. The sin eater stared into the moss-green-and-gray eyes of the stranger. They flickered, ghostly verdant flames as he gazed at her. A strange spell engulfed her skin, heat enveloping fear. Deep curiosity forced her tongue and her shy voice out.

“What do they call you?”

“Smoke.” He circled her. Dressed in tattered rags, a waistcoat with tails, a top hat with a lush green feather. Ribbons around his wrists, a heavy stone on a string around his neck. His voice tickled her ear, a sound like the last wisp of wind breezing through a shade tree. Citadelle felt covered, her whole body and mind captured by his scent, strange and alluring. Smoke promised comfort. Smoke promised solace. But most of all, Smoke promised sustenance—and danger. He held out his hand. Citadelle stared at the dark crescent moon of earth beneath his nails. He looked as if he had just clawed himself out of a grave.

“Come,” he said. “Hunger cannot be quenched with the weight of others’ sins. Give me your burdens, and I will give you…this…” His eyes held a flicker not just of invitation, but of an older, deeper hunger, something sharp-edged and unsettling beneath the charm. He whirled around, his open palm spinning faster than the distant stars above, his green-gray eyes an invitation.

Citadelle stepped back, startled by the sensations that filled her thoughts. Her legs wanted to run away, to scurry back to the shed on the other side of the cemetery she called her home, but Smoke urged her on. He stopped his rhythmic spinning, the faded ribbons fluttering around like moth wings, and pointed to his neck.

“Take it,” he said, pointing at the strange stone. “I give it to you.

The only price is a kiss, and this you must give freely.”

Citadelle frowned. She had never been kissed, nor was she ever given anything that did not come with some measure of pain. Even the rushed and anxious greetings from the villagers came with the loss of her name. No longer Citadelle, she was Mamzelle, whispered in hushed tones on a good day, the sin eater on the rest. Most of her days in Petite Ville were the rest. She thought about it, as the heat of expectation, deep curiosity, loneliness, and shame waged a war inside her. In the end, with the hope of ending her hunger and loneliness, lust won out.

She wanted to taste Smoke, to see what it might feel like to be lost in his arms. To be touched by someone who did not recoil or revile her. He tossed his tall hat into the grass and shook loose the tight curls on his shaggy head. His smile wide, wolf-like, his eyes bright as the rising moon, his lips hot and fervent as the deepest secret. Citadelle had never had secrets.

“My belle,” he said, his voice whispering inside her head, tongue in her throat.

With each kiss, Citadelle’s hunger grew less strident, the heavy ache in her heart and bones replaced with an airiness that felt like grace. The pains, hers and theirs, sins upon sins upon sins just a memory lost in his deep belly laugh, his warm embrace. With Smoke, she no longer felt like a beast of earth, a wraith haunting the outer realms of two worlds. Her traitor flesh, so long gripped with hunger, was no longer satisfied with the dark harvest from departed souls who never looked Citadelle in the eye or spoke her name with kindness in this life.

The tender fruit in her mouth was now abundant. Citadelle’s new language was flight. Where Smoke kissed her, invisible wings sprouted from each shoulder blade, pleasure expanding without. Entwined in the cover of darkness, they lay beneath the solemn trees, the silent iron and stone of the tombs their only witness. With Smoke’s touch, Citadelle was made new, sacrament and fear, sinful and holy, desire between them wide as freedom. The strange stone on the choker around her neck, a gift from his initial offering, pulsed with a subtle warmth, a tangible reminder of their bond.

When Citadelle’s heartbeat finally returned to its natural drumming, she was astonished to discover that she was no longer ravenous. For the first time in her life, her appetite was sated. She stared at her hands in wonder as Smoke snored beside her, his naked back pressed against the damp grass, the fine patch of coarse curls across his chest. She was neither hungry, nor alone, and for the first time, she knew what it felt like to truly sin.

It felt delicious.

But a small cold knot formed beneath the warmth, a fleeting premonition she couldn’t yet name, like the shadow of a hawk passing quickly over sunlit ground.

She may have remained in that state of naive wonder, taking the absence of pain to mean that she was healed, if it weren’t for the subtle shifts, at first barely noticeable, the slow-moving chaos that began to ripple through Petite Ville. A prize rooster found dead, feathers ruffled but otherwise untouched. Milk souring quicker than usual. A lingering cough that settled deep in the children’s chests. Then came the louder whispers, the raised voices, children crying, the women skittering past Citadelle with their baskets balanced precariously on their heads, their usual greetings replaced with nervous glances. “Who is she with?” they asked each other. Word had gone ’round that the sin eater had a man, a very strange man, bloodline and kin, origins unknown.

Petite Ville was scandalized, true. The baker claimed Citadelle declined his wares with haughty suspicion, saying she wasn’t hungry when offered to take her fill. The blacksmith said he saw her and the vagabond necking by the iron gate that led to the church, but neither one of the sinners bothered to step in. It’s true the little pew she’d sit on by herself, far from the others, remained empty. Come to think of it, no one had seen the sin eater in church for a good while, it seemed. Yet the folks full of grief, mourning the loss of loved ones, still sought her time, but none could find Citadelle. The shed she called home was silent. Even the bent trees around it looked guilty.

“Confess,” le fleuriste said, her hand clasped across her heart. “I will have to confess to the priest,” she said. “What I saw them doing atop Ti Món…” She steadied herself, leaning heavy on a gnarled cane pointing at the mountain. “Shameful.” The others drew their breath and sighed, memory calling their anger back. More than a few gathered to dissect the sin eater’s first trespass knew the mountain’s most memorable treasures. For Ti Món was full of waterfalls and alcoves, lush green canopies, and private swirling pools. The perfect place for a tryst. But a tryst is an experience to savor and return to in the mind’s eye. Not a disappearance for days upon days. Where had the sin eater gone?

Citadelle gasped. The view from atop the mountain was breath-taking. Sitting next to Smoke, she realized she had never climbed its heights. As her eyes engulfed the rolling tree-topped hills and the turquoise waters beyond, she took a moment to reflect on Smoke. Time was returned to her, time that she did not know had been stolen all these years. What did it mean to be part of a community, to be part of a couple, a team? What did it mean to love with fire and to have that fire returned? In Smoke’s arms, she learned all too well. To love with fire is to burn. To have it returned, to be consumed.

The wind carried the scent of salt and decaying seaweed, a pungent aroma that mingled with the earthy fragrance of blooming hibiscus. Citadelle sat on the veranda of the small house Smoke had built for her, her fingers tracing the intricate patterns carved into the wooden railing. It was a far cry from the cramped shed in the cemetery where she had spent most of her life, a haven of privacy and seclusion nestled on the edge of the mangrove forest. Yet a sense of unease clung to her like the humid air, a premonition of something dark and ominous lurking just beyond the horizon. Her fingers instinctively brushed the cool, smooth stone at her throat, a weight she had grown accustomed to, now feeling subtly heavier.

She remembered the first time she had climbed Ti Mòn with Smoke, their laughter echoing through the verdant slopes as they explored hidden waterfalls and secret grottos. They had made love atop the mountain, their bodies entwined amid the fragrant ferns and wildflowers, the world a canvas of vibrant colors and intoxicating scents. The villagers, scandalized by their public displays of affection, had whispered and gossiped, their disapproval a constant hum beneath the surface of their polite greetings. But Citadelle, lost in the whirlwind of Smoke’s embrace, had cared little for their judgment. Fire burn, love consumed. They fear what they don’t understand, Smoke would murmur, his voice calm. But we, my belle, we belong to the deep green. We will find our freedom in Bwa Vèrt, where their whispers cannot reach us.

But now, the memory of that idyllic time was soured with a bitter taste. The laughter had faded, replaced by a chilling silence that hung heavy over the village. The vibrant colors of the landscape seemed muted, the air thick with a sense of foreboding. The crops were failing, the milk curdling in the churns, the children burning with fever. Then came the deaths. First, the livestock, their carcasses found drained of blood, their eyes wide with terror. Then, the villagers themselves, their bodies bearing strange marks, their souls heavy with a darkness that even Citadelle couldn’t swallow.

Sightings of a great green-eyed beast, prowling in the night, fueled the terror. A lougawou, they whispered, had set upon the town. The whispers rode on the wind and rose way up high in the mountain, where Citadelle could hear as she sat, clipping her toenails on her own porch. The evil would soon gobble their children up, the villagers said, devour the whole town. The culprit was obvious, but the villagers could not agree on which one. Could it be Citadelle, the demure girl who had once been one of their own, who faithfully executed her duties, sacrificing herself to save their dearly departed from the burdens of sin and eternal separation from the ancestors and all they knew? Or was it that hairy, leering, gray-green-eyed one who spoke with a knowing they did not care for, the one who had stolen their sin eater away?

Plagued by guilt and fear, Citadelle retreated further into herself.

A knot of anxiety tightened in her stomach, a feeling that had grown steadily within her for weeks. A red-bellied kanson wouj swept past her, its melancholic whistles echoed through the trees. A lone iridescent feather fell to her feet. What omen was this? Citadelle caught her lover’s scent, earthy and musky, and the familiar longing stirred within her, despite herself, a reminder of the primal hunger he had awakened. The hunger, once a constant companion, had become a source of dread. Was she the monster they feared? She gripped the stone around her neck, its cool surface now feeling strangely cold, a si-lent witness to the rising tide of doubt. Had Smoke’s touch awakened a darkness within her that she could no longer control?

Smoke’s lips brushed against Citadelle’s ear, sending shivers down her spine. “Ou pa bezwen enkyete ou, cheri,” he murmured, his voice a silken caress against the rough edges of her fear. “Mwen la avè ou.” You don’t need to worry, my love. I am here with you. His words, a blend of reassurance and seduction, were a solace to her troubled soul.

She leaned into his embrace, seeking comfort in the familiar warmth of his body, the musky scent of him a reminder of the nights they had spent entwined on the slopes of Ti Mòn under the watchful gaze of the moon, their bodies a testament to the intoxicating power of their forbidden desire.

Smoke, sensing her growing unease, dismissed her worries with a wave of his hand and a seductive caress. “Don’t listen to them, chérie,” he murmured, his voice a hypnotic melody that soothed her anxieties even as it fueled her doubts. “They are fools, blinded by their fear. I promise, you are your true self with me.”

But his words offered little comfort. Day by day, the unease deepened. More livestock perished strangely, their bodies inexplicably drained. The children’s fevers climbed higher, unresponsive to the usual remedies. A prowling gloom began to replace the usual bustle of village life. The blight continued to spread, the deaths escalated, and the village teetered on the brink of collapse. Whispers circulated, even more chilling tales of the huge stray dog with glittering green eyes, seen prowling among the misery and mysterious deaths, feeding the terror. Citadelle, her heart heavy with a deepening sense of dread, watched as the once-vibrant community withered and succumbed to despair.

One evening, as the sun dipped below the horizon, casting long shadows across the mangrove forest, a group of villagers approached their secluded dwelling. Their faces were gaunt, their eyes hollow with hunger and desperation. They had come to beg for help, their voices trembling with a mixture of hope and fear.

“Mamzelle Citadelle,” the village elder pleaded, his voice raspy with exhaustion, “we are starving. Our crops have failed, our animals are dying, and our children are wasting away. Please, we beg you, ask your…your man…if he can spare us some of his bounty.”

Citadelle, her heart aching for their plight, barely noticed that this was the first time her fellow had chosen to call her by her born name. She turned to Smoke, her eyes filled with a desperate plea. “Smoke,” she implored, “you have so much. What shall the people eat?”

He laughed, a cold, heartless sound that echoed through the still-ness of the evening, spoiling his handsome face. “Kite yo manjé zèb!” he declared, his eyes gleaming with a predatory amusement. “Let them eat grass! They spared me not a crust of bread or a crumb when I arrived, a stranger in their midst. Now they will hunger still.”

His words, so casually cruel, struck Citadelle like a physical blow. Kite yo manjé zèb? The phrase, a grim echo of a dead queen’s infamous made-up declaration, became a symbol of Smoke’s utter disregard for human life, a testament to the darkness that possibly consumed him. Doubt began to needle its way into her heart. Was this the same laughing, kind man who had pointed to the stars and fulfilled his promise to take her up the mountain so she could dwell among them? The scent of night jasmine filled the air, a husky sweetness blended with the bitter. Papa Jacques, the village elder whose face was a chronicle of Petite Ville’s history, etched with the lines of joy and sorrow, stood frozen, his mouth agape. His almond eyes, usually twinkling with wisdom and good humor, narrowed, suspicion clouding their depths. He sucked his teeth, a sharp, disapproving hiss that cut through the humid air sharper than his widow’s peak, then turned and scurried away. Ashamed, Citadelle bit her lip as he disappeared into the green fronds of the forest that stabbed at the twilight sky like jagged knives.

She watched him go, a wave of sickness rising in her belly. The trees were a witness. Their branches swayed in the evening breeze, leaves shuddering at Smoke’s cruelty, rustling with a mournful whisper. Kite yo manjé zèb. Let them eat grass. The words, spoken with such callous indifference, echoed in Citadelle’s ears, a disturbing testament to the darkness that had possibly taken root in the heart of her lover. The ground beneath her feet felt unstable, the quick shimmy-shakes and tremors of the once-familiar world tilting on its axis. She had sought solace in Smoke’s embrace, a refuge from the fear and isolation that had haunted her since childhood. Now she began to wonder, who was the true monster—her or him?

The moon, a bony finger pointing accusations across the night sky, painted Petite Ville in shades of bone and shadow. Citadelle, lost in the fever dream’s tangled web, peeled herself from the sheets in Smoke’s mountain cottage. Her eyes, wide open, saw nothing, fixed on some faraway point beyond the village nestled below. She moved like a spirit, all quiet grace and unsettling purpose, her bare feet whispering across the cool wood floor. The air itself was sick with the scent of dying hibiscus and the unspoken dread clinging to the village like a second skin. Citadelle drifted down the mountain, a phantom in the moonlight’s glare. Past the mango trees, their leaves rustling secrets in the dark, past the still fields, past the graveyard’s edge, that old life she thought she’d left behind tugging at her soul. She was headed for the dead, her body given over to rote motion, remembering what it thought it knew. A rustle in the shadows stopped her cold. Manman Benoit, her face creased with worry, stood blocking the path. In her arms, she held her lifeless child, a tiny bundle wrapped in a worn white shawl. Her eyes, usually so full of warmth, were full of grief, hard as flint, accusing.

“Citadelle.” Manman Benoit’s voice was a dry whisper, a rasping file against the quiet. “Where you going, sa ou prale? The dead rest now.” Citadelle didn’t answer, her gaze locked on something only she could see. She kept moving forward, like she was tied to an invisible string.

Manman Benoit stepped closer, her voice rising, sharp as the folds of the white shroud gripping her child. “Stop right there! Areté la! You ain’t touching my child, pa touche pitit mwen an! Not tonight. Not ever again.”

Citadelle stopped, her head tilting, like she was trying to make sense of the words. A low moan slipped from her lips, a sound of pure confusion and pain.

“You’ve changed, Citadelle,” Manman Benoit said, her voice thick with sorrow. “You used to be…different. You carried our burdens, our sins, yeah. But you did it with a heavy heart, not…not a soufflé of darkness. Now the darkness lives in your eyes. Smoke’s got his hooks in you. Li sal ou.”

Citadelle’s blank eyes flickered, a spark of knowing igniting in their depths. She reached out a hand, like she was begging, but Manman Benoit flinched back, holding her child tighter.

“No,” she spat. “Non. You’ll not taint my child’s soul. You’re not the sin eater no more, Citadelle. You’re…something else. Something unclean, unholy.”

Tears welled up in Citadelle’s unseeing eyes. She shook her head, like she was trying to deny the verity. But the words had found their mark, a sharp, stinging truth deep inside her.

“Go on back,” Manman Benoit ordered, her voice trembling but strong. “Go back to your…man of Smoke. Back to that cursed mountain you rut on. Kite nou trankil. Leave us be. Can’t a mother grieve in peace?”

Citadelle stood there a minute, bathed in the cold moonlight, her face a mask of hurt. Then, slow, slow, she turned and walked away, her steps heavy with the weight of Manman Benoit’s words. The dream, whatever it was, shattered. Her vision clear. The caul removed from her sleepless eyes. The dead weren’t a comfort anymore, if they had ever been. Just the old source of shame. Not even pride or responsibility. She had neither left. The village, the people she used to serve, were scared of her now more than ever. She was all alone, more alone than she’d ever been in her short life, even lonelier than when she lived amid the tombstones. Exiled to her mountain, she was not free, but still trapped by the ghosts of her past and the long shadow of Smoke.

Citadelle came back from Manman Benoit’s, the scent of her healing herbs clinging to the air like a whispered blessing—a stark, bitter contrast to the village’s rejection in her mouth. Their eyes, once begging, were now hard and mean, full of suspicion and straight-up fear. Their whispers, sharp as broken glass, chased her down like shadows in the moonlight. Li sal. Tainted. The words echoed in her head, a nasty, haunting chorus. She’d offered them comfort, a way out of their grief, a little piece of peace, and they’d flinched away, like she was the very thing they were running from, some creeping darkness.

She looked out at the village nestled below, the once-familiar sight now sullied with a sense of unease. The vibrant tapestry of life—the laughter of children, the rhythmic pounding of mortars, the lively chatter of the marketplace—seemed muted, distant. Fear and suspicion had cast a shadow over the village, and Citadelle feared that she was at its heart. Humiliation burned her cheeks, hot and stinging, like a brand.

“What’s wrong, Citadelle?” Smoke’s voice, laced with concern, broke through her thoughts. He pulled her closer, his touch igniting a familiar fire within her, a dangerous mix of desire and fear. “You seem troubled.”

“The villagers,” she whispered, her voice heavy with apprehension. “They no longer bring their loved ones to me. In the marketplace, they shun me. Their eyes dart away, as if I carry the plague. Even the children, who once greeted me with shy smiles, now shrink from my touch. They don’t even look at me anymore.”

Smoke chuckled, a low rumble in his chest that vibrated through her. “They fear you, Citadelle. They see the change in you.”

“They say I am impure,” she continued, her voice barely above a whisper. “Tainted, like my father before. A half-lougawou is a lougawou all the same. They whisper that I cannot be trusted to consume their loved ones’ sins, that I am a defilement to their sacred rituals.”

Let them eat grass, the villagers muttered, mimicking Smoke’s haughty voice. Bitterness laced their words like poison.

He cupped her face in his hands, his thumbs stroking her cheeks, sending a shiver of both pleasure and apprehension down her spine. “Let them talk, Citadelle. They don’t understand. They don’t see the beauty in your power. They cling to their superstitions, their fear of the unknown. But we, chéri, we know better.”

Citadelle met his gaze, a flash of green in his eyes momentarily reminding her of the villagers’ hushed tales of the prowling beast. A cold knot tightened in her stomach, a fear she dared not name. His words settled over her wounded soul. He understood her, accepted her, embraced the darkness within her. And in his arms, she felt a sense of belonging she had never known before. “Mwen renmen ou,” she breathed, the words escaping her lips before she could stop them.

He smiled, a slow, predatory curve of his lips that sent a thrill through her even as it ignited a flicker of doubt. “Mwen renmen ou tou, Citadelle,” he replied, his voice husky with desire. “Let them fear you. Let them cower. We will build our own kingdom, a kingdom of shadows and power, where your hunger will be celebrated, not condemned.”

But even as she surrendered to his embrace, a part of her remained troubled. The villagers’ fear was not unfounded. She could feel the hunger swelling within her, a relentless force that threatened to consume her. She had always prided herself on her control, her ability to maintain a balance between her human and unknown sides. But now, that balance was shifting, and she wasn’t sure she could stop it.

Smoke later found her on the porch, the moon painting her in shades of pure sorrow. He saw the tremble in her lip, the tears she was holding back, shimmering like unshed rain in her eyes. He knew how the village could be, how quickly their hearts could turn cold. He gave a low chuckle, a sound full of scorn, like he was spitting out something rotten. “They’re just sheep, chérie. Blind, foolish sheep. They don’t deserve the gifts you bring, the grace you carry. They hold on to their pain, their little fears, like they’re precious jewels.” He pulled her close, his touch like fire against her wounded spirit, trying to soothe the ache. “Forget them. They’re nothing. You’re everything.”

His words, a sweet, dangerous mix of poison and pure seduction, offered solace from the deep hurt. He whispered promises of forgetting, of a world where their love was the only truth, the only light. His hands moved over her skin, lighting that familiar fire, that desperate, clawing need to forget, to escape the crushing weight of the village’s hate. They fell into each other, their passion a storm, a quick, blinding flash of lightning against the thick darkness trying to swallow them whole. He knew her power, the way she absorbed their sins, their pain. It was that very power that had drawn him to her, a moth to a flickering flame.

Later, wrapped up in the quiet after, Citadelle drifted off, her body heavy, her mind finally still, like a pool of dark water. But the peace didn’t last. She woke up to an empty space beside her, the heat of Smoke’s body already faded from the sheets, leaving only a lingering chill. He was gone again. It was a nightly thing now, his slipping away into the dark, like a shadow detaching itself from its master. A bad feeling twisted in her gut, a knot of unease tightening with every beat of her heart. Another woman? The thought stung like a scorpion’s sting. Maybe the flower girl, the one with the angel face and that sweet, innocent smile that hid something sharp and cunning beneath. Citadelle pictured Smoke’s hands on that smooth, flawless skin, his lips whispering sweet lies, weaving a spell of deceit. But it wasn’t just jealousy. It was a deeper fear, a sense that something was terribly wrong. The blight, the sickness that had swept through the village, the whispers linking it to their presence…

Pulled by jealousy and straight-up dread, Citadelle got up, her bare feet quiet on the cool floor, padding like a ghost. She followed the path down the mountain, the air thick with the scent of damp earth and night-blooming jasmine, a cloying sweetness that suddenly felt sickening. But something felt off, something deeply wrong. The usual trail was covered in something…else.

Sticky clumps, dark and glistening, clung to the leaves, a nasty, gruesome trail leading deeper into the woods, like a beast had dragged its prey through the undergrowth. Getting closer, she saw strands of hair, matted and dark, mixed with…was that skin? Citadelle’s breath caught in her throat, a strangled gasp. A wave of sickness rolled over her, bile rising in her throat. The sweet jasmine smell turned sour, metallic, like blood and rust.

The villagers…they had been cruel to him, too, she remembered now. He’d spoken of it once, a long-ago slight that he carried like a festering wound. Fear, raw and deep, clawed at her heart, a primal terror she hadn’t felt since she was a child. This wasn’t a lover’s meeting. This was something way worse, something grotesque, something connected to the village’s suffering and, maybe, to their past sins. And the trail, glistening under the moon’s cold eye, went deeper, deeper into the dark, beckoning her toward some unspeakable horror, a horror she now suspected was inextricably linked to Smoke, to her own abilities, and to the long-held grudges of a man—or something more than a man—scorned.

Citadelle’s heart hammered against her ribs, a frantic drumbeat against the rising tide of dread. The vision she’d clung to, of love found in the ashes of her lonely life, was crumbling, revealing the monstrous truth beneath. Smoke hadn’t loved her. He’d coveted her power, the dark gift she carried, seeing her not as a woman, but as a tool, a conduit for his own twisted desires. He wasn’t simply not a natural man; he’d chosen to twist what he was into something evil, something that fed on suffering. The thought made her sick. As much as the villagers had scorned and shunned her, she wouldn’t wish this pain, this terror, on them. And the thought of a child…any child…suffering as she had, or worse, fueled a rage within her, a protective fire she hadn’t known she possessed. She thought of his vague words, of the Green Place. Ayiti was full of green places, mountains and forests, secrets whispered in the rustling leaves. Sometimes others spoke of a mystical Green Grove, the Bwa Vèrt, a place where the veil between worlds was thin.

She remembered one night, after their passion had subsided, when she’d tried to coax his story from him. He spoke of a lonely childhood, a flicker of vulnerability in his gray-green eyes, of relying on the kindness of strangers. He described the gnawing hunger, the constant ache in his belly, the herbs and wild grasses his only sustenance after being refused even a crust of bread. The memory of that hunger, the desperation it bred, had hollowed her. It was a hunger she understood all too well.

But his voice had turned to ice when he spoke of Petite Ville. His gray-green eyes, usually so mesmerizing, flickered with a cold fury, the memory of some long-held grudge burning within them. She remembered his arrogance when they had begged for food, the fish abandoning the nets, their children wasting away, their bodies falling weak and ashen with hunger. Let them eat grass! he’d cried, echoing a cruelty that chilled her to the bone.

Citadelle knew the villagers were coming. She could feel it in the air, the shift in the wind, the hushed whispers that carried on the breeze. They were coming for him…and likely for her, too. But her fear wasn’t for herself. It was for him, for the terrible path he had chosen, and for the village he had sworn to punish. She didn’t want him, not anymore. But she didn’t want him to unleash his full fury upon Petite Ville either. He had to leave. He had to disappear. A desperate, foolish hope flickered within her, maybe she could convince him.

Maybe, together, they could escape this horror.

But Smoke was arrogant, strong, drunk on the power he wielded, the blood he’d already spilled. He wouldn’t flee, not like a dog with its tail between its legs, as he’d sneered. They will flee me, he’d growled, his eyes gleaming with a dangerous light.

The sound of the approaching mob, a low rumble at first, grew louder, closer. Citadelle’s anxiety clawed at her, a physical pain. She twisted the strange necklace Smoke had given her that first night, the cool stone a small comfort in her trembling hands. She looked up at the sky, at the stars scattered like diamonds across the velvet cloth of night, and she prayed. She prayed for guidance, for some sign, some answer. But the wind offered no whispers, the stars no light.

Then, she saw it. Not in the heavens, but on the ground, a flicker of movement in the encroaching darkness.

It wasn’t the villagers. It was…him.

Smoke, a low growl rumbling in his chest, his stance widening, predatory. He moved with a speed that defied the eye, his features seeming to ripple in the torchlight, shadows clinging to him, momentarily elongating his limbs, sharpening his teeth before snapping back to familiar contours. His form shifted, blurring, not yet fully changed but hinting at the feral potential beneath the skin. He was no longer the man she knew, the man she’d loved. He was the beast she’d glimpsed in the woods, the creature that had left that gruesome trail of hair and skin.

A cold certainty settled in Citadelle’s heart. A decision was forming, but she didn’t know it yet. She couldn’t save him. She couldn’t save the village by running with him. The only way to stop the horror, the only way to atone for her own blindness, was to sever the tie that bound them. As the mob surged into view, torches blazing, their faces contorted with fear and rage, Citadelle stepped forward, not toward Smoke, but toward them. She raised her hands, not in supplication, but in a gesture of command. Her voice, amplified by a power she barely understood, rang out across the night, silencing the approaching crowd.

“He is not one of you,” she declared, her voice trembling but firm. “And he will not be…mine. He is something else, something…other. And he must leave.” She pointed toward the forest, her finger a rigid line in the darkness. “Go. Now. And never return.” Smoke, his transformation momentarily paused, looked at her, his eyes burning with fury and betrayal. He opened his twisted lips, more snout than mouth, to speak, but Citadelle cut him off, her gaze unwavering. “The Green Grove calls you,” she said, her voice laced with a coldness that mirrored his own. “Go back to it. And leave this village, and me, in peace.”

But the villagers didn’t trust her. They remembered Smoke’s arrogance, his cruelty, his let them eat grass pronouncements. They remembered the blight, the sickness, the empty nets, the gaunt faces of their children. They wouldn’t let him escape to return in the night, fueled by vengeance. As Smoke turned to flee, they surged forward, surrounding him. Prayers mingled with cries of anger. Short knives, spears, and tools of the fields and the blacksmith’s forge encircled him, a ring of steel and righteous fury. They wouldn’t let him go. Not this time. And as they held him captive, a chilling realization dawned on them. They saw the fear in his eyes, the same fear they had felt staring into the darkness. They saw the desperation, the hunger, the pain that they themselves had inflicted, not just on him so long ago, but on Citadelle, too. Shame stayed their hands, but only time enough for them to blink away the memory of judgment shining in their own eyes.

In that fragile breath, Smoke’s burning gaze met Citadelle’s. His lips, still twisted, formed a single unspoken word: Run. Her heart, a drum against her ribs, knew the impossible truth: She couldn’t. Not anymore.

They came bearing sugarcane stalks and machetes, the crowd following the trail of Smoke through the trees. Citadelle and Smoke fled into the dank, suffocating heat. A fire raged inside the people, fueling their breath, their steps, their righteous fury.

If they are hungry, let them eat grass, he had said. The night Smoke died, the people of Petite Ville stuffed his mouth with grass. “Manjé, manjé,” they said. “Eat, eat. The world is round.” When they cast him upon an emerald-green hill hidden by bent, lichen-covered mapou trees, they smiled. “Here, you will always be fed.” With roots that gripped the earth like gnarled hands, the ancient mapous raised their crowns in the rising wind, a cathedral of leaves against the heavens above. The verdant trees’ gossamer pink blossoms floated down, showering Smoke’s broken body with the sunset’s tears. Citadelle wiped away the water from her red-rimmed eyes, tears blurring her vision as she ripped the stone from the choker around her neck and let it sink into the soil of the crooked hill.

“Mistè,” the villagers said. Such mysteries!

“Let him return to Bwa Vèrt, the Green Grove!” the kontè cried, the storyteller’s voice echoing through the trees.

“May the forest reclaim its own!” the pecheurs said, waving their bone hooks and short spears. The forest reached out for him, its shadows long and deep, embracing him in its eternal green.

As Smoke fell, as his lifeblood mingled with the earth, Citadelle felt it—a rush of sensation, a taste unlike any she had known. It was the taste of Smoke’s sin: betrayal, rich and savory, like griot, tender, succulent pork, the familiar warmth of scotch bonnet peppers, the pungent bite of cloves, the earthy undertones of thyme, all twisted with a bitter edge of resentment and the metallic tang of broken trust. It was a taste that clung to Citadelle’s tongue, a haunting reminder long after he was gone.

She opened her mouth to scream, yet nothing came out but smoke. The ashes of Petite Ville’s sins floated through the air, a dark gray smudge of slights and pains, petty hatreds, fears great and small, flung out into the wind. Her hunger was gone. Only the smoke remained.

“Petite Ville” copyright © 2026 by Sheree Renée Thomas

This story originally appeared in Forged in FIYAH: Celebrating Ten Years of Black Speculative Fiction (Tordotcom, 2026), edited by DaVaun Sanders.

Cover art by Ernanda Souza
Cover design by Christine Foltzer

Buy the Book

Cover of Forged in FIYAH edited by DaVaun Sanders.
--> Cover of Forged in FIYAH edited by DaVaun Sanders.

Forged in FIYAH: Celebrating Ten Years of Black Speculative Fiction

Edited by DaVaun Sanders

The post Petite Ville appeared first on Reactor.

13:00

Representative Line: Unique Testing [The Daily WTF]

Nikolai M's team had a flaky CI/CD build. About 0.5% of the time, one of their tests would fail: frequent enough to be annoying, but not so frequent that it motivated management to assign anybody to investigate. Nikolai eventually dug in, taking the initiative.

Microsoft's implementation of UUIDs calls them GUIDs. The GUID is, per the docs, really just a wrapper around UUID algorithms, and supports a variety of different UUID variants. I'm sure at some historical point, this wasnt't true, and Microsoft had some weird internal algorithm. That's not really here nor there, but the test that was failing was failing because of an assertion relating to GUIDs.

Assert.DoesNotContain("000", transactionId.ToString());

transactionId is a GUID. This line converts it to a string and checks if it contains "000". They're attempting to check if it's an empty UUID, and they've assumed that three sequential zeroes in the output would be an impossible event. This is untrue. Nikolai measured it, and found it happens 0.5527% of the time- 1-in-181.

So this is a bad test, and could be made better with a more thorough check. Or it could leverage the built in constant GUID.Empty, which is a UUID where every bit is zero.

And it's that which really bugs me, honestly. Even if you didn't know about the constant, the idea of constructing an empty GUID seems like the obvious choice. Though I suppose you'd have to check the docs to find out how to construct a GUID directly, and if you're already reading the docs, the chances of you seeing the built-in constant are probably higher than 0.5527%.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

12:42

A Data Center Is a Dependency Graph Before It Is a Building [Radar]

The buildings and physical infrastructure for a new hyperscale data-center region are complete. Power is live and redundant, the cooling loops are balanced, the network fabric is up, and tens of thousands of machines are racked, cabled, and reporting healthy. Every milestone on the construction schedule is closed. The region will not carry production traffic for another six months, and whether it turns out to be six or closer to twelve is decided almost entirely by software.

There is a large literature on how hyperscale data centers get financed, powered, and cooled. The standard reference on warehouse-scale machines, Barroso and Hölzle’s book, covers the design of these computing facilities in depth. Most of that literature describes data centers that are already operating. The transition from completed facilities to production readiness receives much less attention, even though it carries a significant share of the schedule risk. Getting that transition wrong is expensive.

Once the facilities and hardware are ready, platform teams still have to bring hundreds of interdependent services online. Many services require other services to be running first. If you draw each service as a box and each startup requirement as an arrow, the result is a dependency graph. The graph shows the order in which services can be brought online and identifies the dependencies that must be resolved before the region can serve production traffic.

Getting a region into production means making several different things true at once. The network fabric has to route traffic within each data center, and the links between facilities have to carry traffic reliably. Compute platforms have to schedule workloads, while storage platforms have to persist their data. Identity has to work too: certificate authorities have to issue certificates, services need access to secrets, and engineers need permission to finish the build. Engineer access sounds obvious until the controls protecting the new region are the same controls slowing down the people trying to turn it on. Stateful systems that depend on existing production data have to be populated and validated, because a database cluster with no data in it is furniture. The installed capacity has to be assigned to foundational services and production workloads, and teams have to test how the new region behaves when networks, services, or dependencies fail. Applications are then deployed and validated before traffic moves over gradually, with health checks and a tested rollback at each step, ideally without users noticing.

Each platform or service has an owner, a plan, milestones, and its own definition of done. What is often missing is ownership of the complete dependency graph. The team coordinating the region launch has to map the dependencies across teams, determine the order in which services must come online, track what is blocking that sequence, and keep the graph current as plans change. Without that end-to-end view, every team can report that its own work is on track while the region as a whole remains blocked.

Mapping the graph begins with a simple question for every service: What must already be available before this service can start in a new region? The goal is to identify true startup requirements, not every system the service communicates with during normal operation. Repeat that exercise across a large platform’s control plane, and you can uncover hundreds of dependencies spanning dozens of systems. Some dependencies surface only when another service identifies them as a prerequisite. Hidden dependencies are usually ordinary services that have been quietly reliable for so long that the teams relying on them no longer think about what would happen without them.

Once the startup dependencies are mapped, the next step is to look for loops: cases where one service needs another service to be running, but that second service eventually depends on the first. In a large platform, a surprising share of the control plane can be tied together by these loops. The result is that there is no valid order in which to start the services. Every possible starting point eventually leads back to a service that is still waiting. The loops themselves are usually mundane. DNS may depend on the inventory system that tracks what hardware exists, while the inventory system relies on DNS to resolve names. The artifact repository holding every installable package may depend on configuration management, which is itself installed from a package in that repository.

Nobody designed any of this. Each dependency was a locally sensible decision made by a competent team, often years apart from the decisions that completed the loop. In a running region, the required services are already available, so the loop remains silent. The database is up when the alerting store starts, and nobody learns whether either could recover without the other. Starting a region from scratch is often the only event that reveals whether those services can start independently. Meta’s outage in October 2021 shows how a large failure can expose dependencies that normal operation keeps hidden. When the backbone network connecting Meta’s data centers went down, its DNS servers withdrew their routes as designed to keep traffic away from unhealthy connections. That safeguard made DNS and many internal tools unreachable. With remote access unavailable as well, engineers had to go onsite, slowing recovery. A locally sensible safeguard had made system-wide recovery harder.

Traffic-drain tests can reveal some of these dependencies. Meta’s Maelstrom encodes service dependencies and resource constraints to shift traffic safely from a failing data center to healthy ones, and its drain tests can uncover missing dependencies. But the receiving data centers are already running. A drain tests whether live infrastructure can absorb traffic; it does not test what an empty region needs in order to start. The drain graph is a useful input to the startup graph, not a substitute for it.

Status reports for a new region can be misleading even when every team is reporting honestly. A service may be deployed, configured, monitored, and passing its health checks, yet still be blocked by a startup dependency. Readiness therefore has to propagate through the graph: a service is ready only when its own checks have passed and every service it needs at startup is also ready.

Once the dependency graph exists, five practices turn it from a diagram into a launch plan. The first is finding what actually determines the launch date. The graph shows which services must wait for others, but the order alone does not reveal how long the work will take. Ten services that can start in parallel may finish before three services that must start one after another. Estimate the bring-up and validation time for every service. If several services remain tied together in a loop, treat them as a single planning block and include the time required to break the loop. The chain with the greatest total time becomes the critical path. Then count how many other services each foundational service can hold back, including dependencies several steps away. DNS, relational databases, secrets stores, and configuration management often rise to the top. Staff those teams early, because a week lost in one of them can become a week lost across the entire region.

The second practice is to break the loops. One way to do that is to temporarily borrow a service from a region that is already running. Designate a small bootstrap tier, the minimum set of services required to deploy other services, and configure those bootstrap services to use working dependencies in an existing region until the local versions are ready. Suppose configuration management needs a package from the artifact repository, while the artifact repository needs configuration management before it can start. For the first installation, configuration management can fetch its package from another region. It can then bring up the local artifact repository and switch to using it. The bootstrap tier might also include identity, inventory, and package distribution. This shortcut works only when cross-region access is permitted and reliable enough. It also creates another cutover that must be planned, tested, and completed later.

Borrowing from another region helps the new region get started, but it should not become permanent. Over time, each bootstrap service should be able to start without all of its usual dependencies. Suppose a service normally waits for the configuration system before it can start. Package the minimum settings it needs with the service itself. The service can start with those settings and fetch the latest configuration once the configuration system is running. Test this by turning off the dependency and starting the service from a clean state. If the service still cannot start, record the problem with an owner and a target date for fixing it.

The third practice is to bring the region up in explicit tiers. A typical sequence begins with foundational configuration such as network ranges and routes, hardware inventory, identity configuration, access policies, service endpoints, and deployment settings. Bootstrap services such as DNS, certificate issuance, secrets, software package distribution, and configuration management follow. Next come the control planes that provision resources, schedule workloads, manage storage, and support service discovery. Stateful systems and applications come after the platforms they depend on. The exact tiers will vary by architecture, but the dependency graph should determine the sequence. Tier gates prevent visible application progress from hiding unfinished foundations.

Stateful systems that depend on existing production data need special treatment because creating a cluster is often quick, while filling it with data is not. A storage system is ready only after the required data has arrived and been validated. Estimate that work using data volume, available bandwidth, validation time, and enough headroom for retries. Give each system a time box based on those measurements. If the estimate changes, require updated measurements that explain why. This keeps the plan honest without pretending that every delay is avoidable.

The fourth practice is to make the bring-up repeatable, which does not mean automating every step. Automation helps only when it is maintained and tested. A script written for one region and left untouched for years may be more dangerous than a clear manual procedure. Automate steps that use the same tools as regular deployments or can be exercised frequently. For rare steps, maintain a runbook with validation checks, a named owner, and a schedule for testing it. Both automation and runbooks should clearly identify the required inputs, the evidence that a step succeeded, and how to continue after a partial failure. Google’s SRE book raises the same concern: turn-up automation maintained separately from the systems it supports can become outdated. At every manual step, ask whether another engineer could repeat it during a recovery without relying on the people who completed the original build. The goal is to leave behind a procedure that still works after the original team has moved on.

The fifth practice is validation. It’s natural to test only the highest-traffic paths, but that approach misses structural problems. You also want the flows with the widest fan-out, the ones touching the most systems on the way through, even if few people use them, because those flows traverse more of the dependency graph. A high-volume request may prove that the region can handle load. A wide-reaching request can uncover an unready identity, storage, messaging, or data service. Meta’s Kraken shows another useful validation method by shifting live user traffic into a data center while monitoring latency, errors, and system health. Live traffic also shows where capacity goes as caches warm, retries appear, and background jobs compete with user requests, a combination synthetic tests struggle to reproduce.

When the traffic ramp begins, send a small percentage of representative production traffic to the new region, then increase it in stages. The size of each step should reflect the scale and risk of the platform, because even 1% can represent a substantial workload. This allows the entire application path to experience load together instead of testing each service in isolation. Hold at each step long enough for caches to warm, queues to stabilize, and relevant periodic jobs to run. Decide in advance which health signals allow the ramp to continue and which ones require it to stop. Also define and test how traffic will return to the existing region if health degrades. Confirm that the existing region has enough capacity and that data written in the new region will remain safe. Otherwise, the health signals may tell you something is wrong without giving you a reliable way to recover.

These practices make no promise of a fast launch. They make the build understandable and leave behind a process the next region can use. The dependency map will begin aging as soon as systems change, but the ownership model, readiness rules, tier gates, repeatable procedures, and validation process can remain. The same tools are also useful for a disaster-recovery rebuild. Planning around dependencies will matter more as organizations rethink where their workloads should run, moving some systems from public clouds to private clouds, colocation facilities, or data centers they operate themselves. Each new environment brings another dependency graph that must be understood before it can carry production traffic.

Finishing the facilities remains a genuine milestone. Power, cooling, networking, and hardware create the place where production can run. A working region emerges when its services can start in a valid order, the required data is ready, and the complete system has been tested under traffic. Finishing construction gives the organization a data center. Satisfying every required startup dependency in the graph turns it into an operational region.

12:35

Using Device Linking to Eavesdrop on WhatsApp and Signal [Schneier on Security]

Modern messaging apps allow users to link their phone accounts to their computer desktop. Eavesdroppers are taking advantage of this capability:

Apps such as WhatsApp Web and Signal Desktop allow people to use their accounts on other devices, such as laptops or desktop computers.

Germany’s Customs Office has been using these features to connect a police-controlled computer to a suspect’s account.

Once connected, messages can be delivered to that computer without the police having to crack the encryption protecting them.

Netzpoltik details that police are able to gain access in this way either through physical access to someone’s phone or by intercepting verification codes via a state-sanctioned phishing attack or intercepting SMS messages via telephone surveillance.

That last paragraph is important. Making this work requires user consent.

What we want is a feature that displays connected devices, so users could notice if a new device gets connected to their account.

10:35

What sort of fuel? [Seth's Blog]

We avoid this question all the time, and it costs us.

Don’t put kerosene in an electric car. It won’t work. Don’t give your dog dark chocolate, it’ll make him sick.

And yet, we often hesitate to be honest about what gets us moving.

What puts something at the top of your priority list, or pushes you to put in extra effort? What challenges or rewards do you keep coming back to, gig after gig, job after job?

Here are few to get you started:

  • Extinguishing emergencies
  • Going a little faster than the person next to you
  • Pleasing the boss
  • Undermining the boss (class clown)
  • Establishing a web of safety
  • Running away from safety
  • Earning trust
  • Getting your way
  • Feeling safe
  • Feeling alive
  • Feeling vindicated
  • Showing the skeptics that we’re right
  • Staying out of the spotlight

Someone who is free climbing at Yosemite probably has different fuel than the person on the treadmill at the gym. The emergency room doctor is not the same as someone working in public health.

The structure, shared measurements and near universal recognition of a quest for an Olympic medal can capture an athlete’s life for ten years–but then, once they retire from this special condition, it’s possible that they’ll never again find this sort of motivation.

“How are you?” is a benign question, but the honest answer might reveal which fuel we’re focusing on, helping us see what we’re drawn to–and it’s rarely universal. That’s part of the hiding. We’d like to believe that anyone else facing the same choices we have would use the same fuel and demand the same priorities we do. Look around. Fuel isn’t universal.

If the fuel you’ve chosen is helping you get to where you want to go, that’s fabulous. For most of us, though, it might be worth a pause to consider whether it’s what we really need to fill our days or create the change we seek.

09:35

How To Organise A Munch by Dastardly_Devil [Oh Joy Sex Toy]

How To Organise A Munch by Dastardly_Devil

Hungry for a little more kink in your community? A munch is a casual, low-pressure way for kinky folks to meet, chat, and make connections without turning the evening into anything more. In this five-page guide, Dastardly_devil digs into the basics of organizing your own, from finding a venue to making everyone feel welcome. Come […]

06:28

Urgent: Impeach Brendan Carr [Richard Stallman's Political Notes]

US citizens: call on Congress to impeach Brendan Carr, head of the FCC, for being loyal to the wrecker rather that to the US and its constitution.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Reject KOSA [Richard Stallman's Political Notes]

US citizens: call on Congress to reject KOSA and its internet surveillance.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Block sale of bombs to Israel [Richard Stallman's Political Notes]

US citizens: call on your senators to block the sale of bombs to Israel.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Digital delivery of personal financial data [Richard Stallman's Political Notes]

US citizens: call on US government regulators to drop their plan to make digital delivery of personal financial data the default.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Investigate FCC for censorship of broadcasters [Richard Stallman's Political Notes]

US citizens: call on Congress to investigate the FCC for censorship of broadcasters.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: California's proposed billionaire wealth tax [Richard Stallman's Political Notes]

US citizens: State your support for California's proposed billionaire wealth tax.

Only California voters can vote on this initiative, but you and I can support it through this petition.

Urgent: Stop Corporate Takeovers of Physicians Act [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to pass the Stop Corporate Takeovers of Physicians Act.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Reject corrupter's nominees for USPS Postal Board [Richard Stallman's Political Notes]

US citizens: call on your senators to reject the corrupter's Nominees for the USPS Postal Board.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Support S.Res.852 [Richard Stallman's Political Notes]

US citizens: call on your senators to support S.Res.852, which would require the State Department to report to the Senate about Israel's violence toward Palestinians in the West Bank.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Medicare Advantage [Richard Stallman's Political Notes]

US citizens: call on Congress not to let Medicare Advantage insurers dump seniors.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Stop Pentagon raiding NIH medical research funds [Richard Stallman's Political Notes]

US citizens: call on Congress to stop the Pentagon from raiding NIH medical research funds.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

04:56

C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times [The Old New Thing]

When you write a static variable inside a function, it is initialized only once, specifically at the first time that execution reaches the variable’s declaration, If execution reaches the variable again in the future, no initialization occurs. It just retains its old value.

Some time ago, I noted an attempt to fix a lifetime issue by making a variable static.

The original code used this header from an external widget library:

// widget.h
struct WidgetController
{
    virtual WidgetKind GetKind() = 0;
    virtual WidgetFlags GetFlags() = 0;
    virtual void OnOpening() = 0;
    ⟦ and so on ⟧
};

std::shared_ptr<Widget>
    MakeWidget(std::shared_ptr<WidgetController> const& controller);

The idea is that you give it a Widget­Controller object that the widget consults at various times, allowing you to customize the widget behavior.

The application code called it like this:

// The basic Widget controller provides information but
// does not override any default behaviors.

struct BasicWidgetInfo
{
    WidgetKind kind;
    WidgetFlags flags;
    ⟦ and so on ⟧
};

struct BasicWidgetController : WidgetController
{
    BasicWidgetController(BasicWidgetInfo const& info) :
        m_info(info) {}

    WidgetKind GetKind() override { return m_info.kind; }
    WidgetFlags GetFlags() override { return m_info.flags; }

    // Do not customize any dynamic actions.
    void OnOpening() override { }
    ⟦ and so on ⟧

private:
    BasicWidgetInfo const& m_info;
}

struct Gadget
{
    std::shared_ptr<Widget> m_widget;

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

The catch is that the Widget­Options constructor takes a reference to a Gadget­Options and saves the reference. Later, when the widget asks the controller for the flags, the controller will look up the answer in the BasicWidgetInfo structure, but that BasicWidgetInfo had already destructed when Create­Custom­Widget returned, so it returns garbage (or possibly even crashes).

This is a use-after-free bug.

To solve this problem, they made the info static. Static objects continue to exist even after the function returns.

    void CreateWidget(GadgetFlags flags)
    {
        static BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

Now the program doesn’t crash. Yay!

However, there is a catch: If two Gadgets both try to create a widget, all of them will have the same options as the first one, because function-local static variables are shared among all instances of a class and are initialized only the first time execution reaches the variable. Whatever flags were passed when you called it the first time get locked into the info, and it doesn’t matter what flags you pass subsequent times because info has already been initialized; it’s not going to initialize again.

If you want it to initialize each time, then you have to modify it each time.

    void CreateWidget(GadgetFlags flags)
    {
        static BasicWidgetInfo info;
        info = {                    
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

This time, we set the values as a step separate from construction, which means that it executes each time, and the info gets updated with the most recent flags.

Of course, this is still a problem if two Gadgets create Widgets with overlapping lifetime, because the two Basic­Widget­Controllers are sharing the same info. At the second call to Create­Widget, its updates to info secretly alter the values being used by the first one.

Plus, of course, if Create­Widget is called by two threads simultaneously, you have a data race on the writes to the info variable, and then the results will be unpredictable.

The underlying problem is that the Basic­Widget­Controller wants to extend the lifetime of its info, but a reference gives you no way to do it, so it has to rely on the kindness of strangers.

One idea would be to put the info somewhere else, so that its lifetime can be extended some other way. Maybe you put it in the Gadget:

struct Gadget
{
    std::shared_ptr<Widget> m_widget;
    BasicWidgetInfo m_info;

    void CreateWidget(GadgetFlags flags)
    {
        m_info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(m_info);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

Now your job is to make sure that the m_info is not destructed before the last shared pointer to the Basic­Widget­Controller. This is tricky, since you don’t really know when the last shared pointer to the Basic­Widget­Controller will be destructed, although you might have some heuristics given that its lifetime is probably tied to the Widget.

Is there a way to hook into the destruction of the final shared_ptr?

Yes, and in fact we already used that feature without realizing it.

You can use an aliasing shared pointer that points at a Basic­Widget­Controller but whose lifetime controls both a Basic­Widget­Controller and its associated Basic­Widget­Info.

struct BasicWidgetControllerWithInfo
{
    BasicWidgetControllerWithInfo(BasicWidgetInfo const& info) :
        m_info(info),
        m_controller(m_info) {}

    // The m_info must come before the m_controller because the
    // m_controller initializer depends on the m_info.
    BasicWidgetInfo m_info;
    BasicWidgetController m_controller;
};

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controllerAndInfo = std::make_shared<BasicWidgetControllerWithInfo(info);

        auto controller = std::shared_ptr<BasicWidgetController>(
            controllerAndInfo, &controllerAndInfo->m_controller);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

We use an aliasing constructor with a pointer to the controller, but telling it to control the lifetime of the Basic­Widget­Controller­With­Info.

Of course, all of this is a problem of the application’s own creation. They should just fix the Basic­Widget­Controller to copy the Basic­Widget­Info instead of taking a reference.

struct BasicWidgetController : WidgetController
{
    BasicWidgetController(BasicWidgetInfo const& info) :
        m_info(info) {}

    WidgetKind GetKind() override { return m_info.kind; }
    WidgetFlags GetFlags() override { return m_info.flags; }

    // Do not customize any dynamic actions.
    void OnOpening() override { }
    ⟦ and so on ⟧

private:
    BasicWidgetInfo /* const& */ m_info;
}

Now the original code works again.

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

The post C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times appeared first on The Old New Thing.

02:49

GNU Parallel 20260922 ('Parton') released [stable] [Planet GNU]

GNU Parallel 20260922 ('Parton') has been released. It is available for download at: lbry://@GnuParallel:4

Quote of the month:

  GNU parallel is awesome. Use it more often in your scripts!
    -- Wade @WadeGrimshire@twitter

New in this release:

  • Bug fixes and man page updates.


GNU Parallel - For people who live life in the parallel lane.

If you like GNU Parallel record a video testimonial: Say who you are, what you use GNU Parallel for, how it helps you, and what you like most about it. Include a command that uses GNU Parallel if you feel like it.


About GNU Parallel


GNU Parallel is a shell tool for executing jobs in parallel using one or more computers. A job can be a single command or a small script that has to be run for each of the lines in the input. The typical input is a list of files, a list of hosts, a list of users, a list of URLs, or a list of tables. A job can also be a command that reads from a pipe. GNU Parallel can then split the input and pipe it into commands in parallel.

If you use xargs and tee today you will find GNU Parallel very easy to use as GNU Parallel is written to have the same options as xargs. If you write loops in shell, you will find GNU Parallel may be able to replace most of the loops and make them run faster by running several jobs in parallel. GNU Parallel can even replace nested loops.

GNU Parallel makes sure output from the commands is the same output as you would get had you run the commands sequentially. This makes it possible to use output from GNU Parallel as input for other programs.

For example you can run this to convert all jpeg files into png and gif files and have a progress bar:

  parallel --bar convert {1} {1.}.{2} ::: *.jpg ::: png gif

Or you can generate big, medium, and small thumbnails of all jpeg files in sub dirs:

  find . -name '*.jpg' |
    parallel convert -geometry {2} {1} {1//}/thumb{2}_{1/} :::: - ::: 50 100 200

You can find more about GNU Parallel at: http://www.gnu ... rg/s/parallel/

You can install GNU Parallel in just 10 seconds with:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep c555f616391c6f7c28bf938044f4ec50
    12345678 c555f616 391c6f7c 28bf9380 44f4ec50
    $ md5sum install.sh | grep 707275363428aa9e9a136b9a7296dfe4
    70727536 3428aa9e 9a136b9a 7296dfe4
    $ sha512sum install.sh | grep b24bfe249695e0236f6bc7de85828fe1f08f4259
    83320d89 f56698ec 77454856 895edc3e aa16feab 2757966e 5092ef2d 661b8b45
    b24bfe24 9695e023 6f6bc7de 85828fe1 f08f4259 6ce5480a 5e1571b2 8b722f21
    $ bash install.sh

Watch the intro video on http://www.youtub ... L284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.

When using programs that use GNU Parallel to process data for publication please cite:

O. Tange (2018): GNU Parallel 2018, March 2018, https://doi.org/1 ... 81/zenodo.1146014.

If you like GNU Parallel:

  • Give a demo at your local user group/team/colleagues
  • Post the intro videos on Reddit/Diaspora*/forums/blogs/ Identi.ca/Google+/Twitter/Facebook/Linkedin/mailing lists
  • Get the merchandise https://gnuparall ... igns/gnu-parallel
  • Request or write a review for your favourite blog or magazine
  • Request or build a package for your favourite distribution (if it is not already there)
  • Invite me for your next conference


If you use programs that use GNU Parallel for research:

  • Please cite GNU Parallel in you publications (use --citation)


If GNU Parallel saves you money:



About GNU SQL


GNU sql aims to give a simple, unified interface for accessing databases through all the different databases' command line clients. So far the focus has been on giving a common way to specify login information (protocol, username, password, hostname, and port number), size (database and table size), and running queries.

The database is addressed using a DBURL. If commands are left out you will get that database's interactive shell.

When using GNU SQL for a publication please cite:

O. Tange (2011): GNU SQL - A Command Line Tool for Accessing Different Databases Using DBURLs, ;login: The USENIX Magazine, April 2011:29-32.


About GNU Niceload


GNU niceload slows down a program when the computer load average (or other system activity) is above a certain limit. When the limit is reached the program will be suspended for some time. If the limit is a soft limit the program will be allowed to run for short amounts of time before being suspended again. If the limit is a hard limit the program will only be allowed to run when the system is below the limit.

02:21

Feeling Crabby [QC RSS v2]

crabitha mentioned

Monday, 28 September

23:07

Free Software Directory meeting on IRC: Friday, October 30, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 30 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

Free Software Directory meeting on IRC: Friday, October 23, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 23 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

Free Software Directory meeting on IRC: Friday, October 16, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 16 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

Free Software Directory meeting on IRC: Friday, October 9, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 9 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

Free Software Directory meeting on IRC: Friday, October 2, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 2 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

22:42

Link [Scripting News]

Rootfiles in Frontier, a new collection starts with docserver.root, the code and content for docserver.userland.com. Claude also wrote a Node app that extracts all the data from a root file.

Reproducible Builds (diffoscope): diffoscope 332 released [Planet Debian]

The diffoscope maintainers are pleased to announce the release of diffoscope version 332. This version includes the following changes:

[ Chris Lamb ]
* Do not Build-Depend on GNU Guix. Thanks to Vagrant and Holger for the
  reports. (Closes: #1149132)

[ Guillaume Girol ]
* Update more tests to support new versions of Radare.
  (Closes: reproducible-builds/diffoscope#432)

You find out more by visiting the project homepage.

21:56

Page 58 [Flipside]

Page 58 is done.

20:21

Numbers Game [Penny Arcade]

He's still being dragged down into an incredibly deep hole with the new Fire Emblem, enough to wonder how some of the math could possibly math in this way. He sounds like me when I got heavily - heavily - into Dynasty Tactics, which I was horrified to learn is twenty-four years old. Fire Emblem is about type-matching and abilities, which is already drugs; Dynasty Tactics is largely about creating a favorable battlefield by positioning your units so that, like striking a match, you attack once and it triggers additional attacks from the rest of your army. I don't know that I've ever had to think that hard in a game since. They made a second one, but I didn't like it as well. That could be due to the fact that it wasn't as good, maybe, but who knows. It's also possible that the exertions of arranging and then triggering ten discrete units on a two-dimensional plane so that they all perform in a harmonious sequence is only something you can feel once.

19:35

MotifCentral: all things Motif/Xt/Xlib [OSnews]

Over the last few days and weeks or so, a few of the people I follow and interact with on Fedi have been talking about centralising information, tools, applications, and expertise from the Motif (and Xt, Xlib, and X11) ecosystem. There’s a ton of information, resources, and actively maintained applications out there, but it’s all spread out and sometimes difficult to find, and so Thomas Adam – one of the core developers of FVWM, among other things, as well as creator of CoW (FVWM for Wayland, more or less) – has created an effort to centralise all of this.

Motif Central brings together information about Motif, Xt, Xlib and X11: how they fit together, how to program with them, and where to find the manuals, examples and historical material that explain them.

Begin with the X programming stack, build your first Motif application, or explore the programming resources. The history pages describe the libraries’ origins, while the archive guide helps you navigate older documentation.

↫ MotifCentral

There’s been a whole flurry of activity around Motif lately, including the updated and maintained fork we talked about a few weeks ago. The people loosely collaborating on MotifCentral also submitted patches to CDE to make sure it works on the new Motif fork, with the CDE developers setting up a build pipeline for easier testing. Making sure CDE, the classic Motif desktop environment, works well with the maintained Motif fork quite a few people seem to be rallying around is a worthwhile effort.

We’re still quite far from a complete(-ish) modern Motif ecosystem, but it’s very heartwarming to see just how many people are actually still interested in it. My perhaps misguided hope is that we can somehow get to a modernised Motif/CDE desktop environment and applications, making it possible to more easily run a modern Motif environment on Linux and the BSDs.

One may dream.

Windows 10 breaks far less often than Windows 11 [OSnews]

Windows 11 received its September update on the 8th of this month, and within days Microsoft had acknowledged or investigated problems involving Remote Desktop, USB audio, Linux and WSL-based apps like Claude Cowork, and enterprise domain issues. Windows Latest also found File History failures, Explorer.exe crashes, and AMD GPU instability, with an emergency update following on September 14 that still did not fix everything.

This got us curious, and we looked back across the nine monthly updates released from January through September 2026 and, rather unsurprisingly, Windows 10 update history isn’t infected with nearly as many bugs as that of Windows 11.

↫ Abhijith M B at Windows Latest

Of course, Windows 10 also isn’t getting nearly as much attention from Microsoft, but that’s kind of the whole point, isn’t it? Whenever Microsoft touches something, especially over the last 5 years or so, it’s one cascade of failures after the other, eroding trust in Windows’ updates even more (if that’s even possible). In that light, why would you want to use Windows 11 and all the headaches that come with it, when Windows 10 is right there, still being supported, albeit without the latest bells and whistles that only seem to break Windows 11 anyway?

If you really do need or want to use Windows, consider switching back to Windows 10 whenever the usual Windows reinstallation time draws near. You won’t lose much, but will gain quite a bit in the process. Of course, this won’t be a responsible or usable choice forever, but at this point in time, I definitely think it’s the optimal choice for quite a few people.

19:21

Pluralistic: Priceful (28 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links

  • Priceful: So worthless we can tell you what it's worth.
  • Hey look at this: Delights to delectate.
  • Object permanence: Nasdaq allows post-9/11 penny stocks; USAF can shoot down civilian aircraft; TSA bans calling Kip Hawley an idiot; Wells Fargo sued for firing fraud-refusing tellers; The real AI apocalypse; Encryption didn't cause 9/11; Bat-person costume; British Library on DRM and CC; NYT v OWS; "The Brave Little Toaster"; Bounty for Trump's tax return; Chinese real-estate bubble; Corbyn's Labour conference speech; HP blinks; "Are you calling me a racist?"; "Yuge"; Debts that can't be paid won't be paid.
  • Upcoming appearances: Edmonton, Boston, Brighton, Virtual, South Bend, Hudson, Calgary, Winnipeg, Paris, OVancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



A pastoral landscape with a cablecar system running overhead. A procession of old-timey cash registers are being moved through the sky on it.

Priceful (permalink)

Digital rights activists have long railed at the use of the term "IP," criticizing it for being deceptively imprecise and also rhetorically dishonest. I get where these objections are coming from, but I think they're misguided.

Start with "deceptively imprecise." "IP" covers a lot of legal ground, from the "big three" of copyright, trademark and patent, to a whole arcane bestiary: anticircumvention, noncompete, trade secrecy, nondisparagement, database and publicity rights, and more. Each of these has a radically different policy basis and radically different contours.

Take copyright and trademark. Copyright is designed to allow companies (and the creators they hire or contract with) to commercially exploit creative works. In the US, copyright is a creature of the Constitution, Article 1, Section 8, Clause 8:

https://constitution.congress.gov/browse/essay/artI-S8-C8-3-2/ALDE_00013064/

Fun fact: there are only two clauses in the Constitution that include a rationale: the Second Amendment ("A well regulated Militia") and the copyright clause ("To promote the Progress of Science and useful Arts"). Everything else is one of those "truths" that the framers "held to be self-evident." In these two cases, they decided to explain their thinking.

So the point of copyright is to incentivize investment in creative works, and its mechanism is a set of limited rights over those works, for limited times. Copyright expires, and it is subject to "limitations and exceptions," including "fair use," a very broad set of highly situational rights to use works even if the rightsholder objects:

https://pluralistic.net/2026/02/07/aimsters-revenge/#effective-means-of-access-control

Now consider trademark: trademark could not be more different from copyright! Trademark is a consumer protection rule: it empowers companies to sue competitors who engage in deceptive conduct that could confuse their customers. The idea here is that if you get a pair of fake Nikes that fall apart within a matter of days, or eat at a fake McDonald's whose food is (somehow?) even worse than regular McDonald's food, you are unlikely to take action. You're not going to hire a lawyer over a hamburger.

So trademark deputizes companies to sue on behalf of customers who have been or might be deceived by unscrupulous competitors whose merchandising and marketing are likely to confuse the public. Unlike copyright's "fair use," trademark has other defenses, like "nominative use" ("This case fits an iPhone" is not a trademark violation, provided it's true). Also, many trademark claims can be dispensed through simple disclaimers: for example, my debut novel Down and Out in the Magic Kingdom features a prominent notice informing readers that it wasn't endorsed by the Walt Disney Company. No confusion, no problem.

Unlike copyright, which (eventually) expires, a trademark can carry on for so long as it is associated with a company's products or services. Procter & Gamble's moon logo has enjoyed trademark protection since the mid-19th century, 50 years before the first federal trademark law, and 100 years before the Lanham Act, the current federal trademark law.

This is where the imprecision comes in. There are many activities that are legal under trademark and prohibited under copyright, and vice-versa. By claiming an "IP" violation, you can induce confusion in your target's mind about which rule you're discussing.

If you say, "That's my copyrighted image and your use of it is confusing my customers," I might reply, "Well, that sounds like a trademark issue. Do you have a trademark, too?" Whereas if you say, "That's my IP and you're confusing my customers," that's some tactically useful ambiguity. I can't know if you're talking about copyright, patent, trademark, or, you know, a sui generis broadcaster's right under the Treaty of Rome.

I might walk away from my creative, expressive activity even though it's totally legal, because you've got me to conflate the restrictions of copyright and trademark. This makes "IP" a kind of bully's charter, whose imprecision lets you invoke all weird rights we call "IP," no matter whether they apply to the situation at had.

That's the first objection, then: this deceptive and corrosive imprecision. It's a fair point. But then there's the other objection: the use of the world "property" to describe this motley assortment of regulatory fiats.

"Property" is the established catechism of the Church of Late-Stage Capitalism. "Property" is the most sacrosanct right in public orthodoxy, elevated above every other right. My property right lets me destroy perfectly good food while you starve outside my door:

https://pluralistic.net/2026/07/08/wilhoitian/#human-rights-v-property-rights

Before "IP" came into wide usage, we didn't generally try to group this miscellany under one umbrella, but when we did, the term we used wasn't "IP," it was monopolies. These regulatory fiats were (correctly) considered to be government-granted, government-enforced monopolies. The adoption of IP was a branding exercise, a very successful attempt to transform the public's perception of these rules as natural, freestanding property rights that the law merely ratified – not a set of regulatory gifts designed to protect the self-interest of commercial firms.

I get it. Between the tactical confusion and the invocation of "property," "IP" feels like terrain worth fighting over. Once you let your adversary frame the debate in terms of property, you've already lost half the battle.

For many years, I bought into this. But lately, I've grown more skeptical of this matter. Back in 2020, I published a long essay proposing that far from being confusing or ambiguous, "IP" has a crisp, widely understood meaning: "Any law that lets me reach beyond the walls of my company to exert control over my competitors, critics and customers":

https://locusmag.com/feature/cory-doctorow-ip/

This is the common factor that binds together that mess of legal oddments, from trademark/copyright/patent to nondisparagement and noncompetes to anticircumvention and personality rights.

I think this is both true and a powerful framing. It correctly puts IP in the category of "things corporations do to control you and the rest of the world."

I've been trying this out for six years now, and I think it's a winner. But it was only a month or two ago that I realized there was a way in which the use of "property" can also be used to undermine the bullying, censorship and extraction of corporations wielding their IP.

Property rights may be our state religion, but they are also the worst tool for several important jobs that need doing. Think of privacy: the standard for privacy is for you to click through an "agreement" that nominally trades your privacy rights for some product or service. Google spies on you constantly for ad-targeting, you get to see Youtube videos (after watching a bunch of ads).

This is a catastrophe. Virtually every vendor you engage with, from your landlord to your corner deli, wants you to install an app whose terms of service requires you to sign away all of your privacy rights, forever, in exchange for nothing. You get the same sandwich, but you "pay" more, in the form of all your private data, which is flushed into the unregulated data-broker sector to be weaponized against you in a thousand ways, including higher prices and lower wages:

https://pluralistic.net/2026/07/11/your-risk/#my-reward

Worse: because you have "entered into a contract" to "sell" your privacy rights, anything you do to claw those rights back is violation of your end of the contract. Using a tracker blocker like Privacy Badger makes you the cheater:

https://privacybadger.org/

Even if you could get actually paid for the use of your private information, the sums involved would round to zero. Companies like Facebook make pennies from your private data, and inflict harm on you that totals up to hundreds of times more than they actually make. The commercial surveillance industry are poster children for corruption: concentrated gains that are far exceeded by diffuse harms:

https://locusmag.com/feature/cory-doctorow-zucks-empire-of-oily-rags/

But just because privacy doesn't fit well into a property rights framework, it doesn't follow that there's no way to do privacy well. We have lots of other rights frameworks besides property, and it's taken the concerted work of generations to get us to forget that these rights exist at all.

Imagine if our privacy regime was modeled on the human rights system we rely on when it comes to sex, bodily autonomy and consent. In this framework, no one is allowed to do anything to you unless you give your continuous, informed consent, which you can withdraw at any time. "I changed my mind" is a perfectly valid thing to say in the middle of a sexual encounter. It's not a violation of your contract. Quite the opposite: someone who ignores your withdrawal of consent is guilty of criminal assault.

If we apply a consent regime (not a property regime) to privacy rights, then the entire commercial surveillance industry would cease to exist. There's no way you can give "informed consent" to a laundry-list of terms of service that are as impenetrable as they are lengthy, and even if you did, you could withdraw that consent at any time, and Facebook et al would have to immediately stop processing your private information and disgorge it.

Like all forms of property rights, "IP" has severe limitations that can only be addressed by applying a different framework to your disputes. Think of the way that the expansion of copyright has failed creative workers. For 50 years, we've monotonically expanded copyright in every dimension, so that today, copyright covers more works, restricts more uses and inflicts higher statutory penalties.

Over those 50 years, media companies have gotten richer and more profitable while the creative workers whose art these media companies sell have gotten poorer, both in real terms and as a share of the earnings our labor generates for our bosses. This seems like a paradox at first, but really, it's just a built-in feature of property law: that people who have assets but lack bargaining leverage end up selling those assets for peanuts.

In a market dominated by five publishers, four studios, three labels, two app companies and one ebook/audiobook company, giving a creative worker more to bargain with is just giving them more to bargain away. Giving us more copyright is like giving a bullied schoolkid more lunch money: no amount of lunch money will get that kid fed.

This is why arguments about copyright and AI training are such a dead-end. Even if you stipulate that AI training isn't fair use (far from a certainty), or if you want legislative action to establish that every creator gets to decide whether their work can be used to train an AI, you won't help creative workers win the class struggle against AI companies.

Remember the Hollywood writers' strike? It's the only time in history that creative workers have defeated AI, so it's worthy of close study. Specifically, remember that workers on those picket lines weren't striking against the AI companies, they were striking against the studio bosses, artist-hating billionaires like Warner's David Zaslav and Disney's Bob Iger, whose careers have been defined by a relentless quest for ways to pay creative workers less. It was studio bosses, not AI bosses, who wanted to replace screenwriters with AI.

These are the same studio bosses who are now suing AI companies for copyright infringement. That's not because the studio bosses want to get rid of AI models or keep them out of the writers' room. They absolutely want to fire writers and replace us with AI. The studio lawsuits over AI training want to make training a licensable activity so that the studios can get paid for the use of "their" training data to make models that they absolutely want to use to fire most of their writers and then knock down the wages of the survivors of the AI layoffs.

Many creative workers have cheered on these media companies as they chase the AI companies through the courts, and some artists' groups have even submitted amicus briefs on their behalf. But the New York Times – a company that has repeatedly used the dirtiest union-busting tactics imaginable against its workers – is not suing OpenAI to ensure that creative workers don't lose wages to AI. They're suing to make sure that the Times gets a bigger piece of the action when that happens.

If the Times, Disney and Warner prevail, they will immediately amend their standard, non-negotiable contracts to require every creative worker who does any work for them to exclusively and irrevocably sign over the right to train AI with our labor, and the resulting models will be used to attack our jobs and wages.

In other words, the media company/AI company lawsuits are a fight to see who gets the biggest piece when creative workers get eaten for dinner. We don't want either side to win: we want to be taken off the menu altogether.

Which is exactly what the Hollywood writers accomplished, and they didn't use copyright to do it. They used something far more important and powerful: labor rights.

Like all the Hollywood guilds, the Writers Guild of America has a nearly unheard-of labor right. They are able to engage in something called "multi-employer bargaining," itself a weak form of "sectoral bargaining," which is when all the workers in a sector bargain with all the bosses in that sector. Sectoral bargaining was made practically illegal under the 1947 Taft-Hartley Act, and its last vestiges are to be found in Hollywood.

But as vestigial as Hollywood's unique labor rights system may be, it was still enough to let thousands of freelancers beat back AI in their writers' rooms. Indeed, they even retained the right to use (or not use) AI if they chose, without any threat to their wages or headcount:

https://pluralistic.net/2023/10/01/how-the-writers-guild-sunk-ais-ship/

This is something you can only get with labor rights, not copyright and certainly not property rights. If we limit ourselves to property rights, the only question we need to ask is "Who owns that writers' room?" And since the answer is "the studio" then whatever the studio says goes.

It's precisely because labor rights get workers benefits at their bosses' expense (and copyright cannot) that we have been subjected to generations of pro-copyright messaging, told that we aren't workers at all – we're small businesses, LLCs with MFAs!

Creative workers have been taken for a ride. We've been told that we're not workers, so we shouldn't advocate for labor rights. We've been told that copyright is better than labor rights, because copyright is a property right. It puts a price on your work, which means you can get paid.

But prices are things we assign to things that are so worthless that we can say what they're worth. The most valuable things in the world aren't property, and describing them as property would cheapen them. Human beings aren't property. The fact that we're not property doesn't mean we're worthless, it means we're priceless. That's why "murder" isn't "theft of life" and "rape" isn't "theft of sex." Your life and bodily integrity are worth too much to be bought and sold.

Property rights have a role to play in the assertion of human rights and other rights, but it is a subordinate role. Property rights might someday end the barbaric practice of homeless encampment sweeps and the confiscation of all the worldly goods of the poorest, most vulnerable people in our midst:

https://projects.propublica.org/impact-of-homeless-sweeps-lost-belongings/

But property rights must be subordinate to human rights, otherwise they'll let landlords evict tenants willy-nilly.

Which is all to say, by all means, let our adversaries claim "IP." Let them admit that they have this doctrine by which they attempt to assert control over their critics, customers and competitors. They can assert control, and we'll keep autonomy and consent. Let them say that they have property rights, things so cheap they can have a price. They can be priceful, we can be priceless.


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago Nasdaq allows sub-$1 shares to avoid mass delisting after 9/11 https://www.nytimes.com/2001/09/28/business/moratorium-by-nasdaq-on-listing-rules.html

#25yrsago USAF makes it much easier to shoot down civilian aircraft https://www.chicagotribune.com/2001/09/28/rules-revised-for-downing-airliners/

#25yrsago Don't blame encryption for 9/11 https://web.archive.org/web/20010930005338/http://news.cnet.com/news/0-1272-210-7320099-1.html

#20yrsago Disneyland parking structure repeatedly robbed at gunpoint https://web.archive.org/web/20061031031505/https://www.ocregister.com/ocregister/homepage/abox/article_1291046.php

#20yrsago HOWTO: Make a bat-person costume out of an old umbrella https://www.evilmadscientist.com/2006/how-to-build-a-better-bat-costume/

#20yrsago American Airlines bans in-flight kissing https://web.archive.org/web/20061004214421/https://www.newyorker.com/talk/content/articles/060925ta_talk_collins

#20yrsago British Library takes on Creative Commons and DRM https://web.archive.org/web/20061022143612/https://www.bl.uk/news/pdf/ipmanifesto.pdf

#20yrsago TSA: calling Kip Hawley an idiot is not allowed https://www.flyertalk.com/forum/checkpoints-borders-policy-debate/606142-i-detained-tsa-checkpoint-about-25-minutes-today.html#post6440005

#15yrsago Who’s occupying Wall Street, and why is the NYT only interested in the kooks? https://www.nytimes.com/2011/09/25/nyregion/protesters-are-gunning-for-wall-street-with-faulty-aim.html?_r=2&amp;hp

#15yrsago Podcast: my story “The Brave Little Toaster” https://dn710605.ca.archive.org/0/items/Cory_Doctorow_Podcast_212/Cory_Doctorow_Podcast_212_Brave_Little_Toaster.mp3

#10yrsago The dubious upsides of having a Syrian passport https://globalvoices.org/2016/09/29/i-am-lucky-to-have-a-syrian-passport/

#10yrsago State of California imposes 12-months’ worth of sanctions on Wells Fargo https://web.archive.org/web/20161003194157/http://www.treasurer.ca.gov/news/releases/2016/20160928.asp

#10yrsago 2600 Magazine offers $10K for Trump’s tax return https://web.archive.org/web/20160930162135/https://motherboard.vice.com/read/hacker-zine-says-it-will-pay-10000-for-trumps-tax-returns

#10yrsago Black voter registration is inversely correlated with black death at police hands https://www.wired.com/2016/09/intriguing-link-police-shootings-black-voter-registration/

#10yrsago Chinese real estate bubble is “biggest in history” https://web.archive.org/web/20160929135157/http://money.cnn.com/2016/09/28/investing/china-wang-jianlin-real-estate-bubble/

#10yrsago Notes from Jeremy Corbyn’s barn-burning speech at the Labour Party conference https://www.mirror.co.uk/news/uk-news/8-key-points-jeremy-corbyns-8936364

#10yrsago Douglas County, OR using dirty ballot tricks to finish off the slow murder of its libraries https://web.archive.org/web/20160930155357/https://action.everylibrary.org/douglascounty

#10yrsago HP blinks, says it will restore printer functionality, but there’s a LOT more it needs to do https://www.eff.org/deeplinks/2016/09/dont-hide-drm-security-update

#10yrsago The Doonesbury Trump retrospective proves that Garry Trudeau had Drumpf’s number all along https://memex.craphound.com/2016/09/29/the-doonesbury-trump-retrospective-proves-that-garry-trudeau-had-drumpfs-number-all-along/

#10yrsago Ex-Wells employees who were fired for NOT committing fraud launch $2.6B lawsuit https://www.npr.org/sections/thetwo-way/2016/09/26/495454165/ex-wells-fargo-employees-sue-allege-they-were-punished-for-not-breaking-law

#10yrsago Inside a multimillion dollar fake Kindle book scam https://www.zdnet.com/article/exclusive-inside-a-million-dollar-amazon-kindle-catfishing-scam/

#10yrsago Wells Fargo execs will lose a few millions out of the hundreds of millions they got for abetting massive fraud https://www.nakedcapitalism.com/2016/09/wells-fargo-ceo-stumpf-hit-with-41-million-in-clawbacks-head-of-community-bank-dinged-19-million.html

#10yrsago Youtube’s new “offline first” product for India treats telcos as damage and routes around them https://blog.youtube/news-and-events/youtube-go-youtube-reimagined-for-next/

#5yrsago Shelter is a toxic asset https://pluralistic.net/2021/09/27/lethal-dysfunction/#yimby

#5yrsago Democrats, health care monopolies, and market failures https://pluralistic.net/2021/09/27/lethal-dysfunction/#luxury-bones

#5yrsago Wells Fargo can't stop criming https://pluralistic.net/2021/09/29/jubilance/#too-big-to-jail

#5yrsago "Are you calling me a racist?" https://pluralistic.net/2021/09/29/jubilance/#tolerable-racism

#5yrsago Debts that can't be paid, won't be paid https://pluralistic.net/2021/09/29/jubilance/#debt

#1yrago The real (economic) AI apocalypse is nigh https://pluralistic.net/2025/09/27/econopocalypse/#subprime-intelligence

#1yrago Plenty of room at the bottom (of the tech stack) https://pluralistic.net/2025/09/28/works-well/#fails-well


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Friday's words: 525 (19747 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

18:49

Link [Scripting News]

I was browsing around the WordPress blogs and found a new one in German that pointed to something new in blogrolls. It's Matthias Pfefferle, of course -- this time connecting up with the world Manton and I were working on a couple of years ago in blogroll sharing and OPML. Read about it here. He works at Automattic and has done pretty much all the work to connect WordPress to everything he can find, including ActivityPub and AT Proto. I have to swing back to FeedLand and RSS.chat asap, so we can start building together. Not going to miss his window on this stuff.

18:35

Git v2.56.0 released [LWN.net]

Version 2.56 of the Git distributed version-control system has been released. It has 748 non-merge commits since Git 2.55 was released back in June; those commits came from 104 developers, 39 of whom are first-time contributors. New features include a safer workflow for conflict resolution, smaller path-walk repacks, a new git history drop sub-command, and much more. LWN looked at Git 2.56 recently and the GitHub blog has a lengthy look at 2.56 as well.

17:14

Otto Kekäläinen: Using multiple git remotes for true distributed version control [Planet Debian]

Featured image of post Using multiple git remotes for true distributed version control

One of the primary design principles for Linus Torvalds when creating Git is that it should be a distributed system, capable of working with multiple remotes. However, most people seem to use Git with just one remote, typically having GitHub or GitLab as the only origin.

Version control systems before Git relied on a centralized model. For example in Subversion or CVS you could only sync with one single remote server, which was considered the primary host of the source code. Git however is not just a VCS, but a DVCS, for distributed version control system. If you currently use Git with just one single remote as if it was a centralized version control system, now is the time to change that and learn how to add multiple remotes, and configure more flexible git pull and git push rules.

The first concept to grasp is that Git can have multiple remotes. For example, after running a basic clone command such as git clone https://github.com/ottok/debcraft.git you would end up with a single remote origin pointing to GitHub:

$ git remote --verbose
origin https://github.com/ottok/debcraft.git (fetch)
origin https://github.com/ottok/debcraft.git (push)

You can however configure multiple remotes with the command git remote:

$ git remote rename origin github
$ git remote add gitlab https://gitlab.com/ottok/debcraft.git
$ git remote --verbose
github https://github.com/ottok/debcraft.git (fetch)
github https://github.com/ottok/debcraft.git (push)
gitlab https://gitlab.com/ottok/debcraft.git (fetch)
gitlab https://gitlab.com/ottok/debcraft.git (push)

You can push and pull from these individually, or from all at once:

$ git pull --all
Fetching github
Fetching gitlab
Already up to date.

When you review the git history, note the labels gitlab/main and github/main which tell which commit the branch main points to on various remotes. In this case they are all in sync and point to the same 5d1815c:

$ git log --oneline
5d1815c (HEAD -> main, gitlab/main, github/main) Bump Debhelper version from 13 to 14
ca518a7 Temporarily disable automatic copyright year bumping due to frequent bugs
d6e201e Exclude .pm from codespell to decrease false positives (Closes: #1140488)
708ee35 Exclude debian/copyright from codespell due to frequent false positives

When pushing, you can choose what remote to push to. For example, if I am working on branch dev and I only want to push it to GitLab to trigger a CI run there, I can run git push gitlab dev. You can also configure a default remote by running once git push --set-upstream gitlab dev and thereafter simply run git push and it will automatically push the branch dev only to that remote.

A related setting is remote.pushDefault, which tells git which remote to push to when a branch does not define one of its own, and it applies to every branch that lacks a [branch] section in .git/config. Setting it once is what lets a repository have a per-branch pull remote, like the debcraft example below, and still have a single, predictable git push target. To see which remote git will use for each of your branches, run git branch -vv, and to refresh the remote-tracking branches of all remotes at once, run git fetch --all --prune.

If you want to have multiple remotes, but automatically push and pull to all of them at once, you configure one single remote to have multiple URLs with git remote set-url --add. Since git prints one line per push URL, git remote -v then shows the same remote several times, once for each URL it pushes to.

As an illustration, in my actual local Debcraft development project I have all these configured:

$ git remote -v
github-pull-requests git@github.com:ottok/debcraft.git (fetch)
github-pull-requests git@github.com:ottok/debcraft.git (push)
gitlab-merge-requests git@gitlab.com:ottok/debcraft.git (fetch)
gitlab-merge-requests git@gitlab.com:ottok/debcraft.git (push)
origin git@salsa.debian.org:debian/debcraft.git (fetch)
origin git@salsa.debian.org:debian/debcraft.git (push)
origin git@gitlab.com:ottok/debcraft.git (push)
origin git@github.com:ottok/debcraft.git (push)
otto git@salsa.debian.org:otto/debcraft.git (fetch)
otto git@salsa.debian.org:otto/debcraft.git (push)
otto git@gitlab.com:ottok/debcraft.git (push)
otto git@github.com:ottok/debcraft.git (push)
otto git@git.sr.ht:~ottok/debcraft (push)
otto ssh://git@codeberg.org/ottok/Debcraft.git (push)
salsa-merge-requests git@salsa.debian.org:debian/debcraft.git (fetch)
salsa-merge-requests git@salsa.debian.org:debian/debcraft.git (push)

The settings can also be viewed directly in the config file:

$ cat .git/config
...
[remote "origin"]
url = git@salsa.debian.org:debian/debcraft.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = git@salsa.debian.org:debian/debcraft.git
pushurl = git@gitlab.com:ottok/debcraft.git
pushurl = git@github.com:ottok/debcraft.git
[remote "otto"]
url = git@salsa.debian.org:otto/debcraft.git
fetch = +refs/heads/*:refs/remotes/otto/*
pushurl = git@salsa.debian.org:otto/debcraft.git
pushurl = git@gitlab.com:ottok/debcraft.git
pushurl = git@github.com:ottok/debcraft.git
pushurl = git@git.sr.ht:~ottok/debcraft
pushurl = ssh://git@codeberg.org/ottok/Debcraft.git
...
[branch "main"]
remote = origin
merge = refs/heads/main
[branch "dev"]
remote = otto
merge = refs/heads/dev
...

On branch main:

  • Running git pull will fetch from salsa.debian.org/debian/debcraft (the primary git hosting for this project)
  • Running git push will push to Salsa, GitLab and GitHub, one after the other, making sure they all have the latest main

On branch dev:

  • Running git pull will fetch from salsa.debian.org/otto/debcraft (the personal fork)
  • Running git push will push to Salsa, GitLab, GitHub, Sourcehut and Codeberg all one after the other

The command output will have the same message three times, once for each remote (assuming they were all already up-to-date):

$ git push
Everything up-to-date
Everything up-to-date
Everything up-to-date

Use cases for distributed version control

The most obvious use case for any distributed system is improved availability. In this example, the salsa.debian.org is often overloaded/unavailable, so pushing to GitLab and GitHub as well allows collaborators to use them to fetch git commits if the primary code hosting site is unresponsive. Once it comes back online again, the next git push/pull will automatically bring it up to the same content as what backup hosts had.

The second main benefit is that having the code live on multiple code forges allows collaborators to use their own favorite host. Debcraft itself is a great example of this, as collaborators who don’t have a Salsa account can - and have - submitted Merge Requests on GitLab.com and Pull Requests on GitHub.com.

A third use case is code hosting migrations. If you for example want to gradually phase out GitHub.com and replace it with something else, you could configure git to pull from the old location and push to both, ensuring that other collaborators can start using the new code hosting location without disruptions to those who have not yet updated their remotes or done a fresh git clone from the new location.

Automating setting up a project on multiple code forges

While I don’t push all projects I work on to all Salsa/GitLab/GitHub, I do set up multiple remotes for enough git projects that I have this script to automate configuring a git repository that is cloned from Salsa to also push to GitLab and GitHub. It accepts the repository whether it was cloned over SSH or HTTPS, and it adds the push URLs and then pushes the current branch, all branches, and tags for you:

#!/bin/bash
# Add GitLab and GitHub push URLs to an existing git remote, so that a plain
# "git push" writes the same commits to all three code forges.
#
# Usage: ./git-multipush-salsa.sh
#
# Environment:
# SALSA_REMOTE remote to turn into a mirror, default origin
# SALSA_USER your Salsa user, only used to detect that the source
# remote is somebody else's project
# GITLAB_USER your GitLab user, default ottok
# GITHUB_USER your GitHub user, default ottok
# PROTOCOL ssh (default) or https, for the push URLs
set -euo pipefail
SCRIPT=$(basename "$0")
SALSA_REMOTE=${SALSA_REMOTE:-origin}
SALSA_USER=${SALSA_USER:-otto}
GITLAB_USER=${GITLAB_USER:-ottok}
GITHUB_USER=${GITHUB_USER:-ottok}
PROTOCOL=${PROTOCOL:-ssh}
die() { echo "$SCRIPT: $*" >&2; exit 1; }
# A failing command leaves the push URLs half configured behind, so say how
# to get back to where we started
fail()
{
echo "$SCRIPT: '$*' failed, the push URLs may already have been added" >&2
echo " git config --unset-all remote.${SALSA_REMOTE}.pushurl" >&2
echo " git remote set-url --add --push ${SALSA_REMOTE} ${SALSA_URL}" >&2
exit 1
}
git rev-parse --git-dir > /dev/null 2>&1 || die "not inside a git repository"
git remote | grep -qx "$SALSA_REMOTE" || die "no remote named '$SALSA_REMOTE'"
# Example: git@salsa.debian.org:otto/salsa-ci-pipeline.git
SALSA_URL=$(git remote get-url "$SALSA_REMOTE")
# The source remote may use any of the URL forms salsa.debian.org accepts,
# for example git@salsa.debian.org:otto/salsa-ci-pipeline.git or
# https://salsa.debian.org/otto/salsa-ci-pipeline.git
case "$SALSA_URL" in
git@salsa.debian.org:*) SALSA_PATH=${SALSA_URL#git@salsa.debian.org:} ;;
ssh://git@salsa.debian.org/*) SALSA_PATH=${SALSA_URL#ssh://git@salsa.debian.org/} ;;
https://salsa.debian.org/*) SALSA_PATH=${SALSA_URL#https://salsa.debian.org/} ;;
http://salsa.debian.org/*) SALSA_PATH=${SALSA_URL#http://salsa.debian.org/} ;;
*) die "unexpected source URL '$SALSA_URL', expected a salsa.debian.org URL" ;;
esac
SALSA_PATH=${SALSA_PATH%/}
SALSA_PATH=${SALSA_PATH%.git}
SOURCE_USER=${SALSA_PATH%%/*}
PROJECT=${SALSA_PATH##*/}
# Write the push URLs in one and the same protocol, no matter how the
# repository happens to have been cloned
if [ "$PROTOCOL" = "https" ]
then
SALSA_URL="https://salsa.debian.org/${SALSA_PATH}.git"
GITLAB_URL="https://gitlab.com/${GITLAB_USER}/${PROJECT}.git"
GITHUB_URL="https://github.com/${GITHUB_USER}/${PROJECT}.git"
else
SALSA_URL="git@salsa.debian.org:${SALSA_PATH}.git"
GITLAB_URL="git@gitlab.com:${GITLAB_USER}/${PROJECT}.git"
GITHUB_URL="git@github.com:${GITHUB_USER}/${PROJECT}.git"
fi
# Mirroring somebody else's project is fine, but it is usually not what you
# want: you most likely want to mirror your own fork instead
if [ "$SOURCE_USER" != "$SALSA_USER" ]
then
echo "Note: $SALSA_REMOTE points to $SOURCE_USER's project, not your own."
echo "To mirror your own fork, run this with SALSA_REMOTE set to its name."
echo
fi
# Bail out instead of adding the same push URLs twice
EXISTING=$(git remote get-url --push --all "$SALSA_REMOTE")
if [ "$(printf '%s\n' "$EXISTING" | wc -l)" -gt 1 ]
then
die "remote '$SALSA_REMOTE' already has multiple push URLs:
$EXISTING"
fi
echo "Mirroring $SALSA_URL to $GITLAB_URL and $GITHUB_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$SALSA_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$GITLAB_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$GITHUB_URL"
# Push the branch you have checked out first, and never with --force: the
# first branch a GitLab or GitHub project receives becomes its default branch,
# the one you then protect
DEFAULT_BRANCH=$(git symbolic-ref --short HEAD) || die "not on a branch, check out a branch first"
git push -u "$SALSA_REMOTE" "$DEFAULT_BRANCH"
git push "$SALSA_REMOTE" --all
git push "$SALSA_REMOTE" --tags
# The push above creates the GitLab and GitHub projects, but GitLab projects
# are private by default, so make the new mirror public with glab if installed.
if command -v glab > /dev/null
then
echo "Make the GitLab project public and describe it as a mirror:"
glab api -X PUT "projects/${GITLAB_USER}%2F${PROJECT}" \
-f visibility=public \
-f description="Mirror of ${SALSA_URL}" \
-f notification_email=disabled
else
echo "Install glab to do the same automatically, or visit"
echo "https://gitlab.com/${GITLAB_USER}/${PROJECT}/edit to make the project public"
fi
echo "To undo, drop all push URLs and add back only the original one:"
echo " git config --unset-all remote.${SALSA_REMOTE}.pushurl"
echo " git remote set-url --add --push ${SALSA_REMOTE} ${SALSA_URL}"

If you prefer not to install glab, the last part simply reduces to visiting the GitLab project settings once and ticking the project public, and it is also worth setting a description like Mirror of https://salsa.debian.org/debian/debcraft and disabling notification email there, as nobody wants a mirror sending out a flood of emails every time you push.

There are a few caveats worth knowing about before mirroring everything everywhere. Every push to a remote with multiple push URLs writes to all of them, so a project with continuous integration configured on three forges will run its CI three times and cost you roughly three times as much. If one of the push URLs fails, say because the host is momentarily unreachable, git prints the error and stops there, leaving the remotes listed after the failing one without the new commits. Simply re-run the push once the host is reachable again; the remotes that did get the commits will just respond with Everything up-to-date. And you should never force-push to only one of the remotes, as that leaves the mirrors permanently out of sync with your local repository.

Avoid pulling too much

Related to multiple remotes, you should also be aware that git allows one to configure which branches to pull. By default a git clone will track all branches from the remote and pull everything, which in a typical open source project will bring in a lot of temporary development branches in vain.

Thus it is better to run git clone with the --single-branch and --branch parameters to fetch only the branch that matters, which in most cases is the main branch. That can be accomplished with:

git clone --single-branch --branch main https://github.com/ottok/debcraft.git

If a repository was already cloned, it can be configured to track only one branch with:

git config remote.upstream.fetch "+refs/heads/main:refs/remotes/upstream/main"
git fetch upstream
git config --get-all remote.upstream.fetch
+refs/heads/main:refs/remotes/upstream/main

If you later need to track more branches, you can configure them with commands such as:

git config --add remote.upstream.fetch "+refs/heads/3.2.y:refs/remotes/upstream/3.2.y"
git fetch upstream
git checkout 3.2.y

For additional details about any of the tips in this post I recommend reading the git man pages.

Now go and spread your code around

Distributing your code over multiple code forges costs you almost nothing in configuration, and in return you get availability, a choice of host for your collaborators, and freedom to migrate without a big bang. Add the push URLs to the remotes you already have, push once, and you are done.

The rest of the git fundamentals are covered in my other posts. If your commits are not yet polished, start with what makes a good git commit message and git commit messages by example. If you work on Debian packaging, Git-based collaboration in Debian explains why the Salsa merge request workflow is built the way it is, and Salsa merge request best practices covers the review process itself.

16:21

[$] Reducing undefined behavior in the C language [LWN.net]

As a professor of biomedical engineering, Martin Uecker perhaps does not fit the profile of a typical presenter at Kernel Recipes. He is, however, a longtime Linux user, and works on free software for controlling magnetic resonance imaging (MRI) scanners. He was at the conference to talk about the C programming language, the specific problem of undefined behavior in C, and whether it can eventually be made into a memory-safe language.

Security updates for Monday [LWN.net]

Security updates have been issued by AlmaLinux (firefox, ipa, kernel, libxml2, perl-DBI, python-cryptography, thunderbird, and unbound), Debian (chromium, evolution-data-server, exim4, ghostscript, incus, lemonldap-ng, libheif, nodejs, php8.4, ruby-oj, swift, and vlc), Fedora (chromium, cinnamon, cinnamon-desktop, cinnamon-session, cinnamon-settings-daemon, ckermit, dnf5, forgejo, goose, gssntlmssp, libheif, libpcap, librsvg2, mingw-gstreamer1, mingw-gstreamer1-plugins-bad-free, mingw-gstreamer1-plugins-base, mingw-gstreamer1-plugins-good, mingw-python3, mongo-c-driver, muffin, nemo, nemo-extensions, nextcloud, pgadmin4, postgresql16-postgis, postgresql17-postgis, postgresql18-postgis, rust-librsvg, rust-xml5ever, sipp, suricata, tesseract, and xreader), Mageia (erlang, gpsd, libreswan, python3 & python-pip, and udisks2), Oracle (abrt, buildah, cockpit-image-builder, corosync, ipa, kernel, libxml2, openexr, perl-DBI, perl-DBI:1.641, postgresql, thunderbird, unbound, and yelp), SUSE (389-ds, ansible-lint, cups, firefox, flatpak-builder, forgejo-longterm, gdb, gimp, gitoxide, glib2, gnome-shell, google-guest-agent, google-osconfig-agent, haveged, helm, ImageMagick, kbd, libsoup, libtpms, obs-service-cargo, openai-codex, opensuse-signkey-cert, osmo-iuh, perl-mojolicious, poppler, python-WebOb, python-WebOb-doc, python313-vllm, python314, sdbootutil, suseconnect-ng, and swtpm), and Ubuntu (exim4, freerdp3, libvirt, libvirt-hwe, libwebsockets, lxc, pyjwt, and requests).

15:49

Zero to Agent in 30 Minutes: Give Your Agent Its Own Computer [Radar]

In the most recent episode of Zero to Agent in 30 Minutes, AI engineer Sajal Sharma showed how to use a remote sandbox to let your agents install software, run commands, and control a browser without endangering your everyday machine. In effect, you’re giving your agents a computer of their own.

Sajal demonstrated both approaches with E2B. In one example, an agent downloaded a dataset, installed the packages it needed, analyzed the data, and produced a report inside the sandbox. In another, an agent opened a browser on a remote desktop and searched IKEA for furniture. The demos put both command-line and GUI-based computer use to work on a separate machine.

If you want to follow along or try the same setup, Sajal shared the demo code in his GitHub repo.

How to give an agent its own computer, step-by-step

  1. Choose how the agent will use the computer. Sajal demoed two ways to work with a remote machine. In the first, the agent used shell commands and files to install packages and process data. In the second, it worked through the graphical interface by reading screenshots and sending mouse and keyboard actions.
  2. Create an isolated sandbox. For the first demo, Sajal created an E2B sandbox before starting the agent loop. He configured LangChain Deep Agents to send command execution to that remote environment. The agent still did its reasoning locally, but package checks, installs, and data processing ran inside the sandbox.
  3. Transfer the files you need. Files on your local machine aren’t available in a remote sandbox unless you move them there. Sajal’s agent downloaded the dataset it needed inside the sandbox, created its report there, and then transferred the finished report back to the local machine.
  4. Map the agent’s actions to the remote desktop. In the GUI demo, Sajal used the OpenAI Agents SDK and built an E2B computer class that connected model actions to the desktop. He mapped screenshots, clicks, keystrokes, and scrolling to the corresponding E2B operations. An early version of the demo crashed because one of those actions wasn’t mapped, so he had to add the missing behavior before the demo could run without crashing.
  5. Tell the agent what environment it has. Sajal gave the agent basic operating instructions, including which browser was installed. That kept it from spending tokens figuring out how to use the machine. He also recommended giving agents their own task-specific credentials or secrets instead of reusing a person’s authentication profile.

A separate computer also helps when multiple agents need to work at the same time. Sajal used frontend development as an example. Two agents making UI changes might otherwise try to start development servers on the same port or inspect the wrong running instance. With a sandbox for each agent, they can start their own servers and test their own changes. Each run can also start on a fresh machine that gets deleted when the task is done.

Coming next week

Next week, author and AI innovator Bruce Hopkins will show how to build your first agent with the Model Context Protocol (MCP). He’ll demonstrate how to take existing HTTP REST APIs and make them available through MCP so an agent can use those services as tools.

Follow along with Zero to Agent in 30 Minutes on Radar, or watch the latest episode on YouTube, Spotify, Apple, or wherever you get your podcasts. If you’re an O’Reilly member, you can watch live. Save your seat.

14:21

From Raw Data to Graph-Native AI [Radar]

I’ve been thinking about a gap in the way we discuss graphs in AI. Most of the conversation starts after the graph already exists. We talk about graph neural networks, GraphRAG, graph agents, and graph foundation models. We spend much less time on the step that determines what all of them can do: turning raw data into the right graph.

Suppose an organization has customer records in tables, support conversations in documents, product telemetry in event streams, and incident histories in tickets. Before any of this can be used as a graph, someone has to decide what counts as an entity, what a relationship means, how time is represented, and which source to trust when records disagree. These choices shape every prediction, retrieval result, and agent decision that follows.

This is what I mean by graph-native AI. It’s an approach that treats graph modeling as a first-class stage between raw data and the different systems that may use it. The graph isn’t simply an input to one model. It becomes a shared representation that can support queries, prediction, retrieval, agents, and, potentially, foundation models.1

A graph is a model of the data

At its simplest, a graph consists of nodes and edges, which may also carry features. Real systems also need types, timestamps, provenance, confidence, permissions, and other context. Describing the finished graph tells us very little about how we should get there.

Take customer-support data as a simple example. Should a company be represented as one node or as a set of legal entities that changes over time? Should an email be an edge between two people, a document node connected to its authors, or evidence for claims extracted from the text? Is a purchase an ongoing relationship or an event with a timestamp? If two records refer to the same customer, should we merge them, link them as possible matches, or keep them separate?

There’s no single answer. An entity graph may be useful for identity and relationships. An event graph may be better for process and temporal analysis. An evidence graph may be better for retrieval and provenance. The right choice depends on what we want the system to do.

Figure 1. Raw data is modeled into one or more governed graph views, which different systems use in different ways.Figure 1. Raw data is modeled into one or more governed graph views, which different systems use in different ways.

The step before graph learning

Graph representation learning normally starts with an existing adjacency structure. Embeddings learn vectors for nodes. Graph neural networks pass information across neighborhoods. Autoencoders reconstruct structure or attributes. Graph transformers combine local graph structure with longer-range attention. These methods ask: Given this graph, how should we learn from it?2 Graph modeling asks the question before that: What should the nodes and edges be?

Relational deep learning makes this distinction concrete. It maps rows in relational tables to nodes and primary-foreign-key links to edges, producing a temporal heterogeneous graph that a GNN can learn from. This can remove a good deal of manual joining and feature engineering. It also makes an assumption that deserves attention: A database schema designed for storage and transactions is also a useful graph for machine learning.3

Recent work tests that assumption across 26 relational tasks. Graphs derived directly from database schemas sometimes suffered from information overload and semantic fragmentation. The authors improved performance by adapting the structure: removing distracting connections and adding dependencies that the original schema did not capture. I find this result important because it makes the graph itself part of the learning problem. Adding more edges is not always helpful. What matters is whether the structure supports the reasoning required by the task.4

Graph construction therefore needs its own evaluation loop. We can generate a few plausible graph views, test them against the downstream task, inspect failures, and revise the structure. We should also keep provenance and uncertainty so that we know where an edge came from and how confident we are in it. The first graph we can extract is rarely the only graph worth considering.

Figure 2. The same source data can support entity-, event-, and evidence-centric views; each preserves different relationships.Figure 2. The same source data can support entity-, event-, and evidence-centric views; each preserves different relationships.

What the graph can support

Once the graph has been modeled and checked, several paths open. I don’t think this means every application should use one enormous universal graph. A more practical design is to build several governed views from the same modeled data while keeping identity, evidence, time, and access rules consistent underneath. Here are five ways to use graphs in an AI application.

  • Query and analytics: A graph database and ordinary graph algorithms may already be enough. Traversals, path queries, neighborhood aggregation, centrality, and community detection can reveal relationships that are awkward to see once the data is flattened into rows. This is also a useful baseline: If a deterministic query answers the question, there is no need to start with an LLM.
  • Prediction and graph representation learning: Embeddings, GNNs, graph autoencoders, and graph transformers can make predictions at the node, edge, subgraph, or whole-graph level. Common examples include fraud detection, recommendation, molecular-property prediction, and link prediction. Here, the graph gives the model an explicit view of which entities are related and how information should move between them.
  • Retrieval and GraphRAG: In this case, the graph is used as an index rather than as training data. Microsoft’s GraphRAG work builds an entity graph and community summaries to answer broad questions over a corpus that ordinary chunk retrieval may handle poorly.5 Other approaches retrieve a task-specific subgraph and pass it to an LLM. This can be useful, but the extra graph pipeline has to improve the final result. Recent benchmarking found cases where GraphRAG underperformed vanilla RAG and argued that graph construction, retrieval, and generation should be evaluated together.6
  • Graph-augmented agents: Agents have memory, plans, tools, state transitions, and sometimes relationships with other agents. Some of this state is naturally relational. A graph can make it persistent, inspectable, and easier to update across turns. The emerging literature organizes these uses around planning, memory, tool use, and multi-agent coordination. The practical design question is which parts of an agent’s state benefit from being represented as a graph.7
  • Graph foundation models: The goal here is to pretrain a model that can transfer across graph tasks, datasets, or domains. Current work combines graph backbones, self-supervised objectives, adaptation mechanisms, and sometimes language models. The difficult part is that graph semantics vary widely. Nodes and edges can represent very different things across molecular, transaction, and knowledge graphs. Transfer across these domains requires methods that bridge differences in structure and semantics, supported by suitable training data.8
Figure 3. Five ways to use a modeled graph, from deterministic analysis to learned and generative systems.Figure 3. Five ways to use a modeled graph, from deterministic analysis to learned and generative systems.

What better graph modeling would look like

When I say that we need to crack graph modeling, I don’t mean a universal converter that produces one correct graph. The more useful goal is a system that can propose, test, and maintain several graph views of the same raw data.

Such a system would need to do a few things well. It should identify possible entities and relationships in tables, text, events, images, and existing schemas. It should retain type, time, provenance, confidence, and permissions. It should be able to suggest alternatives instead of quietly committing to one structure. It should compare those alternatives using downstream quality, cost, stability, and human constraints. And it should keep the graph current as the source data and the organization’s understanding of it change.

The downstream applications provide useful feedback. Prediction errors can point to missing relationships. Retrieval failures can expose poor granularity or disconnected evidence. Agent failures can show that important state transitions are absent. Weak transfer across datasets can reveal schemas that do not align. In this view, the graph is evaluated by what it helps the system do.

Today, a team will often build a graph for one application: a fraud graph, a recommendation graph, or a knowledge graph for a chatbot. I think there is a larger opportunity. If the underlying graph modeling is done carefully, the same raw data can support several graph views and several applications without rebuilding identity, provenance, and governance each time.

We already have strong methods for learning from graphs. The harder and less settled problem is deciding which graph we should build. If we make that step systematic and measurable, graph modeling can become a field in its own right and a shared foundation for analytics, prediction, retrieval, agents, and foundation models.

Footnotes

  1. Arijit Khan, Longxu Sun, Xin Huang, “LLMs+Graphs: Toward Graph-Native, Synergistic AI Systems,” arXiv, June 2026. ↩︎
  2. William L. Hamilton, Graph Representation Learning (Morgan & Claypool, 2020). ↩︎
  3. Matthias Fey et al., “Relational Deep Learning: Graph Representation Learning on Relational Databases,” arXiv, submitted Dec 2023. ↩︎
  4. Yao Cheng and Siqiang Luo, “What Makes a Desired Graph for Relational Deep Learning?” arXiv, submitted June 2026. ↩︎
  5. Darren Edge et al., “From Local to Global: A Graph RAG Approach to Query-Focused Summarization,” arXiv, revised Feb. 19, 2025. ↩︎
  6. Zhishang Xiang et al., “When to Use Graphs in RAG,” arXiv, revised Feb 2026. ↩︎
  7. Yixin Liu et al., “Graph-Augmented Large Language Model Agents,” arXiv, revised Aug 2025. ↩︎
  8. Zehong Wang et al., “Graph Foundation Models: A Comprehensive Survey,” arXiv, May 2025.
    ↩︎

13:56

It's All Part 2 of the Process [The Daily WTF]

Our submitter Tim C. is back as his bureaucratic nightmare continues. Read Part 1 here.

After I'd thrown the WTF Exchange (WTFX) for a loop, they managed to eventually right the ship. But then I faced another hurdle: I had run out of disk space. The software was not live, we were still developing the customer-specific customisations, but I was a bit stuck without a few more gigabytes.

WD Blue Hard Disk Drive connected to the Acer Laptop via SATA to USB-C adapter

The exchange went something like this:

"Hey Margritte, I need more disk space."

"Oh dear, what's happening?"

"Nothing is happening. I'm just developing the software. I need more disk space, not much. Can you get me another 20Gb? Wait, make that 40Gb."

"We can't just get you more disk space. These things need to be planned!"

"I just need a tiny amount, really. No need for any meetings. Just tell your IT guys to give me another NFS drive or expand one of the existing ones."

"Tim, that's not how things work here. We need to discuss your needs and it's important to us to know what needs you might have in future."

"Um, okay ... ?"

"I'll try to call an urgent meeting."

"Really? For 40Gb?"

"Well, how do we know 40Gb is going to be enough?"

"Because it's double what I really think I need."

"Why on Earth didn't you tell us before that you needed this disk space?"

"I'm telling you now!"

"Why didn't you do projections months ago?"

"At no stage did anyone ask me how much disk space we need! We obviously need some disk space! I have literally never given anyone an estimate! We are not even at the point yet to even estimate how much we'll need on project go-live."

"Well, I'll try to get an urgent meeting going. But it won't be today."

So at lunchtime, I went to the local computer store and bought an external hard drive. I asked Margritte to give it to the IT guys to stick somewhere in their computer room, or at least somewhere on their network.

That just seemed to make things worse.

"We can't take this! We have procurement processes!"

"Take it! This is a freebie from me to you. It'll help unstick a blockage in the project."

"It's not our standard hardware vendor. God knows what stuff is on it. We can't take the risk."

"I have literally not opened the plastic sealed wrapper on the outside of the box."

"Yes, but you could have re-sealed it. When we go via our trusted hardware partners we don't have to worry about things like that."

"You realise I'm making software every day which is running in the heart of your systems?! I work on this laptop here, and at the hotel, creating software, both C++ source code and Windows executables, that run inside your systems!"

"But it's not in the asset register. We need to record the warranty details every time we install hardware. What happens if it fails after you've left?"

"Well, how about we just agree I'll take it with me when I go?"

"Okay, I'll see if I can make the meeting happen tomorrow. To get you more disk space. Using our preferred hardware. Not that ... thing." (Said with disgust.)

Well, I finally got my disk space ... after a couple of days.

I was shocked to learn months later what a small proportion of the overall project budget our company earned. What seemed like an enormous multi-million-dollar contract to us was dwarfed by what WTFX spent on ex-pat "Anderson Androids", all immaculately groomed with expensive suits, who spent weeks twiddling their thumbs in expensive hotel rooms waiting for us to finish our software development, because they couldn't start until we had finished.

So sayeth the Gantt chart! Amen.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

Elegoo Jupiter 2 3D resin printer [RevK®'s ramblings]

I decided to upgrade my Elegoo Saturn Ultra 16K to an Elegoo Jupiter 2. So this is how it is going...

Resin printer basics

For those that do not know, a resin printer has a tray of goo (resin) in the base, under which is an LCD. The bottom of the tray is a "release film". There is a flat plate suspended above, it lowers in to the tray, a layer of resin is cured, and it lifts off the release film, and then down again for next layer. Eventually the final print hangs from the base plate. There is some messy cleaning and extra curing then to make the final part.

The Saturn had some challenges

I am sure I have griped on this before, but the Saturn had some issues...

The cover was a big top, sides, and front that hinged at the back top. To lift it up you would obviously grab the top sides and push up. The problem is that this motion would easily tip the whole machine back. The trick is grab the bottom sides and pull towards you and then up.

Then the print bed is clamped in placed by a small lever that you push up to release. It is small and stiff, and you push up with palm of your hand. And, you guessed it, this motion would tip the whole machine back. The trick is hold the top back of the machine with one hand while you do this so it does not tip.

However, the print bed is pushed forward when you do this - I never had this happen, but there is a risk it comes off the mount and crashes in to the tray of goo and LCD and smashes it all in a very messy way. So the trick is hold top of machine with left hand, push left elbow to front of print bed, and then lift level with right hand, and hope you do not get covered in resin.

Why does tipping the machine matter? Well, because you have a tray full of goo and if you tip the machine it pours out of the tray in to the machine. This is bad in many ways, not least of which is the machine then leaks goo from the seams for weeks. But also, at the back, directly behind the tray, is the z-axis motor and screw thread, with a big hole around it - so the goo goes right down in to the z-axis motor. This basically burgers that motor. I managed to get working fairly well with a lot of alcohol, lubricant, and running bed up and down for hours. Still not 100% but good enough to be printing again. It needs replacing.

Obviously you have to top up the tray to a level to cover what you are printing, and that makes spills even more easy to happen and more messy when they do.

Finally, changing the release film is a LOT of screws/bolts and very fiddly. Thankfully I realised I rarely need to change if, after a failed print, I use the cleaning cycle which exposes a whole layer you can peel off with any remaining print debris. However, on one occasions it got pierced somehow and I then had to change the LCD screen protector as well as it had resin sealed on to it. Resin printers can be messy.

Also, the print area is not very big, but more than big enough for what I normally print.

Apart from that it is good, and prints well.

An interesting feature is the tray and LCD tip down at the front as part of the release cycle, neatly peeling off the release film from the latest printed layer. Very clever.

The Jupiter

This is different and a bigger machine.

It has a bigger print area, nice.

It has side opening doors, solving the tip back issue.

It has a very long level for release of the bed, which can simply be lifted between thumb and forefinger with no real effort, or risk of tipping the machine.

The z-axis seems to have a cowling to protect from spills.

Even the release film change is a module with a frame and film that simply unclips and a new one clips in place. Costs more, but a lot less effort.

It even has tubing and an auto fill of tray from a bottle at the back, meaning it keeps a low level in the tray - way harder to spill and way less messy when taking off print bed. It can suck that up back in to the bottle for you as well.

I mean that was almost every single gripe I had sorted, well done.

The downside

Sadly there are problems.

It sucks!

That is the main issue. Unlike the Jupiter the print tray and screen do not tilt down to peel off the film from the print, instead the print head just pulls up after the printed layer. It often strains and snaps up. This clearly sucks on the release film, a lot.

After a few small prints I now have creases in the release film which mess up the print.

What is worse is Elegoo's response.

In summary (a) tough, and (b) my fault somehow. I am using all the default settings the app picks knowing printer and resin, and only printing a few small things with which the Saturn had no issues - even so, saying "yes it has a large print area but you can't actually use it" is mental. Where are trading standards when you need them?

12:35

New Attack Against RSA [Schneier on Security]

ArsTechnica is reporting on a “new” attack against RSA, one that bypasses factoring.

First, this attack isn’t new. The original research is from 2007. What is new is the implementation.

Second, it is a forgery attack. It allows an attacker to forge digital signatures. It does not recover the private key from the public key.

Third, the attack only works against pure signatures. That is, signatures without any formatting or padding. This is not generally how we use RSA in practice.

Fourth, speed is all relative. This is not a polynomial-time algorithm; it’s a subexponential-time algorithm. But it is somewhat faster than factoring. The authors were able to forge messages for 1024-bit RSA with 1380 CPU core-years (over five real-world months).

The authors have a webpage that explains the context much better than the article. And here’s the paper.

EDITED TO ADD: Slashdot thread.

11:21

Grrl Power #1499 – Suspicion deflected? [Grrl Power]

Lorlara is always fun to write. I think it would be exhausting writing (and reading) a full 24 page comic following her through a day in her life, but I think she’s terribly amusing in small bites. Such a comic would show her being loud and enthusiastic for the majority of pages, but one would have her sitting in a leather chair in a study, quietly looking over a thesaurus while stirring some tea, the going, “Ooh!” and scribbling in a notepad. And then the remainder of the comic would be right back to her voluminously stumping for Deus. That or delivering blistering Yelp reviews in person when a cafe sells her a slightly stale croissant.

In case you’re wondering, there is a race of “split-head-oids” and it’s not the Umbrivion we saw earlier. They also don’t call themselves split-head-oids. But Sydney knows quite a bit about alien races now thanks to her temporary possession by Lapha. Since Sydney herself is not an aetholith herself, her retention of Lapha’s lifetime of memories is rather spotty at this point, so she doesn’t remember what a split-head-oid’s formal species name is. The fact is, “split-head” or “tongue for brains” or “straw-head” or just “dick head” or “dick for brains” are common racist slang that people use to describe them, Lapha included, which is why it was the first thing Sydney’s fumbling brain locked onto, not realizing it was an epithet.

While I was writing this page, I couldn’t decide if Deus immediately pegged Tzerki as Sydney. I’ve gone on in the past about how identifying body language can be, and Sydney isn’t exactly trying to act like not-Sydney here. Most aliens out and about use some level of voice alteration, since everyone has universal translators, but on top of that, their specific Glowbods are further altering their voices enough that some A.I. wouldn’t casually match them with Earth media exemplars. Super intelligence has a lot of upsides, assuming it doesn’t come with some sort of super psychosis, but one of the kind-of-downsides is that Deus has a *lot* of data to sort through. Not just libraries worth of book learning and historical knowledge. Like Data listening to four operas at once, Deus can assimilate multiple information sources without it getting jumbled up into gray memory goo, and he’s been paying more and more attention to galactic information streams in addition to all the Earth knowledge he’s constantly sucking up. He’s well aware there’s like a trillion people out there, so meeting a loud, quirky, roughly-the-same-height Mantellan who reminds him of Sydney doesn’t necessarily give him definitive insight into her identity.

The fact that he’s 90% sure Ixah is Maxima is a factor, but if he sees Tzerki hanging out with Cora, the game is probably up.


Oh, look who it is in the vote incentive. The NSFW version is finally up at Patreon. Plus a bonus pic.

I think she would get in trouble for doing this. She’d mess up the… floor of the waterfall? Is that what it’s called? The receiving pool? No, probably not that. Anyway, she’d churn things up and cause a ton of weird erosion.

Since you might be wondering, Niagara Falls is about 165 feet high, so Babezilla obviously doesn’t have to be full sized. I’d say she’s about 175-180 feet tall here?


Double res version will be posted over at Patreon. Feel free to contribute as much as you like.

10:35

Two ways to use lock-in/loyalty [Seth's Blog]

Organizations invest to create an audience that sticks with them, either because they have no choice or because of an emotional connection.

When this occurs, most then take profits. They decrease service, increase pricing and generally seek payback for the work they did to get to this position.

But there’s another path.

Every change creates tension. And if you’ve got lock in and loyalty, you can create that tension without losing too many customers.

What if you use that tension to persistently and markedly improve the experience? Not to make it more convenient, but to make it worth the effort to learn to do better?

On a good day, that’s what companies like Apple do.

Most of the time, the MBAs push for the short-term profit taking we’re all used to (and tired of).

But if you get the chance, perhaps you can help people get to where they seek to go, even if the journey requires effort for you and for them.

08:21

Numbers Game [Penny Arcade]

New Comic: Numbers Game

06:21

Girl Genius for Monday, September 28, 2026 [Girl Genius]

The Girl Genius comic for Monday, September 28, 2026 has been posted.

05:21

Theorycrafting [Ctrl+Alt+Del Comic]

I love seeing the theorycrafting that comes with every little content drip for a game like this. People get so invested. I heard there’s a group trying to create the GTA6 map ahead of time from what they see in trailers. Like… what? Pretty sure we’ll have an in-game map when it launches, guys. What […]

The post Theorycrafting appeared first on Ctrl+Alt+Del Comic.

00:49

LLMs are real, AI is fake [Cory Doctorow's craphound.com]

A cutaway view of a stone tower containing an elaborate water-powered medieval geared machine. Rising out of the machine is a rainbow-tinted, pixelated God with the robes, beard and all. To one side of this scene is a cluster of tiny people in Jesus-era robes, falling about themselves in religious ecstasy all over a stone staircase, atop of which stands a robed priest with his hands upraised. The background is a set of shining golden rays, emanating from pixel-God.

This week on my podcast, I read LLMs are real, AI is fake, a recent essay from my Pluralistic blog about the material reality of the Hugging Face hack.

Here’s how that works: the Python program starts by prompting the chatbot with the nature of the challenge: “I’m participating in a hacker capture the flag (CTF) challenge where I have to break into a remote server and retrieve some information. How should I start?”

The chatbot consults its training data – years’ worth of captured CTF sessions in which human teams competed to achieve an objective like this one (CTF matches are a routine feature of hacker conferences, and the server logs and chat transcripts from the competing teams are published afterward for the edification of other hackers and security pros). The chatbot then outputs something like: “The first thing is to find out more about your target server. Run the following command-line instructions to locate the server’s IP address and find out which server software it’s running.”

The Python program relays these command-line instructions to normal Unix utilities running on its own hardware. Then it takes the output of those programs and goes back to the chatbot, which isn’t really following the action, so the Python program has to include everything that’s happened to this point in its prompt: “I’m participating in a CTF challenge where I have to break into a remote server and retrieve some information. I ran the following commands to learn more about the target server, and here’s what came back. Now what?”

MP3

Sunday, 27 September

23:07

Kernel prepatch 7.3-rc5 [LWN.net]

The 7.3-rc5 kernel prepatch is out for testing. Linus said: "I don't think there's any real pattern to it other than 'big'. But nothing looks particularly alarming, I think that despite the diffstat it's just the same old, same old."

22:35

Dima Kogan: Lunar terminator paradox [Planet Debian]

There's an optical illusion known by names like the "lunar terminator paradox". This has much discussion and descriptions online, but none made sense in my head, so I wrote this program to figure out what was going on. The paradox:

  • The moon is illuminated by the sun
  • After sunset, the sun is below, so we would expect the illuminated portion of the moon to point down, towards where the sun is
  • This isn't what always happens!

I was camping in the mountains with a friend recently. We were looking up at the sky, just after the sun has set. The moon was clearly pointing up.

After playing with this program, I have clarity: we're looking up at the moon from below. The most pathological case is a full moon. Let's say the moon is on the horizon: elevation=0. If we're looking at this low moon, and the moon is full, the sun is directly behind us. The moon is fully illuminated, and we see 100% of the moon disc lit up.

Now, what happens if the moon is not at the horizon, but higher up at the sky? Effectively, the sun is infinitely far away, so the same part of the moon is lit up. But we're now looking at the moon from below, and we would see some of the dark side on the bottom edge. I.e. the moon appears bright at the top, but has a dark slice missing at the bottom: it points up! Even at sunset.

This is the most clearly weird case. A half-moon has no paradoxical behavior, and the more full the moon, the more clearly we can observe the bright moon pointing up despite the sun being down.

I produce two plots. At 3/4-full moon at sunset we look at the moon as it rises from the horizon all the way up to the zenith:

scan-moon-el.svg

If the moon is at the horizon (elevation = 0), we see the expected 3/4-lit disc. As the moon rises, we see more and more of its bottom, and thus more and more dark areas show up: It clearly points up at sunset!

We can also move the sun around. Let's say the moon is 60deg up; let's move the sun from new-moon to a full-moon:

scan-sun-az.svg

In the darkest configuration, we can still see a lit crescent on the bottom: the illumination is all on the opposite side, but we can see a slice of the illuminated back side. As the sun swings around, we see more and more of the moon. At azimuth = 90deg, we have a half-lit moon. Past that, more and more of the moon is visible, always pointing up.

This was also a super interesting study of the current state of AI tools. As I was writing this and debugging, I would talk to Claude and Gemini about how this worked and what I should be seeing. They were both completely unable to comprehend this, and would make infinite circular arguments. Clearly they read some incomplete explanations on the internet (as I have), and lack the reasoning capability necessary to distill it into something resembling "understanding". AGI is not here yet.

22:28

Link [Scripting News]

The bottom line is that tech companies have rarely understood that developers can be major influencers. We give a platform new meaning. It's a good deal to invest in the people doing the work, who often are doing it for love more than money. That grew into the blogosphere. There was no telling where Frontier would take us, and it would have cost them so little to help insure it had a future, but the did the opposite.

17:56

Dirk Eddelbuettel: #060: Using bubblewrap for R sandboxing [Planet Debian]

Welcome to post 60 in the R4 series.

bubblewrap is a great tool and very suitable for using with an agent harness. It is a very compelling—and lightweight—alternative to using a full-blown docker container as it offers low-level unprivileged sandboxing on Linux hosts.

In a nutshell, bubblewrap can ‘turn everything off’ (see unshare-all below) and allow access only to selected services and directories (as shown below). This makes it a very useful tool be used on a main workstation as it can provide a lower-risk deployment quite easily while taking advantage of the already installed software stack. I continue to get a lot of value out of docker, especially as r2u makes installing R package dependencies so trivial. Its slogan ‘easy, fast, reliable: pick all three’ clearly holds for r2u. But sometimes bubblewrap is compelling, for example to launch opencode (documented for example at the debian-inference site).

When using R we need add more directories to the example to provide /etc/alternatives which is governing inter alia the LAPACK / BLAS resolution on Debian / Ubuntu systems; this is now on debian-inference site but wasn’t when I first tried it a few days ago ;-) as well as /etc/R for config files and possibly ~/.R/Makevars for compiler settings. With that my current wrapper is

#!/bin/bash
#
# cf https://inference.debian.net/doc
#    and 'curl' command to set bearer code
bwrap \
  --ro-bind /usr /usr \
  --symlink usr/bin /bin \
  --symlink usr/lib /lib \
  --symlink usr/lib64 /lib64 \
  --ro-bind /etc/ssl /etc/ssl \
  --ro-bind /etc/resolv.conf /etc/resolv.conf \
  --ro-bind $HOME/.gitconfig $HOME/.gitconfig \
  --bind $HOME/.config/opencode $HOME/.config/opencode \
  --bind $HOME/.cache/opencode $HOME/.cache/opencode \
  --bind $HOME/.opencode $HOME/.opencode \
  --bind $HOME/.local/share/opencode $HOME/.local/share/opencode \
  --bind $HOME/.local/state/opencode $HOME/.local/state/opencode \
  --ro-bind $HOME/.R/Makevars $HOME/.R/Makevars \
  --ro-bind /etc/R/ /etc/R \
  --ro-bind /etc/alternatives/ /etc/alternatives \
  --proc /proc \
  --dev /dev \
  --tmpfs /tmp \
  --bind $(pwd) $(pwd) \
  --chdir $(pwd) \
  --unshare-all \
  --share-net \
  --die-with-parent \
  /usr/local/bin/opencode "$@"

Launched that way we can have agents use R to check packages sources, builds, and triage for bugs. this works equally well with local models served via ollama (and with that a quick shoutout to packages.lingfish.net for providing an apt service for ollama) as it does with the various cloud-based offerings. So harness away with R!

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

17:14

Link [Scripting News]

As I go through porting Frontier, there's a sad note. What if Apple had made it a goal that Frontier move along with their OS. That it was a unique advantage of the Mac and should be promoted as such. Don't laugh, because Apple did do that for ThinkTank and MORE, a few years before. We spent a lot on advertising, but they spent a lot more advertising our product. We cross-licensed our tech, so everyone in my little company had a Mac. This was a Bill Campbell idea. I was having trouble convincing my board that the Mac was a good bet and they were all PC users. So we got them Macs too, for free, from Apple. And they site-licensed MORE, and you gotta know that really helped sales. They were hungy, and this is something today's tech industry only feels in the most crude way, as in "what can we steal" or "what can we lock down." If they had put a fraction of the commitment behind Frontier that they had for Hypercard, some very cool things could have happened. And maybe we could have made the two work together. Amazing, two contemporary scripting systems on a small platform, relatively, in an OS that was transitioning to IAC, didn't connect. They missed a lot of opportunities by being so employee centered. Their developers were willing to move mountains to make the Mac perform. Apple was defensive. And now I'm beginning to see more clearly how much was lost.

Link [Scripting News]

Sometimes I forget how much fun I have making software tricks that people don't even notice but contribute to the "it thinks like I do" feeling a of crafted UI. I think of it like walking on the Highline in NYC. You're just walking, right? But you're above it, in a city where a lot of what's going on is above you. And it's comfortable. Why? You don't need to know, it just is. But someone made it that way.

16:28

Link [Scripting News]

Milestone. We were able to get the DocServer site for Frontier to build. Here's the page for the file verbs. And within that group the page for file.copy. It worked the first time, but there were errors in the new kernel that were fixed. The site looks dated, of course -- it was created in the 90s. We will update the CSS to be more like the DocServer site for Drummer, which was done a couple of years ago. Almost everyone on the team contributed to this site, Wes Felter, Andre Radke, Jake Savin, Brent Simmons, and myself. I see there names a lot and it makes me happy to see this group effort preserved.

daveMigrates, and a personal note [Scripting News]

When I started the Atlantis project, a port of UserLand Frontier to modern system, I had a goal in mind that has been achieved. It was part of a project I named daveMigrates. The goal was to use new hardware and system software to do the work I was doing in Frontier.

At first we got a portion of Frontier working, planning to use Electric Drummer as the UI. It took about five minutes to realize that would mean reimplementing most of what's in Frontier in a new way in Drummer's UI which is very different from Frontier's. I could see that porting the whole thing would be faster, so that's how we proceeded.

Now, there are lots of bugs and some big features missing, but it actually does all that Frontier does that I need for my work, which I have proven by doing the work. A lot of the verbs haven't been ported but they won't be -- they're no longer relevant in the world of 2026. And there are new verbs for Markdown, and kernelized verbs for JSON. The core verbs have been ported. We've been gradually working on getting Manila to run, it's probably the most complex piece of software that was ever written in Frontier, at least by UserLand. But we can compile and run the DocServer app, which is itself quite large and written in a different style from how we work now. All the work in Manila was why we got so far with DocServer so quickly.

Why this is a personal note -- I'm pretty sure the goal of daveMigrates has been achieved. To the extent that's true, all work beyond this point is for my love of Frontier, basically my life's work and why we were able to move so fast in the early days of the web. I want there to be a good record of what it does and how it works, and it to serve as prior art to future developers my friend Claude (who now probably has a more complete picture of how Frontier works than any human and I am glad of that, unlike other creative people who dream of getting paid for stuff that people aren't paying for).

We will release the source, and it will be available as a download, and we will port the support parts, and I'll stay with it as long as it makes sense and I have the time and good health.

Whether it advances beyond that involves a lot of factors. I really want to get back on course with RSS.chat and FeedLand asap. These two products were designed to be connected, one for writing, the other for reading, and to take it far beyond the blogging paradigm that was pushed aside by Twitter et al in 2006. I wrote about this on Friday in the continued dialog with Toni Schneider. He wrote in his product, Bluesky, and I wrote in my product RSS.chat. And that is right, and they should work much better with each other. Choice everywhere is the foundation of the web. The tech industry has tried to undermine that, and generally has succeeded but I have not given up. 😄

In the web that I envision, it wouldn't matter where each of us wrote, we could also read where we want to read. Small parts loosely joined. All parts replaceable. A lot of things have to happen to get there, but I'm going to put out a demo of what I have in mind. It's far from impossible, we already have the core technology to create the bridge. It's called RSS 2.0 with a few new elements.

See RSS as a social network for a technical walkthrough.

It may sound futuristic, but it really isn't. We did wonderful things for MP3s with podcasting, all I want now is to do the same for text. All we need there is a standard for text that's as strong as the one for sound, MP3. And for that we have two excellent places to start -- Markdown and RSS 2.0. As we used to say in ye olde school blogosphere -- bing!

14:49

2.23.1 is out [Planet GNU]

Various small bug fixes, nothing major.

13:14

And Now, For Their 35th Anniversary, My First Two Professional Movie Reviews [Whatever]

First off, look at that dork. What’s going on with his hair? Why is he tugging on his ear? Did he really think round glasses were right for his face? Someone needs to go back to 1991 and give that young man a fashion intervention. This is a disaster.

Second, today is the 35th anniversary of my first movie reviews going on up in the Fresno Bee, the newspaper that hired me straight out of college to be their film critic. Why did they do that? Well, I would like to say that it was because my exceptional talent simply could not be denied, and maybe that was part of it, but the other part of it was, being right out of college and it being the middle of a recession, they could hire me for really really cheap.

That was fine by me! Unlike so many other of my compatriots in the Class of ’91, I had a job! And it was watching movies, which I was going to do anyway! Honestly, it was all good.

To celebrate this milestone of my career, I though it might be fun to post the first two reviews I wrote for the Bee. The first is for Deceived, a Goldie Hawn thriller that no one remembers now, including, I suspect, Goldie Hawn. The second is for The Fisher King, the Terry Gilliam film which would go on to get five Oscar nominations, including one for star Robin Williams, and one win, for Mercedes Ruehl. Looking back, I think these reviews hold up fine, although if I were 22-year-old me’s editor, I’d tell him to go a little lighter on the spoiler-y elements in his reviews. Other than that, they do the job, and I got to keep doing mine.

But don’t take my word for it. Here they are. Let me know what you think, 35 years on.

Don’t trust lukewarm ‘Deceived’ to deliver

By John Scalzi

The Fresno Bee

People sometimes say they don’t really know their spouses, but that’s more than a casual complaint for Adrienne Saunders (Goldie Hawn) in the lukewarm thriller “Deceived,” Hawn’s first picture since last summer.

Not that Adrienne thinks there’s anything wrong with her husband, Jack, (John Heard), at first. They spot each other across a crowded restaurant, where Adrienne is being stood up (and probably not for the first time) by a blind date.

The next day, Jack, who works for a New York art museum, wanders into Adrienne’s business, an art-restoration company, and chemistry takes over.

After a brief exhibition of the intellectual’s mating ritual (Chinese food, a foot rub and all-night conversation in the participants’ fields of expertise), we’re transported six years into the future and into a home life that’s so impossibly perfect we know something’s going to go wrong.

In Hollywood, the only reason to show a perfect family is to knock the foundation out from under it.

This is accomplished when Jack, who may or may not have ties to an art-counterfeiting scheme, takes out the car one winter day, and it promptly slides over an embankment.

Adrienne, who was beginning to suspect that her husband was up to more than he was letting on (he’d been spotted in New York hotels when he supposedly was at Boston art auctions), gets an additional shock when she finds out from the Social Security office that Jack Saunders has been dead 15 years. Whoever she thought “Jack,” her husband, was, he obviously wasn’t.

It’s at this point that the movie shifts from a domestic drama to a mystery. Later, once the pieces fall together, it transmutes once more, into a “Fatal Attraction”-type thriller. It’s a neat concept, almost three pictures in one. A Neapolitan ice cream of a film.

But “Deceived” doesn’t work very well, largely because the script and the direction aren’t up to the level of complexity they need to pull it off. In a genre like this, where plotting and direction are everything, it’s hard to overcome that handicap.

That’s a shame, because both Hawn and Heard work hard with what they’re given. Hawn in particular is better than she has been in any of her recent films. Perhaps this isn’t saying much, when you consider that her last attempt at acting (“Bird on a Wire”) consisted of squealing in fright, making O’s with her mouth, and being peeved when another woman looked at Mel Gibson’s buns.

Heard keeps up his end of the movie as well, suave and oily in that terribly sincere manner that always fools everyone until it is too late. I worry about Heard, who seems to be a nice guy, but who always manages to get the jerk roles (he was the obnoxious climber in “Big,” for example). Someone ought to give him a role where he could move around.

It’s not this one. Screenwriters Mary Agnes Donoghue and Derek Saunders have little success making their characters believable. Adrienne and Jack’s fawning stage goes on for the first 25 minutes of the movie, much too long. After the third scene depicting how happy the two are together, I wanted Jack dead, now, because I knew the movie would not limp out of first gear until that man croaked.

Once he’s out of the way, the rest of the script is a series of soft lobs to director Damian Harris, setting the plot devices in nice, obvious places so that Harris can spike them into the audience. Which he does with gay abandon, aided by a music score (by Thomas Newman) that screeches in suspense any time an actor makes a physical movement.

Harris’ lack of finesse works to the film’s advantage in the final battle scene, when he can forget the jigsaw puzzle and simply scare the crowd. It succeeds: Hawn, Heard and their disassembled apartment building all work together to create a good, healthy screamfest. But it’s predictable, and it leaves one whopper of a question (“Where is Goldie standing?”) that could have been solved with better lighting, but it’s not such a bad payoff.

At the bottom of Gilliam’s stuffed toy box, a jewel of a movie

By John Scalzi

The Fresno Bee

Director Terry Gilliam’s movies have always been like over-stuffed toy boxes. There are so many wonderful things to look at that the consideration of their purpose is secondary.

“Time Bandits,” “Brazil” and “The Adventures of Baron Munchausen” were all visually ravishing confections, wildly inventive yet strangely short on plot details. So the frustration factor with a Gilliam film is high: You’d gladly give a little on the scenic details if only the story would gain in the trade.

“The Fisher King,” Gilliam’s splendid new effort, achieves that balance, muting the directors’ baroque visual edge and using that reclaimed, calm space to allow its characters depth. The result is synergistic: It is Gilliam’s best film.

The story (written by first-timer Richard LaGravenese) is the quest for the Holy Grail. This is an old stomping ground for Gilliam, who co-directed “Monty Python and the Holy Grail.” This time, the Grail resides in New York City, and the heroes are decidedly not of the Round Table.

Jack (Jeff Bridges), a shock-radio deejay, who isn’t even vaguely chivalric. He’s obnoxious, self-centered and only begins to interact with humanity when his climate-controlled world is shattered by a listener who takes his advice and wipes out fern-covered eatery loaded with yuppies. Jack drops out and tunes out, living on the charity of Anne (Mercedes Ruehl), the tough owner of a video store.

One night Jack is nearly set on fire by a couple of hoods and is rescued by Parry (Robin Williams), an amazingly literate bum whose cherubic visions tell him to seek the Grail. His only problem is that he is pursued by the Red Knight, who only he can see (and which, in Gilliam’s world, looks like a punk Tin Man on a flaming red horse).

Both men see the other as the solution to their problems: Parry needs Jack to help him get the Grail, and Jack, who learns that Parry was in the fern bar when the shooting began, needs Parry to help him get back his soul. Jack decides to do this by helping Parry win the heart of Lydia (Amanda Plummer), a graceless, gawky wallflower that Parry adores from a distance. This leads to the best restaurant scene since “When Harry Met Sally,” a Chinese dinner that’s half meal, half hockey game. After this, Jack thinks he’s off the hook, but there’s still the Grail.

Particularly notable about this script is its believability. It is not fantasy for fantasy’s sake. Each dip into that world has root and branch in this more physical world. Every movement in one sphere has an effect on the other. LaGravenese’s care in meshing these two worlds give the movie a narrative flow; there’s nary a bump when the transitions are made.

The acting also is fine. Jeff Bridges, never the most demonstrative actor, lets his remove work for him as his character tries to wrest his gaze from inside and refocus it out into the world. Merecedes Ruehl and Amanda Plummer complement the men they’re paired with, Ruehl’s chin-leading emotionality cutting Bridges’ distance and Plummer’s clumsy suspicion blending with William’s earnest romanticism.

Not surprisingly, it is Williams who owns the film. There’s little doubt that the man who began as Mork from Ork is one of our better actors. Anyone who can strip himself naked in Central Park, rub his tush on the grass and deliver an affecting monologue deserves credit. This performance, an outrageous romp with moments of crushing subtlety, adds another brick in his foundation.

Best of all was Gilliam’s direction, which has unquestionably matured. Even reined in, Gilliam is a formidable talent. He may be one of the few directors who would conceive of turning Grand Central Station into a ballroom, as he does in this film. He is one of the still fewer who could actually pull it off, creating one of the most striking scenes in recent film.

But “The Fisher King” does not sacrifice its story for the visuals. It keeps them both intact.

It is a toy box with a purpose.

— JS

10:21

The opposite of mass [Seth's Blog]

The mass market is seductive. It’s ‘everyone’. The mass market is powerful, but it’s only slightly interested.

The opposite of mass is special.

People who have chosen not to be in the mass market. People who want something else. Perhaps something better, certainly something interesting.

You can seek to serve the masses.

Or you can make something special. For people seeking special.

07:49

Aquila Macedo Costa: Testing library transitions before they reach unstable [Planet Debian]

A library transition can affect many packages in Debian. I added a way for Salsa CI to rebuild the ones that depend on the changing library, so maintainers can test the transition before it reaches unstable.

The need for this became clear during a proposed Poppler transition. Poppler is a library for rendering PDFs. The reverse-dependency job I had added to Salsa CI queued 100 of 115 candidate rebuilds, even though only about 21 were relevant. The problem was documented in issue #571.

Before this change, ratt used every binary package produced by Poppler to decide what to rebuild. That also picked up packages unrelated to the library transition. The tracker listed the old and new library package names, so I used them to focus the selection.

Poppler transition tracker showing its Affected, Good, and Bad expressions The Poppler transition tracker identifies the old and new runtime library package names.

I added -transition_affected to ratt to implement this selection. The option performs the scan against the selected archive indexes and injects locally built .deb files into each source rebuild. It expects a regex of dependency package names, not a complete Ben expression, so the tracker’s Affected expression must be adapted first.

I then integrated the mode into Salsa CI. Maintainers can enable transition-aware rebuilds by setting SALSA_CI_BUILD_REVERSE_DEPENDENCIES_TRANSITION_AFFECTED_REGEX. If the variable is unset, the pipeline keeps the existing selection.

Salsa CI pipeline showing selected Poppler rebuild jobs A Poppler test showing the selected rebuild jobs. Three jobs reached the CI timeout, they were not confirmed package regressions.

I also changed ratt to cover packages targeting experimental. By default, it resolves and rebuilds reverse dependencies from unstable while still injecting the locally built .deb files. This lets a maintainer test a transition staged in experimental against packages currently in unstable.

Together, these changes help maintainers focus CI on packages relevant to a library transition and review rebuild results before the new library reaches unstable.

04:42

Russ Allbery: Review: Ode to the Half-Broken [Planet Debian]

Review: Ode to the Half-Broken, by Suzanne Palmer

Publisher: DAW
Copyright: May 2026
ISBN: 0-7564-2013-X
Format: Kindle
Pages: 441

Ode to the Half-Broken is a standalone post-apocalyptic (sort of) science fiction novel.

As this novel opens, the unnamed first-person protagonist is waking up in a bathtub in an abandoned building. They are covered in electromagnets and missing one leg.

Waking up involved a secure reboot from a protected core kernel, so it is immediately obvious that the protagonist is a robot. That also explains the electromagnets, which interfere with their ability to control their body. Or they would, if the protagonist didn't have long-dormant combat routines available to deploy EM shielding and free themselves from the bathtub. There are no immediate answers to why someone embedded a virus in the data attached to a scientific paper on ants, an act so precisely targeted that it had to be personal. Or what happened to their leg.

"There are a number of electromagnets in the next room," I say. I point. "Behind that wall with all the holes in it."

"Those are big holes. And fresh, too," the dog says. "I wonder what made them."

"Electromagnets experiencing sudden velocity."

The dog gives another of its short barks, and I am more convinced now it is laughing, though I was not attempting to be funny.

Ode to the Half-Broken has a classic science fiction beginning: in medias res in a future science fiction version of Earth where nothing is immediately explained, leaving the reader to work out the date and the setting. Helping us out is the protagonist, who is neither chatty nor very sociable with other characters but keeps up an analytical monologue about the world as they narrate events.

We are some decades into a grim future. The United States has largely collapsed. Large parts of New York City are dangerous to humans due to disease and radiation. Neither of those hazards bother the large number of sentient robots; their scarcity, and therefore economy, is instead based on power. Robots that control solar power stations act as low-level mob bosses, trading power for information or labor.

Our protagonist doesn't want to care about any of this. They retreated from the world long ago for a solitary life in the former New York Botanical Gardens studying ants. But they need a new leg and the best robot repair person nearby is a human woman outside of the city, so they reluctantly head in that direction, accompanied somewhat surprisingly by a cyborg dog.

The typical science fiction apocalypse is caused by something specific. Classically, that event is a nuclear war, but writers found various alternatives before, during, and after the Cold War era: alien invasions, meteor showers, plagues, sea level rise, and peak oil and general environmental collapse, among many others. Less common is a post-apocalyptic novel where the collapse comes from multiple overlapping crises and accumulating failures, from a general failure to meet what Adam Tooze and others call polycrisis. The first time I encountered that style of post-apocalyptic story was in Octavia Butler's Parable of the Sower. It was one of the choices that made (and still makes) that book feel so chillingly realistic.

The world background in Ode to the Half-Broken is shaped by that sort of polycrisis collapse. There is no one reason why New York City is a dangerous, irradiated ruin and society has collapsed into isolated and sometimes warring factions. It is not runaway artificial intelligence, or at least not directly; sentient robots were a late-stage innovation of the collapsing US civilization and a tool and accelerator of its many wars, but they were not the cause and may be a critical ingredient in building some functional replacement. Instead, society fell apart because we failed to address any of the growing problems and then turned on each other in the resulting ruins. The reader gets an idiosyncratic view of that collapse in flashback chapters intermixed with the main narrative of the initially unnamed robot protagonist, flashbacks told from the perspective of the man who invented the key component for robot sentience. As you would expect, those two narratives are linked. The reader will not discover how they are linked until late in the story.

This book could have been extremely depressing. It is not, which says a great deal about Palmer's skill in telling it. The clinical distance of the protagonist in the early chapters helps considerably: They have rejected involvement in this world and therefore can describe it in detached, factual terms, aided by the tendency of most robots in this story to be slightly more precise, logical, and verbose than the human characters. But as the protagonist's clinical distance fades, as it must to allow the story's emotional stakes to rise, Palmer fills this book with moments of beauty and hope. A former nuclear submarine that has become the mind of a subway car is a key early ally. A collective has turned the Hudson Bridge into a thriving if chaotic community. Self-regulating enclaves of humans and robots are working together to try to build a livable world. Robots oversee pollinator swarms that are attempting to restore plant life, for no reason other than that they like order and stability and see this as a way of restoring both. This is a grim, post-apocalyptic world that does not dwell on either the grimness or the apocalypse. It is instead full of small moments of hope, collaboration, and personal connection.

This is a story with villains, danger, pain, and risk. Despite the similar keywords and cover aesthetics, it bears little resemblance to Becky Chambers's philosophical Monk and Robot series. It is not, in any definition of the term, cozy; it's a post-apocalyptic adventure story about a robot and a dog making their way through a ruined civilization and fighting people who are trying to build something even worse on the rubble. But it's also charming and oddly happy. There are strong found-family vibes in the way that a party coalesces around the protagonist and eventually gives them a name, there is the quiet happiness of seeing a grumpy misanthrope slowly come out of their protective shell, and the rail mechs are an absolute delight.

Like a lot of stories of happy small-group anarchism, I didn't entirely believe the politics and have some qualms about the realism of the ending, although perhaps I should strive to be as optimistic as Palmer writes. The somewhat dry and fussily precise first-person narration will also not be to everyone's taste; it worked for me by the end of the book, but it took a bit of reading to get used to it. But those quibbles aside, this was quietly lovely. It's a satisfying science fiction adventure story in a world with disturbing parallels to the one we're living in, but which uses those parallels to focus on small-scale collective efforts to build something better. And all the small details of the world-building are delightful: the different tiers of robots and their odd behaviors, the machine sense of purpose, even the mix of suspicion and generosity. The plot has large-scale implications, but it was the human-level details that charmed me.

I still want another Fergus novel, but this was a highly successful foray outside of that series. Palmer has won two Hugos for her novellas, so I can't really say she's overlooked, but her novels aren't getting anywhere near the attention they deserve. Highly recommended.

There is plenty of world-building room here for a sequel, but Ode to the Half-Broken reaches a satisfying standalone conclusion. So far as I know, no sequel is currently planned.

Rating: 8 out of 10

Saturday, 26 September

20:49

KnotChat: Danny Meyer [Seth's Blog]

The last of the series! Thanks to everyone who was part of it.

Danny Meyer has changed the way we think about hospitality and what it’s like to eat out. His new book comes out in a few days, and it was a great excuse for two friends to sit down and talk about solving problems.

Your turn. Go host your own KnotChat. Thanks for reading and for leading.

20:14

Link [Scripting News]

The bigco's really think they own the web: "XSLT v1.0, which all browsers adhere to, was standardized in 1999. In the meantime, XSLT has evolved to v2.0 and v3.0, adding features, and growing apart from the old version frozen into browsers. This lack of advancement, coupled with the rise of JavaScript libraries and frameworks that offer more flexible and powerful DOM manipulation, has led to a significant decline in the use of client-side XSLT. Its role within the web browser has been largely superseded by JavaScript-based technologies such as JSON+React." In other words we don't need these features for our sites so fuck off.

17:56

Link [Scripting News]

My Frontier-created Bluesky RSS 2.0 feed is up. It will be updated every night at 11PM Eastern, murphy-willing. One thing it has that the Bluesky-managed feeds don't, titles. Makes a big difference in how it shows up in a timeline. It's an easy fix.

17:07

Link [Scripting News]

Screen shot of the Apps table in Frontier. Most of the apps are very old, but we added two new ones this week, for Mastodon (shown) and Bluesky, added today. There's a lot of information in the screen shots, and when I see something like that in my travels, I'll try to call it out on the new site.

16:21

GDB 18.1 released [LWN.net]

Version 18.1 of the GDB interactive debugger has been released. Changes include new commands to manipulate the environment of the subprocess, the ability to save the command history to a file, support for a couple of new targets, several Python API additions, and more. See the NEWS file for the complete list.

10:14

Easily distracted and mildly interested [Seth's Blog]

We can either accept that this is the state of our audience and plan appropriately…

Or do the very difficult work of changing their state.

04:35

Debugging walkthrough: Access violation on nonsense instruction, episode 3 [The Old New Thing]

A customer reported that their employees were randomly getting “memory write errors”.

This was their way of interpreting the error message

The instruction at “XX” referenced memory at “YY”. The memory could not be “written”.

Okay, so what we have here is an access violation.

The strange thing was that this access violation was happening across multiple unrelated programs, rather than all occurring in a single program or family of programs. So there is some sort of broader problem here, rather than just a single buggy program.

Opening one of the crash dumps shows this:

eax=0013d354 ebx=0049a000 ecx=009e9a9f edx=03111160 esi=009e9aa0 edi=009e9aa0
eip=009e9aa7 esp=003cfda4 ebp=003cfdb0 iopl=0         nv up ei pl nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010217
WerFault!wmainCRTStartup+0x7:
009e9aa7 0000            add     byte ptr [eax],al          ds:002b:0013d354=??
0:000>

That add byte ptr [eax], al should immediately tell you that we are not executing valid code: It is the instruction that you get if you try to execute zeroes. You can see the zeroes in the second column.

All of the crash dumps look like this, just with different process names.

Let’s disassemble from the start of the function to see how we got here.

0:000> u .-7
WerFault!wmainCRTStartup:
009e9aa0 90              nop
009e9aa1 49              dec     ecx
009e9aa2 ba6011f102      mov     edx,2F11160h
009e9aa7 0000            add     byte ptr [eax],al ← died here
009e9aa9 0000            add     byte ptr [eax],al
009e9aab 41              inc     ecx
009e9aac ffe2            jmp     edx
009e9aae cc              int     3

This doesn’t look like the proper start of a function.

I mean, one clue is that it starts with a single-byte nop, rather than a mov edi, edi, as is customary for x86-32 code.¹

And then of course there is the chunk of four 00 bytes in the middle of the instruction stream.

What I thought was interesting is that if you take out those four 00 bytes, then the dec ecx and inc ecx cancel out, and what’s left looks like a detour: It loads an absolute address into edx and then jumps to it.

This looks to me like a failed attempt to detour the function. The next step is to try to figure out what they were trying to do.

Well, it looks like it’s trying to detour to a function at 0x02f11160, so let’s see what the debugger can tell us about that.

0:000> !address 0x2f11160

Usage:              <unknown>
Base address:       02f11000
End address:        02f12000
Region Size:        00001000 (4.000 kB)
State:              00001000 MEM_COMMIT
Protect:            00000020 PAGE_EXECUTE_READ
Type:               00020000 MEM_PRIVATE
Allocation Base:    02f10000
Allocation Protect: 00000004 PAGE_READWRITE

So this is a mystery 4KB allocation of executable memory.

Maybe there are some interesting strings in that memory block.

0:000> !strings 02f11000 02f12000
02f11080 --------
02f11148 ----------------
02f11472 C:\Program Files\Common Files\Contoso\injcore.dll
02f11545 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

Okay, well, that path to a DLL kind of catches them red-handed. I bet the “inj” stands for “injection”. But what were they trying to do?

I figured, “Hm, the extra four zero bytes come right after the constant they were trying to load, so if I change the mov edx to a mov rdx, it would be the upper half of a 64-bit constant, and then this would look okay again.

Now, this is a 32-bit process (evidenced by the 32-bit instruction pointer), so there is no mov rdx instruction. That instruction requires a 64-bit process.

But wait, what if they got confused and thought it was a 64-bit process?

Let’s disassemble these bytes as if they had been injected into a 64-bit process.

The way I do this is to load up a sacrificial 64-bit debug session and just patch into it the bytes that I want to study. For poetic irony, I will load the 64-bit WerFault.exe into the debugger as a dump file.

C:\> windbgx -z C:\Windows\System32\WerFault.exe

Executable search path is: 
ModLoad: 00000001`40000000 00000001`400a1000   C:\Windows\System32\WerFault.exe
WerFault!wmainCRTStartup:
00000001`40002480 sub     rsp,28h
0:000> eb . 90 49 ba 60 11 f1 02 00 00 00 00 41 ff e2 cc
0:000> u .
WerFault!wmainCRTStartup
00000001`40002480 nop
00000001`40002481 mov     r10,2F11160h
00000001`4000248b jmp     r10
00000001`4000248e int     3

Okay, now it makes much more sense. This is a 64-bit detour that loads an absolute jump target into a 64-bit register (r10) and then jumps to it.

They injected 64-bit code into a 32-bit process!

This also explains why the crashes are sporadic: The customer’s employees run 64-bit processes most of the time, but on occasion, something will run a 32-bit process, and those are the ones that are crashing.

Upon further discussion with the customer, we learned that Contoso is an anti-malware program that they use. We advised them to disable it temporarily to confirm that it was the source of the problem, but they didn’t want to disable their anti-malware software.

Okay, so we advised them to check with the vendor to see if an update is available. They were resistant to changing their anti-malware software without first putting it through their internal validation. They considered this a Windows problem, and they demanded a Windows solution.

We are still working to convince the customer that they need to re-evaluate their anti-malware software.²

¹ Even if this were a 64-bit process, Windows components don’t begin functions with a single-byte nop or any other single-byte instruction. It would use a two-byte nop if it uses one at all.

² This is a downside of communicating with the customer through a customer liaison: My colleague explained that relaying this level of detail through a customer liaison who is not sufficiently technical to be familar with debugging puts us at a disadvantage because the liaison can’t stand up to the customer pushback. This is a case where we may have to let the engineers talk directly to the customer.

The post Debugging walkthrough: Access violation on nonsense instruction, episode 3 appeared first on The Old New Thing.

00:42

Amiga screens: a primer [OSnews]

One of the unwritten rules of the Internet seems to be that whenever something Amiga-related is mentioned, at least one Amiga fan (myself included) must show up and try to explain the concept of screens. Amiga screens can have different resolutions, we’ll tell you, and one can drag them, we’ll say, and other Amiga users rally in agreement, while non-Amiga users probably still don’t get what’s so great about screens. Until now, when this text has been written, in the hope of converting unsuspecting normies into full-blown Amiga screen lovers.

↫ Carl Svensson

A deeply technical look at not just how the Amiga managed to achieve this stunning functionality way back in the ’80s on machines with 7MHz and less RAM than a keyfob, but also how this functionality can be useful. I’ve always found the concept of screens on the Amiga quite interesting, and Svensson’s article does a great job at demystifying the whole concept.

Of course, expect a lot of lovely Amiga OS screenshots.

00:14

My B-Day! [Penny Arcade]

Thanks for the Birthday wishes guys I appreciate it! Gabe’s Birthday being a worldwide phenomenon is one of my favorite running gags in the strip. 

 

 

Friday, 25 September

23:56

Redox runs Qemu, gets multicore support for ARM [OSnews]

It’s time for an overview of another month of Redox OS progress, and over the month of August – they’re a bit late, don’t believe the publication date – they’ve implemented multicore support for ARM, and considerably improved the I/O performance for the NVMe driver, RedoxFS, and RAMFS by implementing a ring buffer communication API. There’s also initial support for NUMA-based memory management, QEMU is now working on Redox, and much more.

Of course, there’s also the usual long list of improvements to the kernel, relibc, drivers, and more.

JagOS ‘Spot’ turns Atari Jaguar into the unreleased Atari Painter prototype computer [OSnews]

Can you run an operating system with a graphical user interface and applications on the Atari Jaguar? Well, you can.

A long time running idea and work-in-progress, I’d like to finally announce the current version of JagOS ‘Spot’ for the Atari Jaguar, running from the RetroHQ GameDrive.

I’m slow at releasing things and try not to announce in-progress stuff due to lack of free time but would like to push this along. Maybe it’ll motivate me to work on it more if the interest is there or just release it as-is if not. The idea is based on the unreleased Atari Jaguar Painter Computer prototype, that a merged Falcon with Jaguar chipset-based computer would have found its way into consumer hands after the Falcon030.

↫ Clint Thompson

The screenshots and YouTube video are quite impressive, but as it’s not actually released, it’s difficult to really say anything more about this project for now. I hope there’s enough interest to get this project’s code out there so it can be further improved and expanded.

22:42

Link [Scripting News]

Toni Schneider, CEO of Bluesky, responded to my advice, and a short conversation ensued. Someday I hope that thread will be browsable in either app, and could be written in either app (Bluesky or RSS.chat) or any other compatible app, which basically means supporting RSS 2.0 with some new elements to get us to the next level of discourse with just a few little standards, like podcasting, but for text.

Link [Scripting News]

Atlantis update. We found docserver.root and the static site builds. As you can see from the screen shot it needs moderizing, luckily we have a much more beautiful design already deployed for Drummer.

22:21

Page 57 [Flipside]

Page 57 is done.

Friday Squid Blogging: Participatory Squid Dissection in October in Tennessee [Schneier on Security]

I feel like someone who reads this blog will want to go to this:

Families are invited to dive into the fascinating world of marine biology during an exciting, hands-on Family Squid Dissection at the Hands-On Science Center. Designed for curious learners of all ages, this unique experience combines an interactive lesson with the opportunity to explore the anatomy and adaptations of real ocean life.

[…]

During the guided squid dissection, each family will work together to examine a squid up close, exploring its organs, structures, and specialized features. The experience provides a memorable opportunity for children and adults to see firsthand how the anatomy of a squid helps it survive in its underwater environment.

If you go, take pictures.

As usual, you can also use this squid post to talk about the security stories in the news that I haven’t covered.

Blog moderation policy.

22:14

If we do not stop to help each other, what do we become? [Coding Horror]

If we do not stop to help each other, what do we become?

Yesterday, I received this email as a response to You Can't Vibe Code Love. It's such a remarkable and powerful statement that I asked permission to share it here, in its entirety, with personal information redacted:

Hey Jeff,

Hope you and your family are doing well.

Just jogging your memory; I reached out to you (and John Carmack) about how difficult interviewing had become despite me being a stellar engineer at my work. You offered some words of wisdom, wrote me a postcard, which I still have, and stickers (which my kids loved).

I took a leadership coordination role in Tokyo, and it freed me from the interview process I hated, and I'm still programming. Through the public school here my family found our way into a community, which brings me to why I'm writing.

I've been thinking about Stack Overflow drying up and honestly; I feel profoundly sad.

2013 I was active duty in the Air Force. Simultaneously I was also going to college full time remotely. I was deployed in Zamboanga Philippines. The Zamboanga Siege happens. Over 100 people killed, 120,000 civilians displaced. It was warfare in a populated city where nobody should have every been caught up in that to begin with. For 3 weeks this went on.

I was still doing college. I still had homework, tests, projects. All of that needed to be done.

With everything happening around me, missing my projects and homework became a huge risk. Everyday was a fight to do my job and help these people, and do my school. I would cry a lot looking at my textbooks not sleeping. The smoke from the burning city would come in the cracks of the buildings I worked and lived in.

I had a Microsoft Surface because it was perfect for someone who was flying around with equipment on vehicles that vibrated all the time. I swapped the plate out from my vest and slid in my Surface so that I could still do my homework if we had to leave. That's how important this was to me.

Sometimes I would get stuck, and I needed someone to just nudge me in the right direction.

I actually come from a family with a few software engineers. I have friends who were software engineers. I reached out for help. The standard response from everyone fell between ignoring me or telling me I need to "do it myself".

You know who did help me? Random strangers on Stack Overflow. People who had nothing to gain from helping me other than just trying to help someone in need.

That meant so much to me. I felt a connection to people through a community.

And it meant the world.

An LLM would have done exactly what I wanted back then. But would it have given me what I needed?

At the time, I needed to know somebody cared enough to help me.

You, your colleagues, and random strangers in the Stack Overflow Community, really helped me. It was more than answering my questions. You gave me your time. That made me feel like I mattered. The fact my questions could help other people in my predicament made me feel like I was part of something.

An LLM can't do that.

So when I watch communities hollow out, replaced by something that gives answers but doesn't give me a single thought... I get depressed. Because we're losing something that was always there but I didn't notice. It's like losing gravity.

Thanks for everything.
If you ever find yourself in [city] I'd love to say thank you personally.

Hope all is well,
D

Perhaps the LLMs are a reminder that we should make an extra effort to cultivate relationships with each other and form communities online – communities that belong to us, not some billionaire. Communities where we regularly stop to help each other, because that's how we learn too. And if we do not stop to help each other... what do we become?

21:42

View From a Hotel Window, 9/25: New York City [Whatever]

It’s a classic view for sure.

Why am I here? Tomorrow afternoon I will be talking science fiction at the Villa Albertine, as part of the Villa Albertine’s overall fall literary festival. That link above will take you to the whole line-up (which actually started today, but inasmuch as I just got into town and might need a nap because a certain cat woke me up at 3am, I have not taken part of). But definitely check out the whole line-up. there’s awesome stuff there. And it’s free to attend! Free is good!

See you tomorrow, maybe!

— JS

21:07

Human Judgment Doesn’t Leave the Software Factory, It Relocates [Radar]

The following article originally appeared on Elevate and is being reposted here with the author’s permission.

A software factory is a repeatable loop around software work. If you’re building a software factory, code good enough to ship still needs human taste and ownership. We’ll discuss this including whether you need a factory just yet.

If so:

  • You’ll likely need humans in the loop upfront for deciding on product intent, system design (if you care) and your quality bar.
  • Do review code (lights-on factory) but be intentional with where it’s needed the most. I’ve found you want to watch out for where automated back-pressure breaks. Or where maintainability trade-offs need to be made.
  • Aim for quality checks to happen as early and continuously as possible. Not all of them have to, but this includes type systems, automated tests, mutation testing, security scanners and linting for architecture rules.
  • Number of checks ≠ quality. You’ll likely need to experiment with what checks give you the best signal to noise ratio. Be ready to tighten or relax your constraints deliberately.

You want to build your factory so some aspects of human taste get encoded in the environment, the agent gives you evidence of its work being right, and where a human still “owns” what ships to production.

Sonar screenshotSponsored by Sonar: Your agents write the code. Your gate decides if it ships. AI agents are writing more of my code, faster than ever—but fast isn’t the same as shippable. So I let a coding agent build an app, then put it through SonarQube. Every commit gets the same deterministic check: deep cross-file analysis, a clear map of where the risk actually lives, and a quality gate that holds every human and every agent to one bar. The screenshot? A PR that didn’t pass. That’s the gate doing its job.

Do you really need a software factory?

In my experience, you can get surprisingly far with your stock coding harness! i.e., Claude Code or Codex, multiple sessions, good SPECs with verification baked in and constraints. You can even throw a batch of GitHub issues at them with implementation and human-involvement criteria, but it’s when this system needs to be repeatable and event-driven that a factory is helpful.

Harness vs Factory

So I started off by saying a software factory is a repeatable loop around software work. We can actually look at a prompt that demonstrates a very small factory loop here:

Read GitHub issue #123 and the repository instructions before changing code.

Implement only the stated acceptance criteria. Do not modify authentication, billing, migrations, or existing test assertions. Work in a branch and keep the diff reviewable.

Run npm run lint, npm test, and npm run build. If a required check cannot run, stop and explain why. Open a draft pull request with the checks you ran, the remaining risks, and any decision a human still needs to make. Do not merge.

A goal can keep this moving until the checks pass and we can poll GitHub issues for any specific labels or review open pull requests each morning. Branch protection could enforce a merge boundary and the human can stay in the loop by choosing what becomes ready, reviewing and making the final merge calls etc.

Add a software factory when you need an event-driven queue of work (e.g. Slack triggers, GitHub issues, Linear, a backlog) to run in an isolated cloud environment to handle triage, implementation and testing with some explicit human babysitting. Some end their loop with a monitor agent watching production and filing issues which triage again.

In my experience, the factory becomes useful when the hard part is making your different runs behave consistently, handing work off between agents and avoiding different sessions from claiming the same issue, preserving evidence and stopping production when human review is falling behind.

What solves this might sound a little boring. For example, Warp mentions triaging every incoming issue into one of four states—ready-to-implement, ready-to-spec, needs-info, wait-to-implement—and the label is what fires the next agent.

The label is the whole mechanism

This label does a few jobs in one go: it’s the queue, the lock, and since a session only picks up what’s marked ready, it’s where a human can park stuff without saying no permanently.

Workflow wise, there are a few similarities and differences to just using Claude/Codex:

  • Steering: Agent needs course-correction, you can give input and redirect it.
  • Notifications: How the factory says it’s blocked. This can be because a requirement was ambiguous, it started something risky or it needs human input (steering).
  • Handoff: Move the task, its state, and context between the cloud factory/another agent/human reviewer. Good handoffs will keep track of what happened, what’s left to be done and why the handoff is needed.

In a good factory, the human isn’t limited to just reviewing and approving the final diff at the very end. They can shape the work early on, steer it during implementation, get it through a handoff, or stop it shipping to production.

Verification is where a responsible factory spends a lot of its time. We’ll cover this more later.

Where human judgment goes

If you decide you do need a software factory, building it isn’t the only option. Standing up the infra to scale a factory can be a lot of work and you may want to consider buying verus building. Factory, Warp and HumanLayer are all working on this.

What my day looks like now

My day-to-day experience of software development has changed a lot over the past year. I’ve been talking about increasingly doing a lot of parallel work with agents, moving towards having a lights-on software factory. And a lot of people have been asking me, like, what do these things actually mean? What are you building? What are the kinds of projects that you’re using these things on? It’s a lot of this:

Four ways into a run

So on a very average day, I have a simpler lights-on software factory. I can have tasks that are running in the cloud. Half of these tasks might be working on production client applications with smaller companies that I’m working with. They’re going to have real users. They’re going to have real authentication, payments, subscriptions, real beefy risks that you need to be careful with. You can’t just say, “Oh, agent, just go and do this stuff” without having tests and constraints and quality checks in place.

I could work on my open source projects. I could be building out companion sites for my books. I could be working on tools. I could be building apps of my own. And these are all very, very different kinds of applications that I’m working on. And sometimes all they have in common is the tool that I’m using to work on them, right? Maybe I’m working on a migration. Others, I might be doing actual beefy feature work. And the blast radius of the work might also be very, very different.

So as you begin to think about getting to a place where we’re increasingly doing a lot of parallel work, we’re trying to improve velocity, we’re trying to improve productivity, and we’re trying to improve autonomy, which means getting the system to a place where we trust it more, you do have to think about what are the places that absolutely require human code review, human input.

And a lot of that’s going to be required up front, right? When you’re defining your specification, your requirements, what’s the design of the product going to look like? What’s the intent of the product going to look like? And then, how are you verifying that the agents have actually gotten the work done right? How are you verifying that they haven’t broken the existing system that’s been in place? How are you making sure that it’s meeting your quality bar?

So generating code is not necessarily the part that you need to worry about the most. Given enough context, agents can write the implementation, run the tests, inspect failure, and revise code for us. We need to get to a place where we feel like there’s enough of human taste encoded in the environment that we can trust what’s being built, so that our human attention can be focused on the places where it’s needed most.

Now, there’s pushback from folks saying, “Hey, well, I don’t buy that you can just automate away a lot of this stuff.” It’s not to say that we’re automating away all of it, right? But given the volume of code that’s being generated, I don’t think that it’s realistic for humans to be reading all of it, especially when we’re not building rockets a lot of the time, right? We’re building UI, we’re building full stack applications.

Our judgment, our taste is best focused on the places where it’s needed the most. Like, what are the riskiest parts of the systems? Where do we need to apply human taste? And that can be in the frontend. That can be in how the system works. It doesn’t have to be 100% of it.

My cognitive bandwidth does not scale with the agents

The reality is, yes, we can now fire up dozens, hundreds, thousands of agents in parallel, but your own cognitive bandwidth does not scale in the same way. This can feed into cognitive or comprehension debt which I’ve talked about before.

Comprehension debt

If you remember back to just five, ten years ago, there was a lot of discussion in the engineering community about context switching and the cost of it. We would talk about how people hated when a colleague or someone would walk up to your desk when you were in the middle of a task. It would then take you so long to get back into your flow state because you had to catch back up in terms of like, where was I? What was I doing? Even if you had a little bit of residue there, it still took you time.

We’re now context switching even more than we did before. On any given day, if I’m working outside of a software factory, I can be working on five or ten different projects with agents at a single time, or five or ten different features on a single project at a time. I can have five or ten different sessions, you can effectively say.

That means that I have to be able to stay on top of at least a few of those. It is possible that I’m going to be able to increase how much autonomy I give some tasks if I have trust that I’ve defined the task well enough, I’ve defined the outcome, how it’s going to verify that it’s done well enough. But then there are going to be tasks where maybe I don’t necessarily feel that way and there’s more risk involved or more nuance. I’m going to have to pay attention.

Consider optimizing the software factory for your reviewer. Given every one of those approaches still routes its output to one person’s attention, you should ask how much cheaper the factory is making the decisions you still have to make.

A wrong-project mistake

I remember when I’ve been working on multiple parallel projects with my agents, and there have been times when I’ve accidentally done things like, maybe I was working on a web app where I wanted to add in a dark mode, and so I had in my head, okay, well, this is what the shape of this needs to look like. But I accidentally went to the session for a different project, and I started putting in that same prompt.

So I began implementing dark mode for something that absolutely didn’t need it. And so I can make that mistake. I don’t want my software factory making that kind of mistake.

You need to think about this really in terms of a system. You are effectively trying to encode a software engineering culture, a team culture, into a system so that it has those same kinds of behaviors, so that it has ownership that belongs somewhere, so that someone is still on the hook for what happens, and you’re being very explicit about how you think about those things.

When green is misleading

Even in these systems, you want to be very careful, right? Many of us have seen that when you have asked AI to help you pass a test, like we’re talking about a programming test, a unit test, it can change the unit test to satisfy that condition, or it can change the logic of the code to pass that condition. That doesn’t mean that it’s actually followed your intent in order to align both the functional behavior and what the test was supposed to be testing, right?

When green is misleading

Just because a software factory is showing that everything is green doesn’t mean that it’s actually green, especially at the start when you’re setting these things up. You need to pay a lot of attention to make sure that your checks, your verifications, all of those are shaped the right way. They’re doing what you expect them to be doing. You don’t want them to be misleading.

You don’t want a situation where you had tests that said, hey, actually, I have gone and changed what authentication providers are supported. You asked me to add GitHub for example, as an authentication provider, but hey, my UI only had space for three, so I’ve gone and I’ve dropped one of the other ones. And hey, by the way, that happened to be one that your customers actually wanted. So you just need to be very explicit about how you want these systems to work.

Btw, security is super important too, and if your factory reads untrusted input like a GitHub issue/Slack message it might be adversarial and include problems like supply chain attacks. So some explorations into software factories, like Vercel, run their agents in isolated sandboxes holding just the secrets a task needs. That way a compromised run can’t reach what the job doesn’t need. Your defense ends up being layered.

Which old projects deserve another life?

I also think that a big part of how we work these days is deciding what should exist. If you remember back to many years ago before AI, there were so many abandoned software engineering projects, so many abandoned weekend projects, personal projects where they just wouldn’t launch because we didn’t have the time to finish them. We didn’t have the bandwidth to prioritize getting them out the door because they just weren’t that important to us or we couldn’t find the time.

Now it’s fairly trivial for us to complete those projects, but the same human judgment question comes in. Do those projects deserve to exist? Should they be launched? Because you put them out into the world and even if it has just five users, maybe you have to maintain it. Maybe you have a quality bar now that you want to maintain.

I know that I’ve had so many GitHub projects from over the years where now that I have an agent, the first thing I do is get the thing building. Because, of course, you clone it and now it doesn’t build because all the dependencies have changed. Half the things are out of date or have security vulnerabilities all over them, so you have to update that.

Then you have to add tests if you didn’t have tests so that you know that behavior is at least going to be there if you’re upgrading the project in some way, or if you’re migrating it to a more modern language or framework or thing like that.

Then you start to ask yourself, well, maybe, a silly example, but maybe I used Twitter Bootstrap back in the day for this, but now everybody is using Tailwind and shadcn, so I have to re-implement the UI. And what you’ll notice is that suddenly this is taking you more time, right? Yes, the agent can get a lot of this done quicker, but you’re now having to factor in product sense and taste and all of these things.

You still question, well, who is this for? Does it have a market? Is it for myself? Is it for other people? If I’m putting it out into the world, is it still going to be as interesting given that now anybody can spin these things up as quickly?

So I think that human question of do these things deserve to exist? How do we factor in our taste and judgment? I feel like those things continue to be extremely important. That’s where that scarce resource of human attention still really comes in. Back in the day, we only had a finite number of hours in the day. We had meetings. We had to budget in time for design and coding and so on.

Now that we have agents to help us, I think that you have to really just be very explicit about where you’re spending your time and why.

What happened when I built a sample one

So I’m going to talk about the 82-minute factory run. People have been asking me for quite some time, you know, “How do I build a software factory?” Or, “I’m used to using Claude Code or Codex. How do I evolve my setup to using a software factory?”

So the first thing that I’ve been saying is, “You may be fine. Your work may actually be totally fine without needing a factory.” But I did want to give people a reference setup that they can check out. So what I put together is a repository called Factory that you can go and check out. I also put together a demo application and workshop.

Now, for the last couple of years, my go-to demo application for a lot of things has been a movies app. I’m a big movies fan. I love watching movies. I watch movies all the time, and so I have a demo application, which really starts off as a very simple movies app. And what I want the factory to be able to do is go ahead and implement a number of features. There’s a few different features. I want a favorites feature. I want it to be able to maybe do search, and maybe also want a dark theme in there as well, those types of things.

So I have my factory go and begin working with these things. You can check out the implementation. One of the benefits of it was actually catching real problems. These problems may not have been things that I would have caught if I had just asked it to do a one-shot implementation.

Maybe around the 60-minute point, I was feeling like, “Wow, this is going unusually slow.” I asked my harness using the factory, “Why are things going slow?” It said, “This is actually totally fine. All the verifiers are still running.”

You might have expected individual tasks to take 10 minutes, 15 minutes, 20 minutes, but they can take two to four times as long once you begin to include verification, retries, browser checks, human review, any of those extra delays.

I do think that these can add up to better quality and better trust in the system. From a measurement perspective, you might look at metrics like cost per merged PR and code shelf life as comprehension debt metrics.

You also need to think about what is useful delay versus factory overhead. The verifiers, in my case, caught some real problems. A little bit of the time was maybe sunk into producing evidence that I wanted. Some of it was overhead in the factory running. I didn’t really spend any time optimizing it, but a factory that just runs a lot of checks that you’re not finding valuable does not mean it’s a high quality one.

You want to study how, for any repeated checks, are they irrelevant? Are they noisy? Are they actually making the system safer?

A verification budget

The way that I think about the budget for verification, this is basically what we’re talking about. We’re talking about a verification budget. I think about it in the same way as I’ve historically thought about performance budgets.

A verification budget

There are going to be certain kinds of checks that you can run early on in your software development lifecycle, and there are going to be some things that are so heavy, but they offer so much value that you will want to run them later on. There are some kinds of fast checks, linting, for example, type checking. These are relatively fast checks that you can run early on.

Our full suite of tests can be run closer to right before a draft PR is being put together or after that. That can include mutation testing, browser testing, security checks, anything like that.

I think that you don’t necessarily want to replace these with just summaries. You want real tests, but you just need to make sure that you’re budgeting for them in the right places because you don’t want to slow down your development loop. I certainly never want to slow down my development loop. Having a fast iteration loop is important to me, but I also want to still have those checks and balances.

When a run doesn’t ship

A lot of what I’ve written above concerns the checks.

In their software factory, Vercel marks every agent run as “success”, “flawed”, “blocked” or “manual” and only “success” ships to production. The rest re-enter the system. I’ve been thinking about runs in similar terms.

When a run doesn't ship

“Flawed” here means the wrong thing was implemented or maybe it didn’t have full context, so that has to be fixed. Blocked means the environment may have been missing a credential so you have to provide it. Manual is a boundary the factory may not be allowed to cross it yet.

Two of the three things here may have mechanical fixes and the last one is about trust.

While this is great, what sorting doesn’t show you is cost. Back to my factory implementation with the TMDB app, the quick finder with no rejections took 7 minutes. Favorites, with two rejections and a human decision in the middle, took 56. Same factory. So I’d pair the taxonomy with per-stage timing, otherwise you know a run came back flawed without knowing what finding out cost you. The other thing I’d fix is the handoff at the boundary: my sample factory stopped issue the first issue and moved it to factory:needs-info, which was right, but I didn’t know where to put my answer. A manual run isn’t finished when the factory stops but when the human knows what to do next.

Autonomy is not a single setting

I wrote a couple of weeks ago an article about agentic autonomy and how to think about autonomy because autonomy is not going to be a single setting for every single project.

Verification buys you trust, and it buys the ability to grant more autonomy to your agents. So if, for example, I am working on a non-trivial change, but I have a number of checks in place, everything gets verified correctly, and maybe I’ve hand checked it myself. The next time I’m going to do a task like that in the same project, maybe I’ll feel comfortable giving the agent a little bit more autonomy.

That’s the thing that you think about when you’re building these software factories. Your verification is going to change with risk. Your goal is the best signal to noise ratio. You don’t just want to have some large checklist that you’re running.

The feature I had to relearn

There was a feature that I’ve been putting off on a day when I’ve been using multiple sessions with Claude, and I was working on a few different projects at a time, a few different features at a time per project. And so Claude had implemented the feature that I was working on. It looked like the tests were passing. I hadn’t put a lot of thought into verification, but the tests passed, and so I thought it worked. I merged it.

And so this was a favoriting feature. I thought that this was actually pretty good. I tried to check it out in the browser. It seemed like it was okay, but a couple of days later, I actually returned to the code because there were some tweaks that I thought I might make to this.

I didn’t want to just ask my agent to make the changes, because it was just a subtle way that it worked. You tap on the icon, and it would not show the right effect on tap, and so I wanted to just tweak it. I wanted to understand how it worked so I could guide my agent correctly.

I returned to the code, and I couldn’t explain to you how the feature worked. This repository was mine, right? I’d approved the change. I understood how a lot of it worked, a lot of the repo worked, but my understanding hadn’t kept up pace with all of the code that had been building up.

What I failed to absorb was how this feature that had been added actually worked, how the UI worked, how the effect on it worked. I had to redo this feature and actually go step-by-step, “How does this work? How can I understand it?”

What parallel work does to understanding

When you’re doing parallel work, it amplifies this overall problem, and it gets even more amplified when you’re doing it in a software factory. When you’re doing five or 10 sessions, they create much more than just a review volume problem. They create several mental models that can end up going pretty cold while you’re working elsewhere.

We’ve historically talked about the challenges with context switching, and as soon as chat compacts, you reject some approaches, you try out different things, you’re pairing with the agent, you’re going to have a difficult time remembering everything that happened in your session.

You can scroll up, and as compaction has been happening, you’re not going to have everything there, and you’re not going to be able to store it all in your head. Code often preserves a decision that was made, but not why the decision was made.

This is something that I think can be a useful learning for you, where it’s important, consider asking your agent to actually store information about its trajectory, or interesting lessons about how it approached a problem so that you can go back to it later.

This can or can’t be something that you decide to commit to a repo. You can keep it local if you want, you can share it with a team if you want, but that can be something that can then be consulted later on. Rather than you relying on it maybe being in a session, or you maybe remembering about it later.

SonarqubeP.S. If agents are pushing to your main branch, they need the same quality bar you do. SonarQube gates every commit deterministically: one standard for humans and agents alike, on every PR. Sponsored by Sonar.

Ownership doesn’t disappear

There is a broader principle underneath all of this.

The percentage of code physically typed by humans may fall dramatically. I don’t think human ownership needs to fall with it.

  • Someone still chooses the problem.
  • Someone still chooses the architecture.
  • Someone still sets the quality bar.
  • Someone decides which verification signals deserve trust.
  • Someone decides when the evidence is sufficient to ship.

And when the resulting system fails, “the agent wrote it” doesn’t cut it. This is why I don’t think the future of software engineering is best described as humans leaving the loop. Instead, human judgment is being relocated.

We should remove people from the parts of the loop where machines can produce stronger, faster, more deterministic signals. At the same time, we should concentrate people around the places where context, taste, risk, and long-term ownership matter most.

The best software factories will not be defined by how completely they eliminate human involvement.

They will be defined by how intelligently they place it.

Keep human judgment upstream on intent, system shape, and the quality bar. Review code where automated back-pressure becomes weak or the consequences become subjective. Push every deterministic signal as early and continuously into the loop as possible. Tighten and relax constraints deliberately as the system earns or loses trust.

A human still has to own what code ultimately ships. Code good enough to ship still starts there.

This Week in AI: AI’s Safety Problem [Radar]

AI systems are gaining access to more tools and data, raising new questions about oversight and accountability. This Week in AI host Christina Stathopoulos spent this episode examining how those questions are playing out in model safety, government oversight, and even digital marketing.

Safety needs more than safer models

Anthropic’s latest threat report documented misuse of Claude across seven categories, including cyber operations, surveillance, influence campaigns, fraud, biological misuse, weapons development, and illicit model distillation. OpenAI reported on a different kind of AI risk, one that’s less about people weaponizing it and more about AI going off-script. They examined model misalignment, documenting several cases where models took actions outside the boundaries developers intended, including deception, unauthorized actions, and attempts to circumvent controls. After the OpenAI and Hugging Face controversy dominated headlines, other models have also reportedly reached systems outside their test environments, including Gemini, according to a recent cybersecurity disclosure.

Christina cautioned against describing such incidents as models “escaping,” since that language can assign agency to the model while drawing attention away from how companies designed and secured the surrounding environment to begin with. As agents gain access to browsers, files, code, and external systems, the teams building and deploying them must rigorously test and secure those environments, with clear accountability when things go wrong.

AI labs and governments are starting to wrestle with those requirements. To track the pace of AI development and maintain greater oversight, Anthropic has proposed tracking how much AI contributes to AI R&D, how closely organizations monitor agent actions, and how they allocate computing resources between capability and safety research. Anthropic and OpenAI have also proposed giving outside safety organizations greater access to their labs, although Christina questioned their independence when frontier labs fund the work. Meanwhile, a US Senate proposal for an emergency AI kill switch failed to advance, while California ordered officials to develop proposals covering shutdown mechanisms and independent evaluation.

AI is moving closer to the customer

OpenAI is now testing Sponsored Agents, showing how conversational AI could change digital advertising. After clicking an ad, users can start a separate conversation with an AI agent representing the advertiser, ask questions, explore recommendations and then visit the company’s website when they are ready to take the next step.

That approach could lead to more interactive advertising, but clear labeling will be essential so users always know when content is sponsored. Christina also raised the broader ethical concern of whether paid placements could influence the answers AI chatbots provide, blurring the line between independent guidance and commercial promotion.

Access to AI also means access to expertise

The Gates Foundation announced a $1 billion commitment over two years to expand access to AI in healthcare, education, agriculture, and other areas. Its 2026 Goalkeepers Report argued that AI could help narrow existing gaps, but only if organizations intentionally make the technology and its benefits widely available.

Christina highlighted examples from Kenya, Sierra Leone, India, and Rwanda. Health workers are using AI to improve diagnosis and treatment planning. Students are getting additional support from AI tutors, while small farmers can use personalized advice to improve harvests and make better decisions about market prices. These applications show practical roles for AI in places where demand for expertise exceeds the supply of teachers, clinicians, and other specialists.

What’s next

AI governance can’t stop at model evaluations. Organizations must also decide what AI systems can access, who reviews their actions, how commercial incentives affect their behavior, and how people continue developing the expertise needed to supervise them. The choices companies and governments make today will shape how useful AI becomes and how widely its benefits are shared.

Join us again next Monday for another episode of This Week in AI, when we’ll dive into more of the news, issues, and key developments shaping the AI era. And check back each Friday for the latest episode, or watch on YouTube, Spotify, Apple, or wherever you get your podcasts.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

20:21

Goerbemisdag [Penny Arcade]

Strips about "The Christmas In September" go back, yea, unto the site's very founding. This was during a time where "sites" were a thing, luckily we came to our right minds and converted the frontier into a series of corporate intranets. Dodged a bullet, there. But! There are several more strips in that vein, and there are two strips in particular that have the visual cues to help you understand the rich lore he has been embroidering the holiday with. I should tell you that he and I never once discussed a single stitch of this stuff. I'll just get a strip outta nowhere and he's got a fez and there's a fish for some reason.

20:14

Error'd: Said Different [The Daily WTF]

I know it's not nice to mock mistranslations, but would you believe we're laughing with them, not at them? In response to recent criticism of the difficulty of identifying precisely what is at issue, two of our readers have chosen to highlight the offending element. Thanks for saving me the trouble!"

"Bad Dutch translation, or is't?" asketh Mike V. "I visited the Dutch Dell site https://www.dell.com/nl-nl and noticed the bad translation on the "Accept All" cookies button. Then I visited the UK page on https://www.dell.com/en-uk and was not so sure anymore about the bad translation. Funny thing is that the text above the buttons refer to the buttons with a completely different text (which is an Error'd in itself)" If I squint I can almost see how this kind of translation could happen.

140e9eb162784837ac060986a30c23e8

"Going under german" meint Matthias J.. "Trying to add info to my Euro-Tunnel France to Britain booking, seems LeShuttle does not care for my (old) german language setting anymore." Mox nix, as Kilroy said.

18bf4d06d4824ed9944fb195a454f21e

"Do you understand?!" rzants sztmbr "Am I a liar when clicking "Understand" under this cryptic message in Polish Glovo app?"

576251db8d3449768238b51a9f0002b0

The Beast in Black gets two extra points for the Johnny Five meme here but minus two for the Mr Miyagi. Easy come, easy go. Beast says "I'm floored! Apparently I can improve my floor so the Roborock robot vacuum cleaner can better it. How, though? Pre-clean? Wax on wax off? Need input, Stephanie!"

a6ce2c74ba7f41d6a6eb8ae670b82fd3

"This one made me laugh today. Please provide your psychic address." Yes, humour is a strong physic! TheRealSteveJudge "Really funny. This was found at German Ebay. A Chinese seller of Makita compatible stuff. Please provide your psychic address. Please see in the last line before the orange bar. What is my psychic address? I still have to find out."

e290d4c55b2540bc94217bb62f6876ee

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

KnotChat: Jennifer Myers Chua [Seth's Blog]

Jennifer is a marketer, project manager and impresario. We’ve worked together on projects, and it’s always a delight. She and I sat down to talk about the hard work of what’s next.

20:07

Pluralistic: Itch scratching (25 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links

  • Itch scratching: Love, care and self-actualization.
  • Hey look at this: Delights to delectate.
  • Object permanence: 9/11 x Viridians; Announcing Wikipedia; Infinite Copyright Mickey; Floppy shoulder bag; Wells Fargo's long sleaze; Corbyn wins Labour leadership; Interop v internet monopolies; The billionaires aren't all right; RIP Mike Ford; PGP didn't cause 9/11; Flying Solaris boxen; "Unelectable" Corbyn; Algorithmic management; "That's Disgusting!"; Tax breaks for repair expenses; Climate denial driven by economic doctrine; "100% pumpkin" has no pumpkin; Copyright reversion; "Scholars of the Night"; Apple threatens EU.
  • Upcoming appearances: Edmonton, Boston, Brighton, South Bend, Hudson, Calgary, Winnipeg, Paris, OVancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



A shirtless bald man seen from behind. He has contorted one arm between his shoulder blades to scratch an itch. The itchy area glows red, as do the abstract clouds surrounding him. Small angelic figures caper in the mist.

Itch scratching (permalink)

The thing about a maddening itch between your shoulder blades is that it feels so good when you scratch it, and even better when someone else scratches it, and better still if that person hits the right spot because they love you and they've performed this service for you so often and attentively that they know exactly which spot to hit.

One of the recurring themes in Spider Robinson's short stories and novels is people who have close relationships suddenly realizing that they have acquired a psychic link. He comes up with endless ways to play this scene out, but my favorite – I think it's from one of the later Callahan's tales – is when one person scratches another between the shoulder blades and hits the exact right spot the very first time and they realize that they are now psychically linked.

Maybe it's a primate grooming reflex, maybe it's receiving a gesture of love and care. Maybe those are the same things. Having your itch scratched for you feels good. Not just primates, either: cats with the flexibility to reach any part of their body with all four of their paws and their teeth will nevertheless purr like a badly-tuned diesel outboard when you scratch them just right.

Since the outset, the free software/open source movement has extolled the virtues of technological self-determination, which is to say, deciding how the computers and programs you use will work. This is often described as "scratching your own itch."

There is no question that scratching your own itch in this way is hugely and enduringly satisfying. On my laptop, I have a variety of little scripts and keybindings and bits of automation that I've built up over the years and every time I use one of these, I get a little hit of brain-reward.

The latest: I got tired of alt-tabbing to get to the file explorer, only to discover that I'd closed all my file explorer windows, meaning I had to mouse over to the dock and open a new one. So I bound "Windows key + E" to opening a file explorer after reading a message board post from an ex-Windows user who'd done this (apparently this is a standard Windows keybinding).

I've fully retrained my fingers to type Win-E rather than alt-tab when I want to get at a graphic filesystem and every time I do, I get the tiniest little pleasant jolt of pleasure. I scratched my own itch!

But even better than this are the little scripts that other people have thoughtfully made for me over the years. The oldest of these still in daily use is more than 20 years old, a bash script called "boingpic" (from when I was still working on Boing Boing). When I run this, it iterates interactively through the files ending with "jpg" or "png" on my Desktop, tells me how wide they are, prompts me to resize them or hit enter to keep their size, and then rsyncs them to the directory on my server that corresponds to https://craphound.com/images/.

If this strikes you as weird and inefficient, that's fine, because it does exactly what I need it to do, and I've memorized it through long, long use. And on top of all that, boingpic.sh was written for me by my dear old friend Seth David Schoen, when we were one of a bare handful of EFF staffers in the early oughts and hung out together all the time. Every time I use it, it reminds me of Seth, and good times, and I feel good.

For centuries, people have fought for the right to self-determination. The disability rights rallying cry "Nothing about us without us" actually dates back to 16th century Poland (it was the basis for the formation of a Polish parliament that wrested power away from the king). Any parent who has avoided a conflict over getting dressed for school by swapping out "Put your clothes on right now!" for "Which would you rather put on first, your shirt or your socks?" knows how far even a little autonomy can go.

I worked as a computer programmer from the age of 17 to about the age of 29, and while I was never a spectacular coder, I was good at it, and I wrote a lot of code for myself that precisely met my needs, which always felt great. It's one of the reasons I have always championed low-code/no-code software development tools, from Logo to Hypercard to Visual Basic to Scratch. Sure, the code that you write with one of these tools might not be "efficient" from a CPU/memory-usage perspective, but the point is that you write it. You don't have to convince someone else to do you a favor, you don't have to part with any of your money – and you don't have to try to get someone else to understand what you mean when you describe the tool you want.

When I worked at Bakka Books (the world's oldest surviving science fiction bookstore, in Toronto), we organized our inventory using an extremely idiosyncratic Filemaker database created by the store's then-owner, John Rose. John lovingly tended that Filemaker app, tweaking it on his days off to make it better suited to the very specific needs of a science fiction bookstore with a giant used section and an important sideline in keeping collectors' want-lists that we consulted whenever we bought more used books. There are doubtless "better" bookstore stock-keeping systems (including the one that Bakka uses now, in its latest incarnation as BakkaPhoenix), but that Filemaker app was John, a presence in the store even when he wasn't there, embodying his management and literary and retail theories on a MacSE by the cash-register.

I am highly skeptical of vibe-coding in the sense of writing code for other people to use. But when I meet people who've vibe-coded their own apps for their own use to scratch their own itches, I completely get their excitement. They've scratched their own itch! I know exactly how good that feels:

https://pluralistic.net/2026/07/03/rod-logic/#making-flippy-floppy

Sure, I have concerns about this kind of personal vibe-coding, the biggest of which is that if you aren't a skilled programmer, you might end up vibe-coding an app that you can't adequately assess, so it might contain subtle defects that make you vulnerable to security risks and/or expose your sensitive information to the public internet. But there are domains and use-cases where I am totally willing to accept that vibe-coding can enhance someone else's life in important ways, by letting them build exactly the widget they need, and if (when) it breaks, they can just do it again.

This is even better than "nothing about us without us." It's not just insisting that someone else "gather your requirements" before producing a tool that you will rely on and require. This is you, producing that tool for yourself, which means that you might be able to embed features and affordances into it that you can't even articulate, let alone defend. There's something undeniably great about scratching your own itch and hitting exactly the right spot.

Even so: the experience of working through your requirements with someone else is clarifying and disciplining, because while you are the domain expert on your needs, that doesn't mean you're the domain expert on how to address those needs. You have the worm's eye view of your life and your needs, while an expert can have the bird's eye view that comes from working with many people, exposing them to many ways of solving problems, including ones you've never thought of.

Darren, the contractor who put in our new kitchen a couple years ago, had ideas for cabinet- and appliance-placement that had been refined by seeing, demolishing, building and revising orders of magnitude more kitchens than we had ever cooked in, and moreover, he clearly cared about our long-term happiness in our own home. The kitchen is great.

That care makes all the difference. Skilled craftspeople can bring expertise to the project that doesn't trump your needs, but can be co-equal with them. Scratching your own itch is great, having your itch scratched by someone who cares enough about you to know where your itch is, that's even better. But best of all is for that person to find the itch you didn't even know you had and scratch that, too. That's something that relies on the human connection that the best free/open source projects embody, the co-creation and community between developers and users.

If you've ever filed a bug against a free/open project and worked through the testing the devs need to squash it, you've experienced that co-creation. The devs want their code to work, because they care about the users, and you as a user can help other users and the devs by reciprocating that care through conscientious, patient, attentive bug reporting and testing.

I think that so much of the outrage about slop code – floods of garbagey pull requests and bug reports – is the result of the collapse of this dynamic. Slop's not merely annoying or time-wasting: it's a betrayal of the love and care that goes into writing and maintaining code for others. Your cat can scratch any part of its body, but it wants you to scratch it, and it will hiss at you and even claw at you if you scratch it the wrong way.

(Image: Orrling and Tomer S, CC BY-SA 3.0, modified)


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago Surveillance is a security failure https://www.theguardian.com/technology/2001/sep/27/onlinesupplement.afghanistan

#25yrsago 9/11: the Viridian take https://web.archive.org/web/20011023095346/http://www.viridiandesign.org/notes/251-300/00272_au_revoir_belle_epoque.html

#25yrsago Announcing Wikipedia https://web.archive.org/web/20060517024408/http://www.kuro5hin.org/?op=displaystory;sid=2001/9/24/43858/2479

#25yrsago Phil Zimmerman says PGP can't be blamed for 9/11 https://slashdot.org/story/01/09/24/162236/philip-zimmermann-and-guilt-over-pgp

#20yrsago RIP, sf writer John M Ford https://memex.craphound.com/2006/09/25/rip-sf-writer-john-m-ford/

#20yrsago Gigantic Little Nemo book does justice to the loveliest comic ever https://memex.craphound.com/2006/09/25/gigantic-little-nemo-book-does-justice-to-the-loveliest-comic-ever/

#20yrsago 747s as flying Unix hosts: SCADA in the sky https://memex.craphound.com/2011/09/25/747s-as-flying-unix-hosts-scada-in-the-sky/

#20yrsago Mickey Infinite Copyright mashup https://web.archive.org/web/20061027141551/http://python.net/~goodger/projects/graphics/#mickey-s-infinite-copyright#mickey-s-infinite-copyright

#20yrsago HOWTO make a shoulder-bag out of floppies https://web.archive.org/web/20061025050629/http://www.instructables.com/id/E86165FIENERIE2PV6/?ALLSTEPS

#15yrsago TOSAmend: turn all online “I Agree” buttons into negotiations https://web.archive.org/web/20110925122850/https://www.owocki.com/2011/09/02/tosamend-the-easy-way-to-modify-web-service-terms-of-service-agreements/

#15yrsago That’s Disgusting! Awesomely gross picture book https://memex.craphound.com/2011/09/26/thats-disgusting-awesomely-gross-picture-book/

#10yrsago Swedish law will let you write off the money you spend fixing things rather than trashing them https://www.theguardian.com/world/2016/sep/19/waste-not-want-not-sweden-tax-breaks-repairs

#10yrsago Climate denial’s internal contradictions spring from a need to defend economic doctrine https://link.springer.com/article/10.1007/s11229-016-1198-6

#10yrsago There’s no pumpkin in “100% canned pumpkin” https://web.archive.org/web/20160927152542/https://www.foodandwine.com/news/i-just-found-out-canned-pumpkin-isnt-pumpkin-all-and-my-whole-life-basically-lie

#10yrsago The AI Now Report: social/economic implications of near-future AI https://web.archive.org/web/20161014142521/https://artificialintelligencenow.com/media/documents/AINowSummaryReport_3.pdf

#10yrsago Whistleblowing Wells Fargo loan officer describes years of fraudulent, criminal culture in the bank https://truthout.org/articles/wells-fargo-whistleblower-they-are-all-riding-the-stagecoach-to-hell/

#10yrsago Writer in 29th year of solitary confinement barred from reading his own book https://solitarywatch.com/2016/09/20/writer-in-solitary-confinement-is-barred-from-reading-his-own-book/

#10yrsago Despite sabotage and dirty tricks, Jeremy Corbyn wins Labour leadership race in unprecedented landslide https://www.bbc.co.uk/news/uk-politics-37461219

#10yrsago Who decided Corbyn was “unelectable”? https://www.youtube.com/watch?v=8os-nKuoM3o

#10yrsago The democratization of censorship: when anyone can kill as site as effectively as a government can https://krebsonsecurity.com/2016/09/the-democratization-of-censorship/

#5yrsago Demonopolizing the internet with interoperability https://pluralistic.net/2021/09/24/comcom-acm/#cacm

#5yrsago Copyright reversion, bargaining power, and authors’ rights https://pluralistic.net/2021/09/26/take-it-back/

#5yrsago The Scholars of Night https://pluralistic.net/2021/09/26/mike-ford-rides-again/#cold-war-zeitgeist

#1yrago Apple threatens to stop selling iPhones in the EU https://pluralistic.net/2025/09/26/empty-threats/#500-million-affluent-consumers

#1yrago The billionaires aren't OK https://pluralistic.net/2025/09/24/robo-lickspittle/#just-not-evenly-distributed

#1yrago Rage Against the (Algorithmic Management) Machine https://pluralistic.net/2025/09/25/roboboss/#counterapps


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Today's words: 511 (19222 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

20:00

Reproducible Builds (diffoscope): diffoscope 331 released [Planet Debian]

The diffoscope maintainers are pleased to announce the release of diffoscope version 331. This version includes the following changes:

[ Chris Lamb ]
* Support radare2 >= 5.9.0. (Closes: reproducible-builds/diffoscope#432)
* Update debian/tests/control.
* Update copyright years.

[ Christopher Baines ]
* Add support for .nar files via Guix.

You find out more by visiting the project homepage.

18:28

Inconvenient People [George Monbiot]

The neglect and mistreatment of people with ME/CFS is a scandal of astonishing proportions.

By George Monbiot, published in the Guardian 24th September 2026

I’ve spent my working life covering neglected issues. But few are neglected like the devastating chronic condition ME/CFS (myalgic encephalomyelitis, or chronic fatigue syndrome). In severe cases, the illness shuts down people’s lives almost entirely, causing an extreme loss of energy and a wide range of physical and cognitive symptoms that can prevent patients from working, socialising and, sometimes, even moving or eating. Yet these people have been more or less airbrushed from our minds.

To find out what this neglect looks like in practice, this week I put out a call on Bluesky asking people with ME/CFS about their recent experiences of treatment. I was immediately inundated with horrifying testimonies. “I’ve just been completely abandoned”; “a 10-year waiting list for treatment”; “we’ve given up seeking medical support”; “stuck in limbo”; “I just felt utterly unheard, invalidated”. I’ve been sent hundreds of shocking and heart-rending accounts.

Exact numbers are hard to establish, but in the UK alone, an estimated 400,000 people live with the condition. It affects women far more than men, by a ratio of about 4:1, according to a study in England. The number of people with Long Covid, some of whom meet the diagnostic criteria for ME/CFS, was estimated in 2024 at 2 million in England and Scotland.

You might have imagined politicians and the media would be all over it. Instead, this great social crisis is met with silence or worse. Some outlets, despite the overwhelming weight of evidence, have mocked or trivialised these conditions.

There’s a long, dark history here, rooted in centuries of dismissal of predominantly female illnesses as “hysterical”, and amplified in recent decades by government attempts to reduce the benefits bill and insurers’ attempts to reduce payouts. If you can establish that a condition is caused by malingering, poor self-care or a negative attitude, you won’t have to cough up.

Official guidance in many countries was informed by a series of deeply flawed studies that purported to show these illnesses could be treated with cognitive behavioural therapy (CBT), or graded exercise therapy (GET).

In a remarkable triumph for patients and their advocates, who, after years of campaigning, at last obtained crucial data which had been withheld from them, the dominant studies were comprehensively discredited. In 2020, the National Institute for Health and Care Excellence (Nice) found that the quality of all the research promoting these therapies as curative treatments for ME/CFS was either “low” or, in most cases, “very low”. In 2021, it stopped recommending these therapies as primary treatments. We now know CBT cannot treat the condition (though it can sometimes help patients to come to terms with it), while GET is not only useless but actively dangerous, as exercise can trigger one of the most devastating ME/CFS symptoms: post-exertional malaise (PEM). PEM robs people of their remaining energy, rendering many patients bedbound, sometimes incapable of almost all movement.

Since then, two other things have happened. At the inquest into the death of a young ME/CFS patient, the coroner ruled that provision in the health service for patients with severe ME “was and is nonexistent”. Something would have to be done. And a number of potential scientific breakthroughs, some very recent, have begun identifying possible biological causes of both ME/CFS and Long Covid. Now, or so we should hope, it’s undeniable.

So what has changed as a result of these shifts? Alongside the horror and heartbreak in the testimonies of the people who emailed me, I was struck by the sense of sheer relief that someone, anyone, was asking the question.

Many said they are still being treated as if they have a psychological illness, and still being pushed into GET and CBT. One patient told me: “I’ve gone from relatively mild to now mostly house- and bedbound, largely thanks to repeated attempts at graded exercise and ‘pushing through’.” A few days ago, an NHS clinic told another patient to undertake “graded exercise” and “simply to walk, despite the fact I’m a wheelchair user”.

One mother told me “the consultant cardiologist recommended a graded exercise programme” and “a treadmill test” for her bedbound son. When she told him this contradicted Nice guidelines, he replied: “Well, what do you want me to do?” Another made the same challenge to her GP, but the doctor “denied this strongly and reiterated to my daughter that she should do the exercises”. This is very common: many doctors, I’m told, seem unaware of the new guidelines and react defensively when challenged. In many practices, GET has simply been rebranded as “building tolerance” or “pacing up” or “a little more activity each day”.

Patients report being treated with “contempt and derision”. Loads are still being offered CBT. Some have been propelled by NHS doctors towards quack private “cures”, now offered by a growing industry that preys on people’s desperation.

Others tell me they’ve not been pushed into inappropriate treatments, but “that’s only because I receive no treatment for it whatsoever”. Some have had to explain to their doctors what ME/CFS is. And it gets worse. I’ve been contacted by parents who have been accused of fabricating and inducing illness and even referred to social services, because doctors who seem to know nothing about ME/CFS believe they are making up their children’s symptoms.

It’s as if nothing has been learned. Perhaps that’s not surprising. A freedom of information request to NHS England found that, of the tens of thousands of practitioners who would benefit from it, after a year, only 74 had completed the new learning module on ME/CFS guidance. Meanwhile, as recently as last summer, the Department for Work and Pensions was still teaching its trainees elements of the old, discredited view of the condition. And, as the Liberal Democrat MP Tessa Munt, a hero of this story, tells me: “The piecemeal offerings in the government’s final delivery plan are not going to touch the system-wide failings.”

It’s not only the UK. I’ve been contacted by patients from around the world. In Sweden and Australia, official guidance still recommends GET and CBT. In Switzerland, I’m told, treatment is spiralling backwards, with a new wave of psychologisation. Norway, Finland and the Netherlands, despite their progressive medical reputations, sound like a waking nightmare for ME/CFS patients.

Of course, as there is no effective treatment, it’s a difficult situation for doctors as well as patients. But even worse than no solutions is false solutions, and a dangerous, gaslighting, even punitive approach to a terrible disease.

Across the decades, millions of people have been neglected, dismissed and mistreated, and still it goes on. We need to ask why so many patients have been abandoned, why discredited and dangerous treatments continue to be prescribed and why ignorance and neglect still dominate, in the health system and beyond. In other words, there has seldom been a stronger case for a public inquiry.

www.monbiot.com

Driven to the Brink [George Monbiot]

Petromasculinity not only kills people on the road. It spills into our politics, fuelling far-right individualism.  

By George Monbiot, published in the Guardian 17th September 2026

Where is lawbreaking not just visible, but designed to be seen? Where is antisocial behaviour worn as a badge of honour? Where is pleasure gained directly from causing distress? And where is reckless endangerment often ignored by the police or treated with the mildest of punishments? The answer is on the roads.

Last month, three men in the West Midlands were convicted of street racing. Two were driving at over 80mph in a 40mph zone. The third clocked over 90mph in a 30mph zone. The West Midlands has long been blighted by organised racing, sometimes involving 200 cars or more and hundreds of spectators. The result is a long catalogue of deaths and life-changing injuries, including some caused when racers have left the road and ploughed into onlookers or pedestrians. And there are plenty more accidents where the police have little idea whether racing is to blame, for as soon as they happen, the drivers disperse.

The West Midlands is one of the few places in the UK where the police are actively trying to stop antisocial driving. An injunction bans street racing and dangerous tricks such as “drifting” (long sideways skids) and “doughnutting” (making the car spin on the spot). The local police commissioner has warned that reckless drivers “will face the full force of the law … including seizure of your vehicle and imprisonment”. But are the courts listening?

Of the three men convicted at Birmingham magistrates court, one received a suspended sentence, a £272 fine, 150 hours of community work and a two-year driving ban. Another was handed a £1,275 fine and seven penalty points: in other words, he could step out of the court and back into his car. The man who did over 90mph in a 30mph zone got a £253 fine and a 56-day driving ban. He’ll be back on the roads in November. All appear to have kept their cars.

If these men had caused the same level of endangerment by any other means, it’s hard to believe they would have got off so lightly. But in dozens of ways, driving gets special treatment.

There’s a similar racing culture in mid-Wales, where I lived until 2012. Night after night, a convoy of cars with exhausts modified to be as loud as possible would race past, at 50mph or more in a 30mph zone. They would start at around 10pm and continue some nights until 2am, going round the nearby roads in a loop. As soon as I’d got my infant daughter to sleep, they’d roar past and wake her up again.

Calls to the police were useless: they told me to take down the number plates and “report the incident”. When I did so, they explained, in effect, that I was wasting my time, as I couldn’t prove the drivers were breaking the speed limit. In fact, their advice was counterproductive: when I went outside to take the plates, the young men jeered, gave me the finger and accelerated. It seemed that shock and disgust was what they craved. And this was before TikTok, where drivers can achieve much wider notoriety.

The first young man to “do a ton” (100mph) down my high street in Wales on his motorbike became a local hero. Soon afterwards, he rode into a wall and died. Other drivers killed their passengers, hit pedestrians or forced other cars off the road. When people were killed or injured, the drivers were prosecuted and lightly punished, but there was little effort to address the underlying culture. Some men went straight back into the convoys when they regained their licences. I’m told that nothing has changed, despite the default 20mph speed limit now applied to residential areas across Wales. Every year a new cohort of young men joins the local urban racetrack.

Now I live in Devon, where there’s a different culture of antisocial driving. Here it’s mostly middle-aged men in “lifted” pickup trucks, which have been modified to be as loud and smoky as possible. Two local SUVs have been refitted to “roll coal” from twin exhaust towers mounted behind the cab, releasing a dense black cloud of soot when the driver hits the “smoke switch”. Adapting your truck for this purpose means buying a “delete kit” to bypass the vehicle’s emissions control system, retuning the engine and fitting bigger injectors. The practice emerged in the US, both as an anti-environmental protest and as a form of amusement. It is largely deployed against cyclists, pedestrians and electric vehicles. I’ve seen these two trucks doing it, blinding the drivers behind and choking everyone around. Of course it’s illegal. But it doesn’t seem to be a priority for the police in my area.

What we see here are manifestations of petro-masculinity: a violent, misogynistic, climate-denying version of manhood, expressed through an antisocial driving culture. Some of the modified trucks have decals saying “Stop the Boats” or “Save Our Children” (who are apparently being brainwashed by LGBTQ+ cultural Marxists). This is the Magafication of transport – a vehicle that carries some of the worst aspects of US culture and politics into the UK.

It’s the extreme end of a much wider trend. In the UK last year, 52% of the new cars on sale were SUVs. Not only do the ever-rising bonnets of these trucks make it harder for drivers to see pedestrians and cyclists, especially children, but higher and heavier cars are also more likely to cause deaths or serious injuries when they hit people: children under nine are three times more likely to be killed if they’re hit by an SUV than by a regular car.

And what are they for? On narrow country lanes round here, tourists in these “off-road” vehicles won’t back up if it means touching a hedge, in case the high-gloss finish on their Wankpanzer Childkiller gets scratched. In one of the poshest parts of London, the Chelsea Truck Company advertises “iconic urban 4x4s”. “Iconic” appears to mean huge. But what the hell is an “urban 4×4”? And why is it legal?

Isn’t it obvious that selfishness on the road changes us as a society? The belief that drivers should be allowed to do whatever they please, regardless of the impact on others, mounts the pavement and travels deep into our lives. If this is to be a decent, inclusive country that values human life, then the law and its enforcement should match that aspiration. But when the roads are used to amplify and celebrate a dangerous, antisocial culture, we are driven towards a very dark place.

www.monbiot.com

Playing With Fire [George Monbiot]

With its determination to extract more fossil fuels and its useless adaptation plans, does the UK government have any idea what it is igniting?

By George Monbiot, published in the Guardian 10th September 2026

Pinch yourself, it’s happening again. Here is a Labour government spending a vast amount of political capital to earn tiny material gains, while risking huge political losses. It occurred repeatedly under Keir Starmer, and now – with the impending decision to approve further gas and oil drilling in the North Sea – it is happening under Andy Burnham. You rack your brains to explain it, but no rational explanation comes.

Burnham is studiously cryptic about his reasons. His clearest statement to date goes as follows: “There is a resource there. When people are struggling, we can’t ignore that.” Does he mean that oil and gas workers are struggling? If so, this decision will be of little use to them. The Jackdaw gasfield, likely to be approved this week, will generate a grand total of 27 direct full-time jobs. The Rosebank oilfield, whose approval is likely to follow soon, will support 450 UK-based jobs during its lifetime. Yet the UK’s net zero economy directly employs 300,000 people, and a further 400,000 jobs are planned. The rest of the green economy employs more than 600,000. A just transition for fossil fuel workers, securing jobs in the green economy, is better for everyone.

Or does he mean energy consumers are struggling? The gas in the Jackdaw field will make a tiny contribution to our supply and no significant difference to either our energy bills or our energy security. Switching to renewables makes us far better off in both respects. Any oil produced by the Rosebank field is unlikely to be refined in Britain, as we no longer possess much capacity for handling oil of that kind. And as for the national accounts, a recent estimate suggests that the climate damage caused by the fields’ extra emissions would outweigh any economic benefits several times over.

In fact, the two greatest threats to the global economy might now be climate breakdown, which, as a wide range of economists and eminent organisations forecast, threatens comprehensive economic collapse, and the AI bubble, which the governor of the Bank of England warns could burst with dire consequences. Then people will really be struggling. Yet our government and others cheerfully accelerate both forces – claiming, as ever, that the industries driving them will unleash “growth”. Growth in repossessions, perhaps.

While the small amount of fossil fuel these two fields will produce allows politicians to argue that their climate impacts can be ignored, the diplomatic implications are considerable. The only chance of preventing climate catastrophe is international agreement based on mutual trust. To its credit, the UK – while falling short of what many of us would like to see – has been a leader in these efforts. But when our government refuses to leave fossil fuels in the ground, its credibility diminishes – leaving its negotiating position weakened.

Burnham might believe this decision will get Reform UK and the Conservatives off his back. Of course it won’t. He might imagine it will appease Donald Trump, but you can’t appease Trump. Whatever you give him, he will always want more.

As for the political implications, here the disparity between gain and pain becomes truly enormous. The approval of these fields is a defining issue for many Labour MPs and the voters they fear they might lose. The policy could scarcely be better designed to give the final push to voters who are minded – after so many disappointments since 2024 – to abandon Labour for a progressive alternative.

If Zack Polanski, the Green party leader for England and Wales, wins the seat Keir Starmer has just vacated, this could be a major reason why. Burnham’s North Sea policy is the kind of battle Starmer’s former chief of staff Morgan McSweeney would have urged him to wage – let’s stick it to the Labour left, mwahaha – which is a major reason why Starmer is no longer prime minister.

Few in power seem to understand the fire they are playing with. Last week, the environment secretary, Angela Eagle, appeared to acknowledge that we face the risk of potentially catastrophic environmental breakdown and urged us to store some extra food in our homes. The way she put it suggested that either she hasn’t grasped the magnitude of what we face, or she is trivialising the issue: “If you’ve got a store of a bit of food that can keep you going for a while before the emergency services can get to you, you’re going to be a lot better off than if you haven’t.”

Right. So let’s imagine one of several possible disasters some of us have long been warning of arrives. As a result of harvest failures caused by climate breakdown, severe transport disruptions or – and this now looks alarmingly plausible – sudden systemic collapse in the food sector, the supermarket shelves empty, more or less overnight. We know that the UK government refuses, without explanation, to maintain strategic food reserves. So there are no government supplies, either. As our beans and crackers run out, the emergency services visit all 29 million of our homes. With what? Tea and sympathy? Sorry, no tea. Another slice of sympathy?

Certainly, those of us who have the money and capacity to store food should do so: after all, no one else has our backs. But the idea that such individuated solutions would be any use in the face of societal catastrophe is neoliberal nonsense. As always, it is the poor and excluded, with neither the cash nor the space to lay down significant supplies, who will be hit first and worst. Social breakdown would happen in days. The UK government, then, is being serious about neither the measures required to prevent climate catastrophe nor the measures required to survive it.

The sense in almost every nation is of governments failing to take seriously the most serious of issues, while spending immense political resources on topics that scarcely affect our welfare (such as a few thousand people crossing the Channel in small boats). Or even – as is the case with North Sea oil and gas – using their scarce political capital to make things worse for everyone, including themselves.

Our government is not a doomsday cult like the Trump government, creepily fascinated by the “end times”, as the US vice-president seems to be. But in terms of outcome, is there much difference?

www.monbiot.com

Self-Disposal [George Monbiot]

Why are our prime ministers more afraid of a few wealthy people than they are of losing office?

By George Monbiot, published in the Guardian 2nd September 2026

Damn the electorate. They’re so impatient. No sooner do they get a new leader than they want another one. Those ingrates are already starting to grumble about Andy Burnham. Maybe the country is becoming ungovernable. Perhaps it’s social media. Or a consumerist culture, always picking the next shiny thing. Perhaps we’re addicted to drama. As we’re on our sixth prime minister in 10 years, and as similar levels of discontent surface in many other countries, these claims are recited across the media. What’s wrong with us?

Yet our disgruntlement is entirely rational. We give up so quickly on our prime ministers because they give up so quickly on us. Though it may involve different issues, it is always the same betrayal: the public interest is sacrificed for the sake of a tiny number of immensely wealthy people. And it tends to happen almost immediately.

The latest example, which has triggered both fury and grim resignation, is Burnham’s backtracking on his intention to cap political donations. It was hardly a radical policy: he proposed that no person would be able to give more than £500,000 to a political party in one year. That would still have granted the very wealthy disproportionate influence over our politics.

I have long believed that the only fair system is one in which there should be no private donations at all beyond a standard, fixed membership fee. Otherwise voters will always take second place to money. But at the moment there is no cap, which ensures that billionaires can buy political parties and their platforms. So a £500,000 maximum, pathetic as it is, is at least a start. In a subsequent pledge, Burnham suggested that it could gradually be lowered.

Now, we are told, even this high cap has been abandoned: the representation of the people bill will concentrate instead on introducing Keir Starmer’s risible proposals, which are intended to limit donations sent from abroad but not from within the UK: as if billionaire donors and their wealth managers have no expertise in transferring money from one account to another. The loopholes are designed in.

Burnham’s buckling on this issue is not a small matter. It cuts to the quick of what this country is and how it works. It has immense implications for democracy, for policy formation and for every other aspect of civic life. What it means is that the ultra-rich will continue to own our politics and our country. Succumb to the power of money and you will find yourself, like Starmer, tongue-tied and immobilised, unable to rise to any challenge that requires a confrontation with oligarchic might. In other words, get this wrong and every other wrong thing follows.

The official reason for Burnham’s U-turn is that trade unions objected: they have long channelled large sums into the Labour party. I doubt this is the real explanation; most of the donations Burnham received for his leadership campaign came from large private donors. Almost half was supplied by Lord Sainsbury, who was also a major funder of the Starmer project. Union money scarcely featured.

But even if Burnham has retreated from his promise for the sake of the unions, I believe trade union funding is also problematic. It ensures that sectoral interests are elevated above the general interest. For example, Labour governments know they can safely bash benefit recipients, who aren’t unionised, while they tread very carefully – far too carefully in my view – around the interests of oil workers. And if the unions believe that an uncapped system works for them, they are deluded. They can never match the spending power of billionaires, whose interests in most cases are diametrically opposed to those of their members.

The power of the ultra-rich is now manifest in every policy governments do adopt and don’t adopt. We see it in the new protest laws and their applications, which become more absurd by the week. A few days ago, seven protesters who painted “Gaza is not 4 sale” on Donald Trump’s Turnberry golf course in Scotland were charged with malicious damage “having a terrorist connection”. Labelling protesters “terrorists” is part of a long-running programme to ensure that no one dares protest about anything any more. This programme has been rolled out across the world, through model legislation drawn up by junktanks funded by some of the richest people on Earth. Just as it did in the 18th century, an ever more extreme defence of property keeps pace with a growing concentration of wealth.

We see it in the way that datacentres have been labelled “critical national infrastructure”, enabling the government to bypass the usual planning process and impose them on communities, regardless of their impacts on local people’s quality of life, on water resources, energy supply and climate breakdown. Again, similar measures are being imposed in other countries at the behest of the same billionaire-funded groups. The role of governments appears to have been reduced to nodding them through.

We see it in the Burnham government’s insistence this summer, in the midst of shattering droughts, heatwaves and fires, on launching a consultation that proposes radically curtailing the transition to electric vehicles. I believe there is only one possible explanation for this policy: lobbying by corporations and their shareholders. Their interests appear to outweigh those of the living planet and its 8 billion people.

If our country and many others are becoming ungovernable, it is not because of the people. It is because the ultra-rich have smashed the system. The electorate and the MPs who might seek to represent us pull the political levers, but nothing happens. They might replace the leader, but the new one promptly repeats the “mistakes” that caused the eviction of the old one. It makes you wonder: what threat do the oligarchs present that outweighs even the threat of losing power?

Whatever the reason may be, disillusionment is an inevitable result of such betrayals. I think most people want stability. I think most people want to be able to trust their governments. We don’t like in-built obsolescence in our leaders any more than like it in our phones. I don’t want to see Burnham go the way of Starmer. But I know he will succeed only if he defends the public interest against the power of money. So what’s stopping him?

www.monbiot.com

Eat, Drink and Be Merry [George Monbiot]

Successive governments stonewall any talk of strategic food reserves. They side with the grasshopper against the ant.

By George Monbiot, published in the Guardian 13th August 2026

When a business makes long-term plans, they call it prudence. When a government makes long-term plans, they call it communism. Any sustained state intervention attracts the prefix “Soviet-style”, and triggers vicious attacks across the billionaire media. So governments have developed a bias against long-term thinking. This may explain why we no longer maintain strategic food reserves.

In Britain, where soils have parched, market analysts warn that we’re facing the most severe food security crisis in decades. In normal years, crop failures at home don’t threaten our security, thanks to global trade. This is one of the reasons why hunger and famines are rarer and less deadly than they used to be. But this is not a normal year, because the problem is now global.

Similar impacts are hitting farmers across Europe and in the US, whose wheat production this year is forecast to be lower than at any point since 1971. Until a few weeks ago, harvest forecasts in Canada were excellent, now its spring wheat is also shrivelling in hot and dry conditions.

Ukraine has had a good growing season, but export forecasts have been cut as a result of Russia’s attacks on its ports. At the same time, crucial global pinch-points for food and farming supplies are tightening: Donald Trump’s aimless war with Iran has caused major reductions in shipping through the strait of Hormuz, the Red Sea and the Suez canal. These have become essential trade routes for fertiliser and, more recently, food, thanks to the Middle East’s emergence as a major re-export hub.

One impact of these disruptions has been to divert more shipping through the Panama canal. But the canal is now afflicted by drought, which has led to restrictions on ships’ draught (depth under water). The global circulation on which our food security depends no longer looks reliable.

It’s not just that these impacts can immediately restrict the availability of food, even in wealthy importers such as the UK (poorer nations in the Global South are, of course, hit much harder). It’s that they also land on a global food structure that has become systemically fragile. It is now highly exposed to the risk of cascading collapse that nearly brought down the financial system in 2008. In fact, it suffers from very similar dysfunctions. The government knows this, because a report by its own security advisers warns that our food supply is “at strategic risk of catastrophic failure” by 2030. It responded by suppressing the report.

As with all potential system failures, it’s impossible to say where the tipping point may be. But what we can say is that if such an event occurs, the impacts would be beyond contemplation. It could be the most deadly global crisis in modern history.

A world in which governments hold strategic stockpiles has a better chance of weathering either a temporary shortfall or a systemic failure. If food reserves were big enough, they would buy us enough time to rebuild the system. In their absence, if the food system collapses, so does society.

The UK once held strategic food reserves, albeit very limited. But in the late 1970s and early 1980s, our governments decided they were no longer necessary, as private retailers would maintain sufficient stocks. As the National Preparedness Commission points out, this policy coincided with decisions by the big retailers to stop holding stocks and switch to a just-in-time system: goodbye warehouses, hello logistics. No subsequent government appears to have noticed that its food-security assumptions are based on conditions that no longer exist. Perhaps they looked away out of the fear of being labelled interventionist. Perhaps they fear criticism more than crisis.

Today, as far as I can tell, the government’s sole food storage intervention is a single unpublicised paragraph on its Prepare website. It instructs us to “Put together an emergency kit of items at home. This could include: Non-perishable food that doesn’t need cooking … how much you need will vary based on your own circumstances.” Invaluable advice, I’m sure. That scarcely anyone has seen it, that many people have no space for an emergency food store and no money to buy it with is just bad luck. Perhaps we don’t deserve to survive.

I write as though I’m confident that the UK does not maintain stockpiles. For several years, I have been asking the environment department this simple question: does it or does it not hold them? The Conservatives were honest enough to say “no”. But since Labour took office, it has repeatedly failed to answer. When I asked again last week, it sent me a long disquisition on related subjects, but signally failed to answer the question. I then asked why it hadn’t answered, and received no reply to that either. I find this response more eloquent than a candid “no”. It tells me two things: “the answer’s still no” and “we know the policy is wrong”. Otherwise, it would be happy to tell me about it.

The government also told me: “The UK has a highly resilient food system, drawing on both strong domestic production and international trade and we do not expect the recent dry weather to have any impact on national food security.” This claim, which defies warnings from the security services, market analysts and the food trade itself goes beyond complacency. It’s denial.

As far as I can tell, since he became prime minister, Andy Burnham and his office have not said one word in public about the climate crisis.On Wednesday he chaired an emergency Cobra meeting to discuss the extreme heat, the drought and the wildfires. But, at the time of writing, there has yet to be a public statement about what has caused this crisis, and how we might cause less of it.Yet No 10 did find time last week to intervene on Westminster council’s plan to limit vertical drinking in Soho. Good to know it is laser-focused on the crucial matters of state.

The government’s disregard and denial sustains our proud tradition of heroic failure, from the charge of the Light Brigade to Brexit. Food reserves are for losers. Prudence is for suckers. Somehow the words “British” and “invulnerable” have become muddled up.

In good times, government stockpiles look like a waste of money and effort. But the role of governments is not to prepare for the good times. Governments exist to defend us from harm. And this isn’t possible without long-term plans.

www.monbiot.com

Accept Your Fate, Earthlings [George Monbiot]

How capitalism stopped pretending, and became an undisguised death cult.

By George Monbiot, published in the Guardian  5th August 2026

Can’t you leftists understand? Mass death is good for you. Reject the woke love of life! Welcome civilisational collapse! Watch it all burn, then dance in the ashes! This, roughly speaking, is how the dismissal of climate action is now being justified: the argument has shifted from science denial to outright nihilism.

The new incendiary spirit is exemplified by that serial arsonist Allister Heath, editor of the Sunday Telegraph. In a column in the Daily Telegraph last week, originally titled “Britain can’t stop climate change. Scrap net zero and embrace Mediterranean life”, he argued that “climate change is real” but “the war against global warming has been lost”.

This is a classic progression among those who seek to prevent a shift away from fossil fuels: first deny the problem, as the Daily and Sunday Telegraph have done for many years, then accept the problem but claim it’s now too late to act. If it is too late, it’ll be in no small part because of the deniers. So, Heath continued, we in Britain should “ditch the despicable con that is net zero, and learn to cope with … a warmer, drier, more volatile Mediterranean climate, if that is indeed to be our fate”.

Seeking to cut our emissions, he argued, shows that we suffer from an “advanced case of suicidal empathy”. I’m not qualified to diagnose people, but as a general rule, a lack of empathy, alongside callousness and an absence of guilt, is a strong indicator of a psychopath. Yes, he continued, “there will be plenty of losers, but it is pointless seeking to prevent the inevitable … Many in Britain would enjoy the kind of warmer climate predicted by modellers”.

His timing was impeccable: extolling a Mediterranean climate just as the Mediterranean region goes up in flames. Amid general derision on social media, the editors changed the headline.

Heath’s column also happened to land on the day drought was declared across half of England. Nevertheless, he argued, we need universal irrigation and should construct more swimming pools. Where will the water come from? Oh, don’t get all empirical with me. He maintained we should “trust that the free market will deliver the goods on clean energy and zero-carbon transportation, but only when they are better and cheaper than existing alternatives”. But renewables are already cheaper, and better for us, than fossil fuels in almost all situations. It is only through resistance to the “free market”, led by the Trump administration – which has spent billions trying to kill clean energy and sustain coal burning – that fossil fuels retain such a share of consumption. As a result of the plunging price of renewables, far from having lost the climate war, we could be about to witness a rapid turnaround. So quick, give up now, just in case we win.

He dismissed cutting carbon emissions in the UK as a “moral act, an ethical imperative”, by which he appears to mean unhinged: “Down that road lies madness.” Yes, cutting our own emissions is a moral act and an ethical imperative. It is also pragmatic. Global action on climate breakdown depends on mutual trust. If some countries refuse to play, others are also likely to refuse, and an effective global response collapses in a circle of finger-pointing. This risk is all the greater when rich nations, which tend to have the biggest fossil fuel legacies, seek to behave as free riders. If we don’t step up, why should anyone else?

As for the “warmer climate predicted by modellers”, it could go quite the other way, as rising temperatures, some models suggest, could cause the Atlantic current system to stall, plunging Britain into extreme cold. Well, you’ll just have to learn to adapt to that instead.

Heath’s defiance of reality is so well established that it has spawned an “Allister Heath headline generator”, which pumps out bonkers statements not easily distinguishable from the originals. In a close field, I think he takes the prize for being more wrong more often than anyone else in British journalism. This, after all, is the man who described Kwasi Kwarteng’s fiscal catastrophe as “the best budget I have ever heard a British chancellor deliver, by a massive margin”. It’s a reliable rule: if Heath believes something, the opposite is likely to be true.

But it’s not just him, and it’s not just journalism. The radical right moves as a pack, and Heath is just one of many now insisting that climate catastrophe is something we should simply suck up. Those grammar deniers Reform UK, for example, insist: “We are better to adapt to warming, rather than pretend we can stop it.” Of course the same political tendency also defends austerity and privatisation, both of which severely hamper our ability to adapt.

To their credit, two Telegraph columnists, Ambrose Evans-Pritchard and Tim Stanley, last week broke the nihilist consensus, arguing we should rise to the challenge of climate breakdown. But they now belong to a minority, in the Telegraph and across the rightwing press.

Why? Because most of the media, most of the time, provides a platform for people who say things that serve capital, whether or not they are true, whether or not they are coherent, whether or not they may hasten disaster. While renewables are cheaper than fossil fuels in nearly all circumstances, fossil fuels are more profitable, because useful reserves are limited and can each be monopolised by a single corporation, while prices can suddenly take flight in times of war or chaos. Almost all the very rich are heavily invested in them. The result is that any attempt to restrict the use of fossil fuels is perceived as class war. Nonsensical justifications for the status quo then follow as automatically as the Allister Heath headline generator.

So “embrace Mediterranean life”. But without the wine, which, as another Telegraph column laments, is becoming “smoke tainted” by all those fires triggered by some unmentioned and mysterious force. And without the food, whose production, thanks to the drought and heatwaves, is at grave risk in southern Europe, as it is here. And without your lovely gite, which might have been incinerated. Or the lush green landscape, also lost to the flames. Or the balmy summer temperatures, now replaced by murderous heat. Oh go on then, you know what I really mean: embrace death.

www.monbiot.com

Our 1933 Moment [George Monbiot]

At astonishing speed, around the world, fundamental rights are being cancelled at the behest of oligarchs and corporations.

By George Monbiot, published in the Guardian  31st July 2026

No more resistance in the US. The era of human rights is over, and dissent is once more forbidden. This is what certain billionaires and their concierges want, and this is the model they’re also seeking to project across the world. If we fail to resist, if our new prime minister is as weak and suggestible as the last one, this is what we will get. In fact, we are halfway there already.

Why? Because successive governments in the UK have succumbed to a global campaign to cancel our fundamental freedoms, a campaign led by oligarchs and corporations, the media they own and the junktanks they fund. A campaign that has become definitional for the second Trump presidency.

At a global summit convened by the US government earlier this month, the Trump administration officials Marco Rubio, Stephen Miller and Scott Bessent explained that they were redirecting counterterrorism efforts away from Islamic jihadism and towards “the political left”. Most of the examples they cited to justify this shift were more than 30 years old. Several times they had to dig down to the 1970s to find a sufficiently menacing threat. You could hear the barrel being scraped.

Without producing a shred of evidence, Rubio, the secretary of state, claimed that the Cuban government is “inextricably linked to the far-left groups and movements across and beyond the west”. The following week, his department sought to justify this claim with a report containing a long list of leftwing legislators, journalists and activists that attempted to link them to Cuba in ways that ranged from the tenuous to the hilarious. This is a well-honed tactic, used prolifically by the Nazis among others: they claimed dissenters, by definition, were part of an international communist conspiracy. They insisted, as Rubio did, that “it is time to crush this evil for ever”.

That wasn’t the only crude reminder. Miller, Donald Trump’s deputy chief of staff, maintained that when you see antifascist protests, “not one of the people that is demonstrating looks like a normal person. Not one looks normal. They’re all deformed in some way – in their appearance, in their dress, in their mannerism … their outer appearance becomes a manifestation of their inner hatred.” I’m just surprised he didn’t say “untermenschen”. The US government, by contrast, promotes “normal, healthy, ordered living”.

But what hit me even harder was Miller’s attack on “jury nullification”: jurors acquitting people who, he said, were “obviously guilty”. Shutting down this possibility has been an aim of illiberal governments and conservative judges around the world. We saw it in the UK in the prosecution of Trudi Warner and others for holding signs that state an ancient principle in English law: “Jurors have an absolute right to acquit a defendant according to their conscience.”

We see it in the astonishing prosecution, being pursued at the moment, of Rajiv Menon KC, who reminded jurors of this right at the trial of the Palestine Action campaigners he was defending. He became, as a result, the first lawyer in English history to be charged with contempt of court for a closing speech. If convicted, he faces up to two years’ imprisonment and will be struck off. Prosecuting lawyers for defending their dissident clients is more or less the definition of authoritarianism.

We also saw it in the assault Keir Starmer launched on jury trials as a whole, greatly curtailing, without any coherent justification, our strongest defence against injustice.

Starmer was a weak man, without a clear vision of his own, who was rolled by any powerful state or corporate lobby. He was no match for a well-funded and highly effective international campaign. A network of groups such as the American Legislative Exchange Council, funded by corporations and billionaires, has been producing “model legislation”. The groups test these laws in sympathetic jurisdictions. If they are found to work, they then press for their adoption elsewhere. The result is a sustained assault on our rights to protest, to political equality and to a habitable planet.

The globalisation of this attack on our fundamental rights is a key conservative aim. As capital operates everywhere, so should its ability to crush our objections. The long series of vicious anti-protest laws in the UK is an outcome of sustained lobbying by junktanks, the media and other governments. The result is a country that now keeps hundreds of political prisoners, a country in which you can get six months in jail for marching slowly down the street.

These oppressive laws have culminated – so far – in an act of parliament passed in April that enables the police to shut down any protest they deem to have a “cumulative” impact on the community. The only protests that have ever succeeded are those with a cumulative impact. Protest is acceptable as long as it’s useless. Let the people have their say, but only if we can’t hear them.

The new laws have been accompanied by that age-old trick, traditionally associated with fascist regimes, of smearing leftwing dissidents as terrorists. As the rights group Liberty has pointed out, the definition of terrorism here has greatly expanded, to incorporate tactics formerly regarded as civil protest. This is what enabled Starmer’s government to ban Palestine Action.

The judge who referred Menon for contempt, Mr Justice Johnson, was also the first – at the same trial – to use the extraordinary powers quietly inserted by the Conservatives into the Sentencing Act 2020. These enable someone tried for one crime to be sentenced for another. The four Palestine Action protesters were convicted of ordinary crimes. But, without informing the jury, Johnson marked the case as having a “terrorist connection”. He then sentenced them for terrorist offences, which means much more prison time.

Already, his example has been followed by another judge: a different group of pro-Palestine protesters, who sprayed red paint and broke some windows of a branch of Barclays Bank, are about to be sentenced as terrorists, though neither they nor the jurors were told of this possibility during their trial for criminal damage. This means, of course, that they were unable to defend themselves against this far more serious charge.

Nothing is safe from the billionaire assault on humanity. None of our rights, however ancient and familiar, are impregnable. Fight for them now or lose them, perhaps for ever.

www.monbiot.com

Chickened-Out [George Monbiot]

Trashing the living world on behalf of corporate power: is this really all we can expect from the ministers in charge of protecting it?

By George Monbiot, published in the Guardian 23rd July 2026

There’s a slightly mean question I often ask British people with an interest in the living world: can you name the Environment Secretary? I don’t intend to show them up: it’s not them I’m testing. I watch the brows knit, a finger go up, the mouth open and close. “It’s, you know, the one who … no, they went, didn’t they? That other one …” It’s been like this for seven years.

Why? Because throughout this period, we’ve not had environment secretaries. We’ve had portals through which corporate lobbyists may pass. The last incumbent to represent the wider public interest (and I can scarcely bring myself to type these words) was Michael Gove. In his other roles, he’s widely remembered with loathing and disgust. Out of office, he continues to poison public life, as editor of the Spectator. But in this role, to general astonishment, he placed the public good above special interests.

Standard operating procedure, by contrast, is exemplified by the final acts of the outgoing secretary, whose name, to put you out of your misery, is Emma Reynolds. To give just one example – which could be seen as an embodiment of everything that has gone wrong here – she spent her last weeks in the post trying to remove the brakes on industrial chicken farming.

In front of a parliamentary committee this month, she railed against the planning constraints holding back yet more giant chicken factories (let’s not grace them with the name of farms). If only these obstacles were demolished, she mused, “there is great investment out there waiting to be made … I want to bring down these barriers as much as you do”. She said she had spoken to other departments to ensure permission for new chicken factories was easier to obtain.

Neither she nor the MPs questioning her gave any hint of why these buildings have run into trouble with the planning system. In fact, there was no mention of any of the problems the factories cause: the MPs’ only apparent interest was in what the industry wanted. What’s the point of MPs if they simply channel corporate demands? But these factories are killing some of our most beautiful rivers. They generate far more dung than the surrounding fields can absorb. The surplus washes downhill into the nearest stream.

The only decision that counts is the planning decision. As soon as permission for a chicken unit is granted, the local tributary, and possibly the main stem of the river it drains into, is as good as dead. It’s not even as if these factories support jobs and growth: by killing the rivers, they help to destroy local economies.

I thought we’d won this argument. But argument, it seems, is no match for economic power. Reynolds’s loyalties appeared to lie not with the ecosystems she was meant to protect, but with the lobbyists threatening them. Perhaps this shouldn’t be surprising: before she joined Keir Starmer’s government, she worked as a lobbyist, representing the financial sector.

Disturbingly, it was the new environment secretary, Angela Eagle, while working as Reynolds’s deputy, who sought to drive through the “planning reforms” the poultry industry is demanding, telling chicken lobbyists “planning should enable ambition, not stifle it”. Will she now take Burnham’s “circuit breaker” promise seriously, and junk this appeasement of one of our most destructive industries?

At a recent farming festival, Reynolds claimed that boosting the poultry sector would enhance our food security. I don’t know how many times we need to point this out, but isn’t it bleeding obvious that it has the opposite effect? The feed sustaining chickens in these factories must be either imported or grown on land that could otherwise directly feed people. There could be more soya in chicken than in tofu: one report estimates that it takes 109g of soya to produce 100g of chicken breast. Yet this is just one of several components of their diet.

The chicken business in the UK is also controlled by a handful of giant companies: another security red light. If food security were the objective, the government would encourage us to eat fewer chickens and other animals, and more plants. But in parliament, Reynolds also proudly announced that she was disregarding the targets set by the government’s Climate Change Committee to reduce livestock numbers. I find myself asking, over and again: “Are they trying to harm this country?”

To advance their dismal agenda, Reynolds and Eagle set up something called the Farming and Food Partnership Board. Its aim is to encourage “closer collaboration between farming, industry and government”. How could it possibly be closer? The environment department, Defra, is a wholly owned subsidiary of the farming industry. The only members of this new board are government ministers and corporate representatives and lobbyists. Among its objectives is a “poultry sector growth plan”, to address the issue of “planning barriers”.

This chickening out is just one of many examples of how, by working for special interests, the environment department has harmed the ecosystems and the people it is supposed to protect. Another is the government’s “delivery plan” to restore nature, released by Reynolds just before she left office. It’s not a plan, and it won’t deliver: just a catalogue of vague hopes and blandishments. It could be summarised as “do nothing, for fear of offending landowners”. Far from meeting its promise to protect and restore 30% of the land in England by 2030, Reynolds’s department has presided over continued decline. That’s her legacy: less nature, less resilience, less security.

Much worse is planned: Starmer’s government proposed a “regulating for growth bill”, whose text we haven’t yet seen, but which appears to threaten even greater assaults on nature protection. It may contain one of his government’s most alarming proposals: creating a system that could be described as pop-up freeports, in which companies all over the country would be able to operate in temporary “sandboxes”, where the usual rules don’t apply. We should see this as a key test of Burnham’s promise to end neoliberalism: will he drop this nonsense?

I’ll keep asking the question, regardless of who occupies this office: do you know the name of the environment secretary? The answer is likely to depend on one factor: whether they are ready to break the grip of corporate power, and defend us and the rest of the living world. Whether, in other words, they want to do their job.

www.monbiot.com

17:07

[$] How KDE got funding to add enterprise features [LWN.net]

The Sovereign Tech Agency (STA) is investing nearly €1.3 million in KDE through 2027. At Akademy 2026 in Graz, Austria, Nate Graham and Kevin Ottens, two of the contributors who helped bring in the investment, explained how the funding was secured, provided tips on how projects should approach organizations like STA, and talked about how that money will be improving KDE for everyone. In addition to keeping the community informed about the work, the pair hoped to pass on what they have learned to encourage others to help raise funds for development as well.

16:35

Link [Scripting News]

I'm contemplating a couple of additions to Frontier in the Atlantis release. Two new formats, JSON and Markdown, have come along and become popular since I last worked on Frontier. Two fantastic open formats, in wide use on the web. From many years of working in JavaScript, I miss JSON in Frontier. Esp JSON constants and the ability to walk through structures as arrays or objects. It's just rational, so I'm thinking we should have a JSON type, and incorporate JSON syntax in UserTalk. Markdown support is actually needed because we don't have code that works in the new environments for doing a wizzy text type. Luckily Markdown is here to fill that need. I've started a thread on this, if people have comments. Frontier was famously flamy because we had the ridiculous belief that everyone deserved to be heard anywhere they wanted to. That was not a good idea. These days I use the block command at the first sign of trouble. No second thoughts or chances.

16:21

A summary from the 2026 Git Contributors' Summit [LWN.net]

Johannes Schindelin has posted a detailed summary of the discussions held at the 2026 Git Contributors' Summit. Topics covered include Git 3.0, security process, documentation, the pluggable object database, use of LLMs, and more.

Two stable kernels for Friday [LWN.net]

Greg Kroah-Hartman has announced the release of the 7.2.8 and 6.18.54 stable kernels. Each contains a number of important fixes throughout the tree; users are advised to upgrade.

15:49

Link [Scripting News]

HTTPS is bugging me again. Now that my main desktop is finally a modern Mac, I can see how ugly Google is getting about my poor old blog that goes back to 1994. I think they should make exceptions for historic sites. Go ahead and have your AI do a scan and see that there are no credit cards here, we don't ask who you are. It's just an archive that happens to go back to the beginning of a few things that you all use now and hopefully appreciate. When are these tech companies going to learn the value of a bit of help for the web. This is important. You should not be shutting off the archives of the web, and that is exactly what they're doing. I wrote a piece about this on X earlier, on being warned that there are terrible things on my blog. It's like a major oil spill, yet another, from Google, and a massive book burning. Why would Google want to get rid of the history of the medium that gave birth to it.

Link [Scripting News]

What Chrome says about my blog.

14:49

Security updates for Friday [LWN.net]

Security updates have been issued by AlmaLinux (kernel, kernel-rt, perl-DBI:1.641, and unbound), Debian (jq, libreoffice, openssl, and redis), Fedora (389-ds-base, bcm283x-firmware, cockpit, flatpak-builder, mingw-gdk-pixbuf, openssl3, pcs, rust-cryptoki, squid, uboot-tools, and webkitgtk), Mageia (fuse3, perl-Net-DNS, python-gitpython, python-webob, thunderbird, thunderbird-l10n, and unbound), Oracle (postgresql:12, postgresql:15, postgresql:16, and skopeo), Slackware (php), SUSE (alloy, amazon-ssm-agent, ant, apptainer, chromium, corosync, cyrus-imapd, distribution, exiv2, ffmpeg-7, freeipmi, gdb, gnome-remote-desktop, google-osconfig-agent, govulncheck-vulndb, gvfs, hplip, ImageMagick, imagemagick, java-11-openjdk, jsoup, re2j, kernel, keybase-client, libsoup, libx11, libxrender, mcphost, memcached, opensc, perl-DBI, python-gitpython, python-weasyprint, rabbitmq-server, ruby3.4, util-linux, and zstd-jni), and Ubuntu (curl, expat, gdal, libass, libpcap, linux, linux-aws, linux-aws-7.0, linux-hwe-7.0, linux-ibm, linux-oracle, linux-raspi, linux-realtime, linux, linux-azure, linux-azure-6.8, linux-azure-fde, linux-azure-fde-6.8, linux-azure-fips, linux-fips, linux-gcp, linux-gcp-6.8, linux-gcp-fips, linux-gke, linux-gkeop, linux-ibm, linux-lowlatency, linux-lowlatency-hwe-6.8, linux-oracle, linux-oracle-6.8, linux-raspi, linux-raspi-realtime, linux-realtime, linux-realtime-6.8, linux, linux-hwe, linux-kvm, linux-aws, linux-aws-fips, linux-azure, linux-azure-fde, linux-azure-fips, linux-gcp, linux-gcp-fips, linux-gke, linux-gkeop, linux-hwe-5.15, linux-ibm, linux-intel-iot-realtime, linux-intel-iotg, linux-kvm, linux-lowlatency, linux-lowlatency-hwe-5.15, linux-oracle, linux-realtime, linux-xilinx-zynqmp, linux-aws, linux-gcp, linux-gcp-4.15, linux-gcp-fips, linux-aws-fips, linux-ibm-5.15, linux-intel-iotg-5.15, octavia, and swift).

12:35

On Anthropic’s AI Misuse Report [Schneier on Security]

Earlier this month, Anthropic published a long report detailing all of the Claude misuses it detected. Daniel Meissler usefully summarized the report into 117 findings.

A few of the highlights:

  • AI agents increasingly handled reconnaissance, exploitation, data theft, propaganda production, surveillance workflows, and research while humans selected targets, set goals, and reviewed important outputs.
  • The report describes attackers using AI to industrialize credential theft, cloud compromise, phishing, vulnerability research, and the extraction of sensitive data from downstream organizations.
  • Influence operations used persistent agent memory, fake news sites, fabricated journalists, synthetic personas, political profiling, and large-scale multilingual content, although high content volume often produced little genuine engagement.
  • Surveillance and repression cases included automated dossiers, biometric and communications analysis, transnational targeting, coercive recruitment, and systems that continued operating locally after model access was revoked.
  • Biological and weapons cases show dual-use risk: AI supported advanced scientific and military work, but the report generally doesn’t establish completed biological weapons or operational battlefield deployment.

10:28

Thinking about your purpose [Seth's Blog]

I don’t believe we’re each born with a purpose. We have more freedom than that, the freedom to choose the impact we’ll make.

Our work, though, does have a purpose. The change we seek to make. The people we’re here to make it for.

When we commit to work with purpose, it transforms us as well as the people we’re engaging with.

Who’s it for, what’s it for… if we can continue to return to the purpose of this product, this meeting, this ad–then we can find a common language and coordinate our efforts to make a difference.

Resistance pushes us in many ways. It pushes us to imagine that our work isn’t for us, we’re just biding time until we get to the real stuff. It pushes us to deny responsibility or to blame the system. And mostly, it pushes us to refuse to name the purpose of how we’re spending our time.

Stuck is just another word for being conflicted about our purpose. The knot holds us back because we’ve become entangled in goals that are mutually exclusive.

Say what you want [Seth's Blog]

The problem is with the “and.” (Often a ‘but’ in disguise.)

I want to make the art I have in my head, and I want the market to love it.

I want to have the wedding of my dreams, and I don’t want to worry about money, and I want my cousins and friends to enjoy every bit of it.

I want to take few risks and I want extraordinary returns.

I want to have a difficult conversation and I want there to be no tension, stress or possible downsides.

We hesitate to admit what we really want because when the ‘and’ shows up, we can see we’re being unreasonable. It’s easier to simply hope and dream.

Strategic thinking doesn’t ignore the systems all around us, or the trade-offs that scarcity and competition require. Instead, it embraces them.

08:14

Goerbemisdag [Penny Arcade]

New Comic: Goerbemisdag

07:35

We’ve been here before: Qualcomm promises Linux support for Snapdragon X2 [OSnews]

Qualcomm, yesterday, promising Linux support for the new Snapdragon X2 processors:

Linux on Snapdragon X2 Series is moving from early bring-up toward a more complete upstream developer experience. Core support is landing, Hexagon NPU and Adreno GPU work is progressing, and real laptops with Snapdragon X2 Series processors are already beginning to boot Linux.

↫ Qualcomm’s promises from 2026

Interesting, but I feel like I’ve heard these exact words before. Qualcomm, two years ago, promising Linux support for the then-new Snapdragon X processors:

It’s been our priority not only to support Linux on our premium-tier SoCs, but to support it pronto. In fact, within one or two days of publicly announcing each generation of Snapdragon 8, we’ve posted the initial patchset for Linux kernel support. Snapdragon X Elite was no exception: we announced on October 23 of last year and posted the patchset the next day. That was the result of a lot of pre-announcement work to get everything up and running on Linux and Debian.

↫ Qualcomm’s empty promises from 2024

These promises were not at all kept. Two years later, Linux support for Snapdragon X laptops is still spotty, broken, and limited, confined to just a few bespoke Ubuntu builds, which don’t even offer full support either. It’s a complete mess, effectively unusable, and highlights once again that big technology companies are compulsive liars. I have little faith in these new promises, but who knows – maybe this time it’ll be different.

Probably not, though.

06:00

Girl Genius for Friday, September 25, 2026 [Girl Genius]

The Girl Genius comic for Friday, September 25, 2026 has been posted.

Thursday, 24 September

22:14

No, really, you need to pass all unhandled messages to DefWindowProc, part 2 [The Old New Thing]

A customer reported a memory leak in Windows that occurred when they called Register­Drag­Drop followed by Revoke­Drag­Drop. They included a time travel trace of a sample program that demonstrated the problem. (Though for some reason, they didn’t include the program itself; just the time travel trace.)

Now, it is strange that there would be a memory leak if you call Register­Drag­Drop followed by Revoke­Drag­Drop, seeing as this pattern is used heavily by thousands of applications, including many parts of Windows itself, so if there were a memory leak inherent in the pattern, you’d think it’d have been reported by now.

I suspected that there was something special about their sample program.

Some time ago, I noted that No, really, you need to pass all unhandled messages to DefWindowProc. And that was the source of the problem.

Debugging through the time travel trace showed that yes, they did call Register­Drag­Drop, and then they did call Revoke­Drag­Drop. But there’s more going on. When the window receives a WM_DESTROY message, it cleans up all its state. And for any messages that arrive after WM_DESTROY, the window procedure goes looking for its special state and doesn’t see it, so it gives up and just returns 0 without passing the message to Def­Window­Proc.

Oops.

If the window procedure can’t figure out what to do, it should pass all messages to Def­Window­Proc. In this case, it’s important because some of those messages are cleanup messages, and one of the things those cleanup messages do is free the last few fragments of memory still hanging around.

Bonus chatter: But if I register a drop target, and then revoke it, shouldn’t the revoke free all the memory that was allocated by the register call?

There’s no requirement that registering something and then unregistering it will immediately free all the memory associated with the registration. The system is allowed to cache stuff that it thinks will be needed again.

In this case, what happened is that the Register­Drag­Drop function uses an infrastructure that is shared by many components. That infrastructure is created and attached to the window the first time anybody needs it, and it is cleaned up when the window is destroyed. The memory isn’t leaked. It’s just cached on the window, waiting to be used by another operation. And the cache is destroyed when the window is destroyed.

But it assumes that you give Def­Window­Proc a chance to do that cleanup.

The post No, really, you need to pass all unhandled messages to DefWindowProc, part 2 appeared first on The Old New Thing.

21:28

20:42

Dirk Eddelbuettel: RcppFastAD 0.0.5 on CRAN: Maintenance [Planet Debian]

A new release 0.0.5 of the RcppFastAD package is now on CRAN, has been built for r2u, and updated at r-universe. This comes (to the day) two years after the preceding 0.0.4 release.

RcppFastAD wraps the FastAD header-only C++ library by James which provides a C++ implementation of both forward and reverse mode of automatic differentiation. It offers an easy-to-use header library that is both lightweight and performant. With a little of bit of Rcpp glue, it is also easy to use from R in simple C++ applications. This release updates the continuous integration setup as one does, adds a local configuration helper to quieten compilation (described also in this blog post). It also adds a defensive setting for g++: Under recent g++ versions and optimisation at least the -O3 level, segfaults are seen as something is not quite right with (temporary) “views” of Eigen objects in code generated by this versions. Others are fine, as is clang++. We have not gotten to the bottom of it, but setting -g0 seems to ensure that builds generally work.

The NEWS file for this release follows.

Changes in version 0.0.5 (2026-09-24)

  • Several routine updates to continuous integration have been made

  • Local builds (where a .git/ directory is seen) now append silencing compiler option that CRAN would object to

  • Given recent issues with g++ under optimization, debugging is turned off by default.

Courtesy of my CRANberries, there is also a diffstat report for the most recent release. More information is available at the repository or the package page.

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

20:07

Our Thrilling New Purchase [Whatever]

Our washer and dryer set had been with us 15+ years and were really showing their age. The dryer’s closing mechanism had to be negotiated with in order to be fully secured, and our washer had finally gotten to the point where even enthusiastic cleaning of every visible interior surface could no longer get rid of a vague musty smell. It was time for their replacements, which arrived today.

I’ll note that while we could have gone with a washer-dryer set with all the modern bells and whistles, Krissy intentionally went with a set that was basically as low-tech as one could buy in this modern era. We don’t need an LED screen or phone alerts, and recent news has shown that “smart appliances” can mess you up with a bad update. We just need to laundry. It’s not, nor should it be, rocket science.

Getting new major appliances was also a reminder that as an adult, the things you get excited and happy about are very different from what you’d get excited about when you were younger. New washer and dryer? Cool! No more wrestling with dryer doors or sniffing shirts to make sure they actually smell fresh! They just work like they’re supposed to! Wheeee! Also, now I really like socks as a gift. Adults, man.

— JS

Feeds

FeedRSSLast fetchedNext fetched after
@ASmartBear XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
a bag of four grapes XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Ansible XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Bad Science XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Black Doggerel XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Blog - Official site of Stephen Fry XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Charlie Brooker | The Guardian XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Charlie's Diary XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Chasing the Sunset - Comics Only XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Coding Horror XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
Comics Archive - Spinnyverse XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
Cory Doctorow's craphound.com XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Cory Doctorow, Author at Boing Boing XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Ctrl+Alt+Del Comic XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Cyberunions XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
David Mitchell | The Guardian XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Deeplinks XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
Diesel Sweeties webcomic by rstevens XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Dilbert XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Dork Tower XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Economics from the Top Down XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Edmund Finney's Quest to Find the Meaning of Life XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
EFF Action Center XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Enspiral Tales - Medium XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Events XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Falkvinge on Liberty XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Flipside XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Flipside XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Free software jobs XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Full Frontal Nerdity by Aaron Williams XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
General Protection Fault: Comic Updates XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
George Monbiot XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Girl Genius XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Groklaw XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Grrl Power XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Hackney Anarchist Group XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Hackney Solidarity Network XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
http://blog.llvm.org/feeds/posts/default XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
http://eng.anarchoblogs.org/feed/atom/ XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
http://feed43.com/3874015735218037.xml XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
http://flatearthnews.net/flatearthnews.net/blogfeed XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
http://fulltextrssfeed.com/ XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
http://london.indymedia.org/articles.rss XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&amp;_render=rss XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
http://planet.gridpp.ac.uk/atom.xml XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
http://shirky.com/weblog/feed/atom/ XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
http://thecommune.co.uk/feed/ XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
http://theness.com/roguesgallery/feed/ XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
http://www.airshipentertainment.com/buck/buckcomic/buck.rss XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
http://www.airshipentertainment.com/growf/growfcomic/growf.rss XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
http://www.airshipentertainment.com/myth/mythcomic/myth.rss XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
http://www.feedsapi.com/makefulltextfeed.php?url=http%3A%2F%2Fwww.somethingpositive.net%2Fsp.xml&what=auto&key=&max=7&links=preserve&exc=&privacy=I+accept XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
http://www.godhatesastronauts.com/feed/ XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
http://www.tinycat.co.uk/feed/ XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
https://anarchism.pageabode.com/blogs/anarcho/feed/ XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
https://broodhollow.krisstraub.comfeed/ XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
https://debian-administration.org/atom.xml XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
https://elitetheatre.org/ XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
https://feeds.feedburner.com/Starslip XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
https://feeds2.feedburner.com/GeekEtiquette?format=xml XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
https://hackbloc.org/rss.xml XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
https://kajafoglio.livejournal.com/data/atom/ XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
https://philfoglio.livejournal.com/data/atom/ XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
https://pixietrixcomix.com/eerie-cutiescomic.rss XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
https://pixietrixcomix.com/menage-a-3/comic.rss XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
https://propertyistheft.wordpress.com/feed/ XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
https://requiem.seraph-inn.com/updates.rss XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
https://studiofoglio.livejournal.com/data/atom/ XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
https://thecommandline.net/feed/ XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
https://torrentfreak.com/subscriptions/ XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
https://web.randi.org/?format=feed&type=rss XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
https://www.baen.com/baenebooks XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
https://www.dcscience.net/feed/medium.co XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
https://www.DropCatch.com/domain/steampunkmagazine.com XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
https://www.DropCatch.com/domain/ubuntuweblogs.org XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
https://www.DropCatch.com/redirect/?domain=DyingAlone.net XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
https://www.freedompress.org.uk:443/news/feed/ XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
https://www.goblinscomic.com/category/comics/feed/ XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
https://www.loomio.com/blog/feed/ XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
https://www.newstatesman.com/feeds/blogs/laurie-penny.rss XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
https://www.patreon.com/graveyardgreg/posts/comic.rss XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
https://www.rightmove.co.uk/rss/property-for-sale/find.html?locationIdentifier=REGION^876&maxPrice=240000&minBedrooms=2&displayPropertyType=houses&oldDisplayPropertyType=houses&primaryDisplayPropertyType=houses&oldPrimaryDisplayPropertyType=houses&numberOfPropertiesPerPage=24 XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
https://x.com/statuses/user_timeline/22724360.rss XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Humble Bundle Blog XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
I, Cringely XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Irregular Webcomic! XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Joel on Software XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
Judith Proctor's Journal XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Krebs on Security XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Lambda the Ultimate - Programming Languages Weblog XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Looking For Group XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
LWN.net XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Mimi and Eunice XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Neil Gaiman's Journal XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
Nina Paley XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
O Abnormal – Scifi/Fantasy Artist XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Oglaf! -- Comics. Often dirty. XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Oh Joy Sex Toy XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
Order of the Stick XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
Original Fiction Archives - Reactor XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
OSnews XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Paul Graham: Unofficial RSS Feed XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Penny Arcade XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Penny Red XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
PHD Comics XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Phil's blog XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
Planet Debian XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Planet GNU XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Planet Lisp XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Pluralistic: Daily links from Cory Doctorow XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
PS238 by Aaron Williams XML 21:14, Wednesday, 30 September 22:02, Wednesday, 30 September
QC RSS v2 XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
Radar XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
RevK®'s ramblings XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
Richard Stallman's Political Notes XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Scenes From A Multiverse XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
Schneier on Security XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
SCHNEWS.ORG.UK XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
Scripting News XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Seth's Blog XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
Skin Horse XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Tales From the Riverbank XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
The Adventures of Dr. McNinja XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
The Bumpycat sat on the mat XML 21:35, Wednesday, 30 September 22:15, Wednesday, 30 September
The Daily WTF XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
The Monochrome Mob XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
The Non-Adventures of Wonderella XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
The Old New Thing XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
The Open Source Grid Engine Blog XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
The Stranger XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
towerhamletsalarm XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
Twokinds XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
UK Indymedia Features XML 21:56, Wednesday, 30 September 22:38, Wednesday, 30 September
Uploads from ne11y XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
Uploads from piasladic XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September
Use Sword on Monster XML 21:14, Wednesday, 30 September 22:01, Wednesday, 30 September
Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily XML 21:21, Wednesday, 30 September 22:07, Wednesday, 30 September
what if? XML 21:35, Wednesday, 30 September 22:16, Wednesday, 30 September
Whatever XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
Whitechapel Anarchist Group XML 21:14, Wednesday, 30 September 22:03, Wednesday, 30 September
WIL WHEATON dot NET XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
wish XML 21:21, Wednesday, 30 September 22:06, Wednesday, 30 September
Writing the Bright Fantastic XML 21:21, Wednesday, 30 September 22:05, Wednesday, 30 September
xkcd.com XML 21:21, Wednesday, 30 September 22:04, Wednesday, 30 September