17 Jun 2026

feedPlanet Grep

Frederic Descamps: MariaDB + TidesDB: my first steps with this new engine

After testing the latest Storage Engine in the MariaDB family, DuckDB, I wanted to test another storage engine about which I had only heard good things: TideSQL. TideSQL is the name of the pluggable storage engine for MariaDB Server powered by TidesDB. TidesDB is an LSM-tree-based storage engine, and TideSQL makes it available directly inside […]

17 Jun 2026 7:58pm GMT

Dries Buytaert: The 2026 redesign of dri.es

I spent last weekend redesigning dri.es, squeezed between hosting one barbecue, going to another, and driving to the Belgian beach.

I didn't write a single line of HTML or CSS myself. I told Claude Code what I wanted, and it generated a Drupal theme.

Here are a few before-and-after screenshots that show what changed.

Screenshot of the main page in the old dri.es design. Before: The old homepage, with a blue header. Screenshot of the main page in the new dri.es design. After: The redesigned homepage, with recent photos.

The new design is still minimalist, like the previous one. I prefer simple websites that focus on the content.

Vanessa thinks it is too plain. Given our respective records on style and fashion, she is almost certainly right.

Screenshot of a blog post in the old dri.es design. Before: The old article page, with a blue header. Screenshot of a blog post in the new dri.es design. After: The redesigned article page, with a larger lead image.

Besides a new design, I also added a photo strip to the main page, cleaned up the sensor pages, added charts to the tag pages, and more.

So if the new design feels a little too plain, you may still find a few new things to enjoy.

17 Jun 2026 7:58pm GMT

Dries Buytaert: AI and the great CMS unbundling

The question I get most these days is: did AI kill the CMS? Should we still invest in a CMS, switch to AI agents, or wait until the market becomes clearer?

At a friend's birthday party recently, I was talking with engineers and startup CEOs. They were all smart people, but none of them worked in the CMS industry. From where they sat, AI seemed to make the CMS obsolete.

I understand why. AI can now generate copy, design pages, write code, translate content, and assemble websites. If that is what you think a CMS is for, it does look like the CMS is in trouble.

They may be right about one part of the CMS market. But I think they are wrong about the larger picture.

To see why, it helps to separate what a content management system, or CMS, does into two planes: the control plane and the execution plane.

The control plane governs content: who can edit it, what gets approved, which version is canonical, how translations move through workflow, and where content can be used.

The execution plane creates, assembles, and delivers that content into websites, mobile apps, feeds, and other customer experiences.

AI is unbundling these two planes. It is commoditizing the execution plane while making the control plane more valuable. That is why I think AI is killing one corner of the CMS market, but making the CMS more critical everywhere else.

This post is a companion to AI and the great digital agency unbundling. That post looked at AI's impact on the digital agency market. This one looks at the same unbundling pattern in content management systems and digital experience platforms.

AI lowers the cost of creation, not the cost of trust

We have seen this pattern before. The printing press made it cheap to produce and distribute content, but it did not make editors or publishers irrelevant. It made them more important, because more content created more need for judgment, trust, and standards.

AI is doing something similar to digital content. It makes production cheaper: drafting, generating, translating, designing, assembling pages, and adapting content for different channels.

But AI should not be the final authority on what is correct, approved, compliant, or safe to publish. It can help, but people and systems still need to own those decisions. The more content AI helps produce and distribute, the more that ownership matters.

As production gets cheaper, control becomes more important, not less.

That is the real test for a CMS. Not whether AI can generate content or build a page, but whether your organization needs a control layer: roles, review, approvals, publishing states, revision history, and more.

How shared is your work?

Two simple questions can help decide how much you need a CMS:

  1. How many people or agents create, review, and publish content?
  2. How many systems need to use, update, or trust that content?

Put those questions on a grid, and four use cases emerge.

A two-by-two grid showing four scenarios: Assist, Relay, Delegate, and Orchestrate. The vertical axis moves from one person to many people and agents. The horizontal axis moves from one system to many systems and channels. AI tools may be enough for simple solo work, but a CMS becomes more important as content work involves more people and systems. The more people, agents, systems, and channels involved, the more a CMS matters as the control layer.

When one person creates and publishes content, and no other systems depend on it, you may not need a CMS. A lightweight publishing tool or AI site builder may be enough.

When multiple people or agents touch content, you need a CMS for coordination: roles, review, approvals, publishing states, and revision history. AI inside the CMS can help teams create, review, and publish faster without losing control.

When many systems touch content, you need a CMS as the trusted source for content, permissions, workflows, and publishing controls. AI around the CMS can coordinate work across tools, but it still depends on the CMS to know what content is approved, who can use it, and where it can go.

In short, when many people and many systems are involved, the CMS becomes the critical control layer for people, agents, and systems working together. It gives people and agents a safe place to create and approve content, and gives other tools a trusted system they can read from, write to, and build on.

The decision, by quadrant

1. Assist: one person, one system

This is the simplest case: one person, one system, and little coordination.

If you are creating a new website quickly, an AI site builder may be the right tool. It can turn a prompt into a working site in an afternoon. In that case, a CMS may slow you down more than it helps. This is 1a in the quadrant image: the job is to create, not to manage.

But one person does not always mean a CMS is unnecessary.

My website has been around for more than twenty years. It has more than 1,500 blog posts and 10,000 photos. That is not just a website to create; it is a body of content to manage. Drupal helps me manage that content as structured content: content types, fields, taxonomy, media, revisions, URLs, and search.

I would not move my site to a standalone AI site builder. But I do use an AI agent to work on it through Drupal: updating content, improving existing features, and building new ones. This is 1b on the chart. AI helps with the execution work, while Drupal remains the control plane. This is the CMS unbundling at the smallest scale.

So use an AI builder when speed to a new site matters most. Use a CMS when the work is about managing a large or growing body of content over time: keeping it structured, consistent, reusable, and reliable.

2. Relay: many people, one system

This is a clear case for a CMS.

When many people collaborate on one website, the work becomes a "relay": a designer uploads an image, a developer builds a component, a marketer writes the copy, an editor reviews the page, legal approves it, and someone presses publish.

AI does not remove that relay; it makes it move faster. The developer may use an AI coding agent, the marketer may use an AI writing assistant, and the editor may use an AI policy checker. More work moves through the same website, with less time between handoffs.

But the moment several people and several agents are working on the same website, you need a control layer to manage roles, permissions, approvals, revision history, and one source of truth.

A CMS lets teams move at AI speed without losing track of who changed what, which version is approved, and what is safe to publish.

3. Delegate: one person, many systems

In the Delegate scenario you are still one person, so there is little coordination with other people. But the work now spans many systems: a CMS, an email marketing platform, a commerce system, a CRM, and a planning tool.

When one person spans many systems, no single product sees the whole job. The center of gravity moves to the coordinator: an automation tool that connects your systems, or an AI agent that works across their APIs.

That is why this quadrant is debatable. For a short-lived campaign, you may not need a traditional CMS. You might use an AI builder for the site and an automation tool or agent to coordinate the rest. This is 3a on the chart.

But that only works while the content is small, short-lived, and easy to manage by hand. Once the content has to be structured, reused, updated, approved, or kept consistent across systems, you need a trusted source for it. This is 3b on the quadrant image.

4. Orchestrate: many people, many systems

This is the most complex environment, and the clearest case for a CMS.

A company campaign can involve many people and many systems at once: a marketer plans the campaign, a designer reviews the creative, legal approves the content, an editor publishes the page, marketing operations builds the email, and a commerce manager checks the discount. Every person has a role, and every system has a workflow.

AI can remove much of the coordination work: reminders, status updates, handoffs, and manual routing. But coordination is not control. Someone still has to approve the content, approve the promotion, and answer for the campaign's effectiveness.

In this quadrant, the CMS has two jobs. First, it has to govern and accelerate the work that happens inside the CMS. Second, it has to make that work usable by the broader digital ecosystem.

The CMS is not necessarily the orchestrator of that ecosystem. It is the governed workspace where people and agents can work safely, and the trusted source that other systems and agents can read from, write to, and build on.

At this scale, and at AI speed, a weak content foundation becomes expensive fast. A strong CMS is not optional.

From unbundling to rebundling

One thing the grid does not show is where the market is moving the fastest. Right now, most of the visible energy is on the bottom row of Assist and Delegate, sections 1a and 3a, where no control plane is needed: one person using AI to create and coordinate faster.

In Assist, that means AI site builders that turn an idea into a working website. In Delegate, it means agents and automation for single-person workflows across different systems.

Lovable reportedly reached roughly $400 million in annual recurring revenue less than two years after launch. n8n raised $180 million at a $2.5 billion valuation in 2025.

But once many people are involved, individual productivity is no longer enough. Organizations need productivity, coordination, and control.

The current wave of AI site builders is mostly making one person faster. The next wave has to make organizations faster without losing trust.

AI is unbundling creation from the CMS and driving its cost toward zero. But once creation becomes cheap and abundant, the value shifts to control.

That is where rebundling starts. The next generation of products will combine AI-powered creation with a trusted control plane.

So, is the CMS dead? No. Its role is changing.

The more AI you use to create, translate, update, and publish content, the more you need a system that keeps that work structured, approved, reusable, and safe.

That means that a CMS is not a competing line item to your AI budget. It is what makes that budget pay off.

And the real risk is not that AI replaces your CMS. It is running AI without one.

AI gives you speed. A CMS gives you control at speed.

17 Jun 2026 7:58pm GMT

feedPlanet Debian

Joey Hess: best of the web

This is somehow the featured website on https://earlyweblinks.com/ this week.

Read all about my web site here! https://earlyweblinks.com/site-of-the-week/joey-hess

Kind of reminds me of back in 1995 or so when my website would randomly end up picked by some best of the web list that I never heard of. The web is still a small place I guess.

Maybe I should join a web ring or something?

17 Jun 2026 3:11pm GMT

Dirk Eddelbuettel: rspdlite 0.1.0-1 on CRAN: New Package!

Very happy to share that a new package rspdlite arrived on CRAN today in its inaugural version 0.1.0-1. It wraps and provides the (header-only) C++20 library spdlite which its author describes (aptly) as tiny, fast, capable. Just like its bigger sibbling spdlog (which we wrapped as rcppspdlog), it is written by Gabi Melman. However, with a focus on C++20 and compile-time configuration, it is lighter, nimbler and faster. It is also still a fairly young project so changes may occur.

I have been working on this for about a month, and it is ready for use by R and C++. It contains the initial upstream release 0.1.0, and I plan to follow the upstream versioning making this first release as 0.1.0-1.

The package itself provides the headers for use from other C++ projects (i.e. mostly other packages), as well as a simple R wrapper so that logging can occur from either C++ or R. It will generally access the single logger instance in a compilation unit. So for a package built against these header it would be shared library of that package. At present we provide the basic logging level setters and getters, formatting accessors, and two (compile-time) options of a 'null logger' and a file-based logger. More options are availble from the C++ level, multiple logging sinks are but one example. Some examples are provided in the package as an R example and a C++ example; these are probably best examined from the sources.

The NEWS entry for this release is simply and just announces that we have a release. More details are in the ChangeLog and the GitHub repo.

Changes in version 0.1.0-1 (2025-06-08)

  • Initial complete version and CRAN upload

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. You can also sponsor my Tour de Shore 2026 ride in support of the Maywood Fine Arts Center.

17 Jun 2026 12:16am GMT

16 Jun 2026

feedPlanet Debian

Mike Gabriel: Ubuntu Touch development - 24.04-2.0 Beta and Meaning of Branching-Off

The next Ubuntu Touch major release is approaching rapidly, yesterday we reached a major step in the preparation of the upcoming Ubuntu Touch 24.04-2.0 release: The branching-off (see below on what that is).

Ubuntu Touch 24.04-2.0 Beta is Now Available

Part of this development release step is the publication of the 24.04-2.0 Beta release images, for more details and information see:
https://ubports.com/blog/ubports-news-1/ubuntu-touch-24-04-2-0-beta-is-n...

And additionally, find below some background information on how we maintain various Ubuntu Touch releases in parallel via Git(Lab). In fact, the release model of Ubuntu Touch has partially been adopted from how we in Debian maintains our various Debian versions in parallel, only that in Ubuntu Touch we use Git(Lab) for maintaining the different package versions and not, like in Debian, the APT archive itself.

What does 'Branching-Off' Mean?

Last Saturday, in the UBports Q&A, I explained Ubuntu Touch's "branching-off", an aspect of the Ubuntu Touch release workflow based on Git(Lab). To make this accessible to even more people, here it comes as a write-up:

We host many Git repositories on GitLab, and our primary work is done on the main branches, which contain the bleeding-edge code. When a merge request is deemed critical for stable versions of Ubuntu Touch, we cherry-pick it into a release series branch.

Currently, we land our changes in the main branches and then cherry-pick them to the ubports/24.04.1.x branches. The 'branching off' process for the upcoming 24.04-2.x release means that our current main branches will be copied over to create new branches for this release cycle, namely ubports/24.04-2.x.

This has two major implications. First, any item that hasn't been translated by the time of the branch-off will not receive any more translation updates during the 24.04-2.x cycle. This is why it is crucial that translation work is completed before the branching-off.

Warning of Breaking Changes arriving soon in 26.04-1.x Daily Development UT Images

Second, looking ahead to the release after 24.04-2.x, we will be approaching 26.04-1.x. The OS base will change to Ubuntu 26.04 LTS, hopefully being ready for release to Ubuntu Touch users before the end of the year. We already have a list of features we want to land there. Because we plan to include various major changes, such as the switch from Mir 1 to Mir 2, new calendar and contacts backends, Qt6-based core apps and service components, etc., the likelihood of breaking changes at the beginning of the 26.04-1.x release cycle (which will become the next main branches' target) is very high.

The Ubuntu Touch 24.04-2.0 Release Schedule

The current release schedule is estimated to be:

25 May 2026 [done]
Platform stability freeze 24.04-2.x

25 May 2026 [done]
String freeze 24.04-2.x

15 June 2026 [done]
Branching-off (and unfreeze 26.04-1.x development), UT image release: 24.04-2.0 Beta

22 or 29 June 2026 [coming]
Final freeze for 24.04-2.x, UT image release: 24.04-2.0 RC

6 or 13 July 2026 [coming]
Release version 24.04-2.0

16 Jun 2026 11:14am GMT

01 Jun 2026

feedPlanet Lisp

Joe Marshall: Regression

Last year I wrote some Lisp related AI apps. There was a syntax highlighter that used the LLM to determine how to colorize and highlight syntax, and a prompt refiner that takes a wimpy LLM prompt and creates more elaborate prompt from them.

I took the apps down last week. They were `vibe coded' and therefore approximate and had bugs (but that's to be expected), but they had a security hole where you could hijack the LLM processing with your own prompt turning my app into an open relay using my API key. Last week I discovered that my AI spend on video creation was becoming serious. This is odd because I never create AI video. It turned out that my app was being hijacked by a proxy in Luxembourg and was generating videos on my dime.

So I shut down the apps. I knew they had the potential of being abused, and I was willing to tolerate a small amount of abuse, but it didn't occur to me that syntax highlighter could be hijacked to generate gigabytes of video at my expense. Future applications will be careful to obtain the API key from the user.

01 Jun 2026 7:00am GMT

31 May 2026

feedPlanet Lisp

Joe Marshall: CLRHack: Meta-object Protocol

Metaobject Protocol (MOP) Implementation in CLRHack

The Metaobject Protocol in CLRHack is a high-performance implementation of the Common Lisp Object System (CLOS) integrated into the .NET 8.0 Common Language Runtime (CLR). It provides a complete meta-compilation pipeline that bridges the gap between dynamic Lisp semantics and the static CIL (Common Intermediate Language) execution model.

Core Architecture

The MOP is implemented through three primary layers:

  1. The Metaobject Hierarchy (C#): A set of foundational classes in LispBase representing classes, methods, generic functions, and slot definitions.
  2. The Runtime Engine (MopRuntime): A centralized orchestrator that manages class finalization, method combination, dispatch caching, and instance allocation.
  3. The Compiler Bridge (Lisp): Transformations in ast.lisp that translate high-level CLOS forms (defclass, defmethod) into optimized runtime calls.

Instance Representation

Because the CLR type system is strictly single-inheritance and statically defined, CLRHack decouples Lisp-level inheritance from C# inheritance. All CLOS instances are represented by the StandardObjectInstance class, which contains:

The Dispatch Pipeline

Generic function invocation is the most complex part of the implementation. When a generic function is called:

  1. Cache Lookup: The DiscriminatingFunction first checks a thread-safe dispatchCache using an InvocationCacheKey (a stack-allocated struct) to find a previously computed effective method.
  2. Applicability & Precedence: If the cache misses, the runtime computes all applicable methods and sorts them based on specializer specificity and the Class Precedence List (CPL).
  3. Method Combination: The ComputeEffectiveMethod logic builds a nested execution chain following the Standard Method Combination rules:
    • :around methods are called first, with call-next-method progressing to the next around method or the main chain.
    • The main chain executes all :before methods, the primary method, and finally all :after methods in reverse order.
  4. Fast Invocation: The resulting effective method is compiled into a Func<object[], object> that uses direct delegate invocation to minimize overhead.

Challenges and Solutions

1. Thread-Safe Non-Local Exits (call-next-method)

Challenge: call-next-method and next-method-p require access to the current invocation's state (the remaining methods and original arguments). Passing this state through every function call would break compatibility with standard Lisp function signatures.

Solution: CLRHack utilizes [ThreadStatic] fields in MopRuntime to store the currentNextMethods and currentArguments. This ensures that even in highly concurrent environments (like a web server), each OS thread has its own isolated invocation context, allowing call-next-method to function correctly without state leakage.

2. Forward References and Lazy Finalization

Challenge: Lisp allows classes to refer to superclasses that haven't been defined yet. The runtime must handle these "zombie" classes without crashing the JIT compiler.

Solution: The system implements a ForwardReferencedClassMetaobject. When a class is defined, it is automatically finalized (computing its CPL and slot layout). If a superclass is missing, a forward reference is created. The EnsureFinalized protocol ensures that inheritance is resolved and slot locations are assigned the moment the class is first instantiated or used in dispatch.

3. Performance Overhead of the "MOP Bridge"

Challenge: A naive implementation of slot-value or generic dispatch using C# reflection or linear searches is orders of magnitude slower than native C# member access.

Solution: Three distinct optimizations were applied:

4. Bootstrapping the COMMON-LISP Package

Challenge: Core CLOS functions like make-instance must be available as symbols in the COMMON-LISP package before user code runs, but they rely on the MOP runtime being fully initialized.

Solution: A MopRuntime.Initialize() method is injected into the entry point (Main) of every generated assembly. This method interns the necessary symbols and binds them to GenericFunctionClosureAdapter objects, ensuring that the MOP is "alive" before the first line of Lisp code executes.


Vibe coding the MOP basically involved feeding chapters 4 and 5 of the Art of the Meta-Object Protocol into the LLM and telling it to make an implementation plan. It came up with a twenty-step plan to bootstrap CLOS. I then spent the rest of the day instructing an agent to take on each task of the twenty-step plan in sequential order. At the end of the day, I had a working MOP

This is the end of my series of posts on CLRHack.

31 May 2026 7:00am GMT

30 May 2026

feedPlanet Lisp

Joe Marshall: CLRHack: signal and error

Implementation of SIGNAL and ERROR in CLRHack

In CLRHack, the condition signaling system is implemented in the Lisp.HandlerControl class within the LispBase library. It leverages .NET's [ThreadStatic] storage to maintain a per-thread dynamic stack of active condition handlers.

SIGNAL Implementation

The Signal(object condition) method performs the following logic:

  1. Retrieval: It fetches the activeHandlers list for the current thread. This list is a chain of [LispBase]Lisp.Handler objects maintained by handler-bind.
  2. Iteration: It iterates linearly through the list from the most recently bound handler to the oldest.
  3. Type Matching: For each handler, it calls IsType(condition, handler.ConditionType).
    • If the condition is a symbol, it checks for symbol equality (supporting simple symbol-based conditions).
    • If the condition is a .NET object, it checks if the handler's type is assignable from the condition's runtime type (supporting interop with system exceptions).
    • It treats the symbols T or EXCEPTION as catch-all types.
  4. Handler Invocation: If a match is found:
    • Recursive Signal Protection: Before calling the handler function, the current handler list is temporarily shadowed. activeHandlers is set to cell.rest (the handlers bound outside the current one). This ensures that if the handler itself calls signal, it won't trigger itself recursively.
    • Execution: The handler's Closure is invoked with the condition object as its argument.
    • Restoration: A finally block ensures the original activeHandlers list is restored if the handler returns normally.

    ERROR Implementation

    The Error(object condition) method build upon Signal:

    1. Signaling Pass: It first invokes Signal(condition). If a handler performs a non-local exit (e.g., via handler-case), the Error method never returns.
    2. Debugger Entry: If Signal returns normally (meaning all handlers declined), Error calls EnterDebugger(condition).
    3. Interactive Debugging: The debugger:
      • Prints the condition and a list of available restarts (retrieved via RestartControl.GetActiveRestarts()).
      • Provides a prompt for the user to select a restart, launch the system-level debugger (Visual Studio/Rider), or abort.
      • If a restart is selected, it is invoked interactively (potentially gathering arguments from the user).
    4. Final Fallback: If the debugger is exited without invoking a restart, Error throws a C# Exception to ensure that execution does not continue on an invalid path.

    Notable Implementation Decisions and Edge Cases

signal and error complete the Common Lisp condition system implementation for CLRHack

30 May 2026 7:00am GMT

25 Apr 2026

feedFOSDEM 2026

All FOSDEM 2026 videos are online

All video recordings from FOSDEM 2026 that are worth publishing have been processed and released. Videos are linked from the individual schedule pages for the talks and the full schedule page. They are also available, organised by room, at video.fosdem.org/2026. While all released videos have been reviewed by a human, it remains possible that one or more issues fell through the cracks. If you notice any problem with a video you care about, please let us know as soon as possible so we can look into it before the video-processing infrastructure is shut down for this edition. To report any舰

25 Apr 2026 10:00pm GMT

29 Jan 2026

feedFOSDEM 2026

Join the FOSDEM Treasure Hunt!

Are you ready for another challenge? We're excited to host the second yearly edition of our treasure hunt at FOSDEM! Participants must solve five sequential challenges to uncover the final answer. Update: the treasure hunt has been successfully solved by multiple participants, and the main prizes have now been claimed. But the fun doesn't stop here. If you still manage to find the correct final answer and go to Infodesk K, you will receive a small consolation prize as a reward for your effort. If you're still looking for a challenge, the 2025 treasure hunt is still unsolved, so舰

29 Jan 2026 11:00pm GMT

26 Jan 2026

feedFOSDEM 2026

Call for volunteers

With FOSDEM just a few days away, it is time for us to enlist your help. Every year, an enthusiastic band of volunteers make FOSDEM happen and make it a fun and safe place for all our attendees. We could not do this without you. This year we again need as many hands as possible, especially for heralding during the conference, during the buildup (starting Friday at noon) and teardown (Sunday evening). No need to worry about missing lunch at the weekend, food will be provided. Would you like to be part of the team that makes FOSDEM tick?舰

26 Jan 2026 11:00pm GMT