Skip to content
Tech briefing

Tech briefing

Today’s tech news, read aloud in ten minutes. Every morning at 06:00 a small Java app collects the most important news on AI and software engineering and publishes it as a private podcast and a page I can skim on my phone.

What it is

I follow about 20 sources: newsletters, research blogs, arXiv, Hacker News, Lobsters and engineering blogs from Anthropic, Netflix, GitHub and others. That is too much to read every day, but too important to skip.

Tech briefing reads all of it for me, picks the most important items and makes two things from the same content:

  • An MP3 episode in a private podcast feed. It lands in my podcast app and plays in the car through CarPlay.
  • A written digest as static HTML. It can be added to the phone’s home screen as a PWA and read offline.

Intent

  • Short and predictable. An episode is about 1,450 words, roughly ten minutes. Headlines first, then AI and machine learning, then software engineering. I can stop at any point without missing the most important part.
  • The model never writes links. Every article has an id. The model refers to ids, and the app inserts the stored links itself. A made-up link therefore cannot end up in the digest.
  • Always a direct link. Every story links to the article itself and to the discussion, if there is one.
  • Static files, no web app. The content changes once a day and is the same for everyone. The app writes the files to disk, and Nginx serves them to both the podcast app and the PWA.
  • Cheap to run. One call a day to a small model, estimated at under two dollars a month. The speech is free.

How it works

  1. Fetch. The app fetches every feed and stores new articles in PostgreSQL. The same article from several sources becomes one item, also when the URL is spelled differently.
  2. Select. Each source has its own rules in a YAML file: minimum points, maximum number of articles, or keywords. An episode has at most 14 stories, and whatever is left out gets another chance the next day.
  3. Summarize. One call to Claude Haiku writes the headlines and a short brief for each story. The answer is structured, and tokens and cost are logged for every episode.
  4. Publish. The app writes the day’s page, the archive and the podcast feed. The feed has timecodes, so I can jump straight to a story.
  5. Speak. The script is sent in chunks to a small speech service, and the app joins the MP3 pieces itself, without ffmpeg. Code and tables are replaced with a short remark, so the reading is easy to follow.
  6. Clean up. MP3 files are deleted after 30 days. The text stays in the archive.

Some posts are too good to shorten. A rule per source can therefore say that a post is read in full. Martin Fowler’s “Fragments” posts are one example.

If the speech fails, the text is still published, and the audio can be made later. Only the missing chunks are requested again.

Tech stack

App

  • Java 25 · Spring Boot 4 · Maven · scheduled with Spring @Scheduled
  • PostgreSQL 18 with Flyway · JdbcClient, no JPA
  • ROME for feeds · jsoup for article text · Thymeleaf for the static pages
  • Anthropic API with the official Java SDK and a structured answer

Speech

  • Python with edge-tts as a small HTTP service

Publishing

  • Nginx serves the static files
  • RSS 2.0 with iTunes tags and timecodes · PWA with a manifest and a service worker

Operations

  • Development in Docker Compose with a devcontainer: app, speech, PostgreSQL and Nginx
  • Production without Docker: the jar and the speech service under systemd on a Hetzner server, set up with Ansible
  • Build and deploy with GitHub Actions
Last updated on