AGENTS.md

Project purpose

Lex TL;DR is a small Jekyll blog that publishes concise, readable summaries of long-form podcast episodes. The initial focus is the Lex Fridman Podcast; the information architecture must remain able to add other popular podcasters later.

Keep public copy centered on this purpose. Avoid generic positioning such as a journal about ideas, making, or multiple forms unless it directly explains podcast summaries. The homepage should make three points clear:

  1. The site summarizes long podcast conversations.
  2. Lex Fridman is the first podcaster covered.
  3. Other podcasters may be added later.

The production repository is allenlsy/lex-tldr, and GitHub Pages serves it at https://lextldr.com/.

Architecture

The repository also contains SSSF automation under adws/ and related recipes in justfile. The new-post recipe is the blog-specific exception. Keep other blog work independent from SSSF unless the task explicitly concerns that machinery.

Homepage pagination operates on logical episodes after grouping variants by article_id, never on individual language or spec variants. It offers 20 and 50 episodes per page, with 20 as the default. _data/summary_page_sizes.yml defines the choices, and _data/summary_pages.yml defines their static routes. When the episode count outgrows one of those route sets, add its next page file with the matching summary_page and summary_page_size front matter.

Keep indexable pages self-canonical. Podcast summary variants must emit reciprocal hreflang links, using valid BCP 47 language tags (en and zh-CN) and the English variant as x-default when available. Search is noindex,follow and excluded from the sitemap. Do not add fabricated authors, ratings, images, or other structured data that the page does not substantiate.

Summary and variant model

Treat one podcast episode as one logical article. Every published variant of that summary must share:

Each variant also has:

Language display names live in _data/languages.yml. Templates must use the shared language-label include so every number of variants is supported and known languages show their native names.

When language is the only distinction, omit spec and end the URL after the language:

language: en
variant_rank: 1
permalink: /articles/example-episode/en/

When spec is present, preserve its order and join the values with - in the final URL segment:

language: en
spec:
  - short
  - audio
variant_rank: 2
permalink: /articles/example-episode/en/short-audio/

Most imported summaries have two variants, en and cn. Episode 440 intentionally has four variants because two distinct source summary sets were imported as ordered short and long specs. Templates must support any number of variants and render cleanly when spec is absent.

Local summary conversion

Content batch tooling lives in the admin/ git submodule (separate repository allenlsy/lex-tldr-admin; fetch it with git submodule update --init after a fresh checkout). The tools resolve the blog root from their own location, so run them from this repository. The just new-post recipe uses scripts/new_post.rb inside this repository and needs no submodule.

admin/convert_pending.py converts pending summary files into Jekyll posts. Place summaries in pending/<collection_id>/ (e.g. pending/lex-fridman/), preview with a dry run, then apply:

python3 admin/convert_pending.py
python3 admin/convert_pending.py --apply

The script derives the episode id, title, and language from the file name and content. The episode number comes from the heading, then the verified video metadata table (VIDEOS), then a live lookup against https://lexfridman.com/podcast (title match plus the YouTube page title), and finally an interactive prompt when nothing else resolves it; the number drives title, article_id, article_title, and permalink. It must remain dry-run by default, must never overwrite a different destination file, and moves converted sources to pending/processed/. Excerpts use the first substantive paragraph of the post body. Chinese variant titles are translated from the shared article_title through an OpenAI-compatible endpoint (default http://127.0.0.1:8000/v1, model Qwen3.6-35B-A3B-MLX-4bit). To regenerate metadata (fill missing excerpts, translate titles) for a date range:

python3 admin/convert_metadata.py --start 2026-08-01 --end 2026-08-31
python3 admin/convert_metadata.py --start 2026-08-01 --end 2026-08-31 --apply

Podcaster collections

Collections represent podcasters in the visible interface. Add a collection entry to _data/collections.yml, add a front-matter-only landing page under collections/ that uses the shared _layouts/collection.html layout, and give all related summary variants the same collection_id. The layout derives the collection number from the _data/collections.yml order.

The first collection is displayed as Lex Fridman Podcast and uses the internal ID lex-fridman. Its /collections/practice-notes/ route is a legacy public URL; preserve that route unless a task includes a deliberate URL migration and compatibility plan.

Public copy and design

Local commands

Install dependencies once:

bundle install

Run the regression test:

sh tests/collection_links_test.sh

Build the production site:

bundle exec jekyll build

Preview locally:

bundle exec jekyll serve

List the existing project recipes:

just --list

Create a language-only podcast summary:

just new-post "EPISODE TITLE" en

Preview and convert the pending Lex Fridman summaries:

python3 admin/convert_pending.py
python3 admin/convert_pending.py --apply

The recipe derives the episode ID and URL slug from the title, assigns the next variant rank, and rejects duplicate episode-language variants. Authors must replace the generated placeholder body before publication.

Change workflow

  1. Inspect git status before editing. Preserve unrelated user changes.
  2. For behavior changes, add or update a regression test and observe the intended failure before implementation.
  3. Make the smallest coherent change.
  4. Run sh tests/collection_links_test.sh and bundle exec jekyll build.
  5. Run git diff --check and review the rendered paths or HTML relevant to the change.
  6. Stage only intended files. Do not use broad staging when unrelated files exist.
  7. Commit and push only when the user requests publication.

Pushing main triggers GitHub Pages. After publishing, verify the Pages workflow succeeds and confirm the changed routes at https://lextldr.com/.

Repository hygiene