GitHub Icon BYTE • WORKFLOW

Atproto Gave Me Superpowers to Fix My Bookhive Data

Yesterday I imported my StoryGraph (a famous Goodreads alternative) data into BookHive (a much less famous Goodreads alternative built on atproto).1

The migration went only partially okay. It imported 50% of my history, and the entries that were imported had wrong or missing data, in particular the dates I started reading them.

Matching books is HARD, so I am not criticizing BookHive. Still, I had to fix all the values, and the task was boring and overwhelming.

Then I realized that BookHive data is hosted on my PDS2. So I thought, “What if I give Claude a temporary password and unleash it to fix my data?”

After all, I keep extensive notes on all the books I read (and more) in my Obsidian vault. Each book has start/read dates, scores, ratings, and all the data it needs.

So I asked it. In two minutes, I got this answer:

I logged into your PDS setup (handle davideaversa.it on eurosky.social) read-only (no auth needed for listing) and compared your Bookhive library against the vault. Here’s what I found:

Bookhive already has 229 book records (171 finished, 57 want-to-read, 1 reading) — looks like it was populated recently, likely via a Goodreads import.

Vault has 177 books with a read_on date. Comparing them:

83 matched an existing Bookhive record — of those, 2 are marked wantToRead in Bookhive despite being finished in the vault (On the Calculation of Volume I, Self Editing for Fiction Writers). ~75 have no Bookhive record at all — notably the Steven Saylor Roma Sub Rosa series, Blackwater series, several Star Trek novels, Stephen King titles, the Cixin Liu trilogy, and a batch of Italian-language books (these are likely missing from Bookhive’s catalog/Goodreads matching, or just weren’t in the import). Adding a missing book to Bookhive isn’t a single write — for each one I’d need to search Bookhive’s catalog for a matching hiveId (their internal book-catalog ID), then write a record to your PDS repo referencing it. That’s ~75 catalog lookups plus writes, and some (Italian titles, small press) may not exist in their catalog at all and would need to be skipped or reported.

It was promising. I did a couple of manual checks and then I gave it the green light. Ten minutes later, all my books’ data were synchronized and fixed.

It was a revealing experience. Note that I didn’t have to specify anything: no BookHive API, no structure of BookHive’s lexicon, nothing. The full prompt was:

Can you log in to my PDS (did:plc:w2wvugwwbehm7v774fkgagfl) and update the read book of Bookhive according to my Obsidian book vault?

That’s it. In an era of powerful agents, atproto applications give me a universal API to interact with my data. I think we are only scratching the surface of how awesome this is.


  1. I am not migrating away from StoryGraph. I just wanted to participate in BookHive as a “mirror” of my data in the ATmosphere↩︎

  2. The Personal Data Server, that is, where the data of atproto applications is stored. In my case, on EuroSky↩︎

GitHub Icon BYTE • PERSONAL

The Great 2026 Blog Renovation

One of my projects for summer vacation was to completely overhaul the theme of this blog. The last time I changed the theme was in 2023, when I removed all third party CSS frameworks from the codebase, but I was never satisfied with the result. I learned a lot in the process, but my relative lack of experience with modern CSS forced me to use a very simple design.

While the body of the articles was great (and it still is, as it is almost untouched), the home was just a thin, long list of articles in order. However, this website is my home, my Internet-facing business card. A list of articles in chronological order was not the best way to showcase all I do and all I like.

That’s why I dreamed of something richer.

Now that I am better at CSS and we have better tools that help me debug, for instance, why the damn z-index property doesn’t do what it is supposed to do, I felt more confident in my ability to create something more complex. And so this is how I spent my first week of summer vacation.

After sketching different designs, I opted for a magazine-like layout. The last blog article still stands out as a prominent element, but now I have space for more. First, I added a section showing the last articles by topic (I picked four main topics among everything I talk about). Then, there is a more compact section showing the last articles in chronological order.

Most importantly, I added a sidebar for all the rest: a “widget” showing a summary of my /now page, a list of these small bytes/notes articles, a way to subscribe to The ChangeLog, and a list of projects.

Moreover, there are more silly features, such as a way to change color scheme (as I could not decide on one no matter how much I tried) and, finally, a way to search for articles (it is a bit of a hack, given the lack of a backend, but it works).

Everything is still in flux. I will probably shift many things in the coming weeks/months but, overall, I am quite satisfied with the result. Let me know what you think!

In the coming months I plan some more features, more polishing and, why not, Standard Site integration. Stay tuned!

GitHub Icon BYTE • ARTIFICIAL INTELLIGENCE

The Problem With Measuring AI Productivity

Every time I read about some study measuring the productivity gain of AI-assisted development, I raise an eyebrow. I find them uninteresting and useful only for the online fights between “there is no AI productivity for software developers” and “Claude Code increased my productivity by a billion percent.” The problem is that the landscape is so varied that, honestly, you can stress the data to prove both assertions.

My personal opinion is that many papers on the subject are just messy, and often they do not test at all how people using AI efficiently for work are actually using it. There are many issues I identified: they give too-easy problems, they impose arbitrary time constraints, they give problems to people not familiar with the framework they have to use (a big no no), and, surprisingly, I still see a lot of studies where the test subjects use “copy-pasting code from the web chat interface back and forth.” That is a way to work with AI that I think every developer stopped using in 2024.

But setting this aside, my main problem is that they never measure a specific class of task: the tasks that I would not have even started without AI assistants. We can discuss “this AI agent increases productivity by 2%” or “5%” or “20%” for as long as we want, but the reality is that many software and features I made in the last year would not exist at all without AI agents. I have folders with a sea of tools, automations, and single-use scripts that I would have never started.

So how could I measure that? For me, that is an increase of infinite percent, because they didn’t help me complete a project faster; they are the reason some projects exist. In some sense, it is a kind of Pascal’s wager. How should I redact the claim “AI agents improve developer output by only 2%” when I have concrete evidence on my hard drive of things that would have remained annotated in my notebook for all eternity?

Maybe it is my ADHD talking. Probably other people function differently and can do everything by just deciding to. But for me, lowering the activation moat that blocks me from starting to work on something is 100% worth it, even if I end up doing 80% of the work by hand.

It is a personal thing. I know that. I also understand if you work differently. And that’s the point. I saw developers using these tools in wildly different ways, for very different purposes, and with very different outcomes, and I don’t think it’s possible or fair to reduce that to a universal percentage number in some random study.

GitHub Icon BYTE • PERSONAL

Why I Quit Mastodon in 2026

I vented my concerns on Mastodon before. Multiple times. But I was moderately optimistic.

Now, after years, I have to say that little changed. Almost all the technical issues are still there, but they never were my main concern. What bothered me was Mastodon’s sociology and the “instances” dynamic.

A lot of people are unrelentingly annoying. Having a Ph.D. in Artificial Intelligence (even if video game–related) was often enough to have people scolding me for no reason. But even that I could tolerate.

But then there are the instances and their admins: feudal castles ruled by feudal lords, fighting or allying with each other, enacting arbitrary rules even more arbitrarily enforced.

The other day, mastodon.social deleted a post by a guy I know because it criticized (legitimately, and by stating factual truths) another instance. Recently, another instance added a rule prohibiting talking badly about other instances. They said it is to protect the quality of the Fediverse. That’s funny, because I constantly get false and deranged posts on the Explore tab, and I don’t think that criticizing an instance admin is the problem with Mastodon’s quality.

In any case, that’s the last straw. I refuse to be part of such infantile power play.

Mastodon’s problem is not a technology issue; it is a people issue.

P.S. This is not about the Fediverse as a whole or ActivityPub

I just want to say that this is a Mastodon-specific issue. The ActivityPub protocol is, obviously, not responsible for this. Probably other services of the Fediverse (Lemmy, Pixelfed, etc.) have the same problems. I don’t know. It didn’t look that way to me, but maybe it is just because they are small in comparison.

And, of course, there are exceptions. There are instances and admins that genuinely care about Mastodon’s mission. I know them. It is a shame they have to be affected by this state of affairs.

But I am too old for this. I have little time for things that are no longer interesting or fun.

GitHub Icon BYTE • PROGRAMMING

The Golden Rule of Using AI Agents

As with many, I played around with AI agents in code. Contrary to some opinions, AI agents made me rediscover the joy of coding (for many reasons I may discuss another time). However, I am not blind, and I owe my satisfaction with AI agents to a strict mental model and practice.

If you are not a software developer and you use AI to jam together personal scripts for yourself, do not worry, you can do as you want. If you are using them to learn something, don’t worry either.

But if you are a professional coder or you want to publish your work, you have to follow the Golden Rule:

You must use an AI Agent only to do what you know how to do.

Only in this way can you be efficient with them. Only if you know how to do something can you instantly spot when the agent is doing something decent or not. Only if you know how to do something can you recognize whether the generated code is good.

This doesn’t make them less useful. I like to code algorithms, solve problems, and sketch the architecture of the various elements. So I focus on that while I let the robot work on things I loathe. Things like CLI interfaces, reporting, writing diagnostic endpoints, and other tasks I find super boring. I know how to do them; they are just boring. So I let the robot do them while I focus on the math and the algorithms.

However, be careful. The siren’s song is strong. If you are not disciplined, you may think, Why not? Why should I not use the robot for this thing I don’t know how to do?

And that’s the moment you open yourself to fatal mistakes.

GitHub Icon BYTE • WORKFLOW

Movie Posters Grid in Obsidian With Dataview

With the upcoming Bases update in Obsidian, this may become obsolete, but for the time being I am still quite happy using Dataview to embed little graphical elements in my notes.

For example, I have a note summarizing all the movies I watched each month. For that I use a combination of CSS and a Dataview query to generate a grid of movie posters. Until recently I used a very simple Dataview query, but I had a problem: if I watched a movie twice in a month, I got only one entry in my poster grid. This is not what I wanted, so I had to do something more complicated.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const results = [];
const from = dv.date("2025-07-27");
const to = dv.date("2025-08-28");

for (const page of dv.pages('"03 - Literature/Movies"')) {
    const watched = page.Watched;
    if (!watched) continue;

    // Handle both single dates and arrays of dates
    const watchedDates = Array.isArray(watched) ? watched : [watched];

    // Add an entry for each watch date that falls within the range
    for (const date of watchedDates) {
        const watchedDate = dv.date(date);
        if (watchedDate &&
            watchedDate < to &&
            watchedDate > from) {
            results.push({
                poster: page.Poster,
                date: watchedDate
            });
        }
    }
}

// Sort by date descending and display just the posters
dv.list(
    results
        .sort((a, b) => b.date.ts - a.date.ts)
        .map(item => item.poster)
);

So in short, I have a Watched property on my movie notes that can take multiple values, and for each date in the property I add a “poster” entry to the results array. Finally, I sort the results by date descending and display the posters.

Problem solved.

(Btw, let me know if you want the CSS for the grid.)