Skip to content

Blog post notes: reviewing ytx, NativeAOT and v1.0.8 #7

Open

Description

@solrevdev

Blog post notes

Raw material for a future solrevdev.com post about reviewing, testing and speeding up ytx. This is not the post. It collects what the post needs in one place, so nothing depends on local scratch files that will be deleted.

Status: v1.0.8 is released on GitHub. PR #6 (NativeAOT) is an open draft. The caption bugs in #3 are still open.

Rule for the post: do not publish captured YouTube caption text. Use titles, video IDs, byte counts, exit codes and timings only.

Links

What Link
Repo https://github.com/solrevdev/solrevdev.ytx
Issue #3: review of v1.0.7, bugs and competitors #3
Issue #4: NativeAOT and allocations, findings and plan #4
PR #5: source-gen JSON, streamed output, fewer allocations (merged) #5
PR #6: NativeAOT builds, benchmarks, packaging (draft) #6
v1.0.8 release https://github.com/solrevdev/solrevdev.ytx/releases/tag/v1.0.8
v1.0.7...v1.0.8 diff v1.0.7...v1.0.8
NuGet package https://www.nuget.org/packages/solrevdev.ytx
Investigation write-up (PR #6 branch) https://github.com/solrevdev/solrevdev.ytx/blob/feat/native-aot/docs/investigations/2026-10-native-aot-and-allocations.md
Benchmark project README https://github.com/solrevdev/solrevdev.ytx/blob/feat/native-aot/benchmarks/Ytx.Benchmarks/README.md
AOT scripts README https://github.com/solrevdev/solrevdev.ytx/blob/feat/native-aot/scripts/aot/README.md
Packaging templates README https://github.com/solrevdev/solrevdev.ytx/blob/feat/native-aot/packaging/README.md
native.yml first run, 5 platforms green https://github.com/solrevdev/solrevdev.ytx/actions/runs/37830351761
native.yml run after retarget to master, 5 platforms green https://github.com/solrevdev/solrevdev.ytx/actions/runs/37832924672
publish.yml run that released v1.0.8 https://github.com/solrevdev/solrevdev.ytx/actions/runs/37831516382
PR #5 validate run https://github.com/solrevdev/solrevdev.ytx/actions/runs/37828767791
Earlier post: building ytx (27 Oct 2025) https://solrevdev.com/2025/10/27/building-ytx-a-youtube-transcript-extractor-as-a-dotnet-global-tool.html
Related post: bbx ("test the exit code") https://solrevdev.com/2026/08/03/building-bbx-a-bitbucket-cloud-cli-as-a-dotnet-global-tool.html
Related post: orchat ("trimming warnings are not noise") https://solrevdev.com/2026/08/04/building-orchat-a-single-file-dotnet-client-for-openrouter.html
Related post: .NET tools and roll-forward https://solrevdev.com/2026/08/11/dotnet-tools-roll-forward-major-version.html

The hook

The October 2025 post that introduced ytx published this caption ordering and listed it under "Key Learnings" as "Intelligent Caption Selection":

.OrderByDescending(t => t.Language.Name.Contains("English", StringComparison.OrdinalIgnoreCase))
.ThenByDescending(t => t.IsAutoGenerated)

A year later the review found that this exact line is bug 1. It ranks auto-generated tracks above human-written ones. The Contains match is the root of bug 2. That is an honest and strong opening for the follow-up.

Timeline (8 Oct 2026)

Times are UTC. Add one hour for UK time (BST).

Time What happened
17:52 Asked Claude Code to grab the transcript of a SaaS-idea video (aCi6BhrvjhM) with "ytx or yt_json". It chose ytx and saved transcript.json and transcript.md.
17:54–18:02 Downloaded the PRD the video links to, built a small project folder with a README, committed it and moved it into a projects folder.
18:03 Asked which tool it used. Answer: ytx, because it is one installed tool. yt_json chains yt-dlp, jq and uvx.
18:04 "ytx is my tool. What do you think of it?" Three agents start in parallel: source review, live testing, competitor survey.
18:05–18:11 Source review done in about 1.5 min. Survey in about 2 min. Live testing in about 7 min.
18:17 Asked for one issue with everything, plus a separate look at NativeAOT and allocations. Two more agents start: AOT prototype and allocation profiling.
18:19 Issue #3 opened (review).
18:32 Allocation profiling done (about 14.5 min).
18:37 AOT prototype done (about 19.5 min).
18:38 Issue #4 opened (AOT and allocations).
18:54 Asked for branches: the JSON fix as a PR, and AOT as an extendable branch. Two agents start.
18:55 Follow-up comment on #3 pointing to #4.
19:01 PR #5 opened. Agent took about 7.5 min.
19:13 PR #6 opened as a draft, stacked on #5. Agent took about 16.5 min. Status comment on #4 with the exit code correction.
19:13–19:17 First native.yml run on #6: all 5 platforms built and smoke-tested.
19:22 Asked to merge #5. Merged with a merge commit (5 commits kept) and --delete-branch.
19:22:59 PR #6 closed automatically, because its base branch was deleted.
19:23 publish.yml released v1.0.8 to GitHub Releases and pushed to NuGet.
19:34 Restored perf/source-gen-json from its last SHA, reopened #6, retargeted it to master, deleted the branch again.
19:34–19:37 native.yml ran again on #6 against master. All 5 platforms green.
19:34 Two more agents start: one scopes the #3 fixes and their order, one gathers blog material (these notes).
19:36 NuGet still listed 1.0.7 as latest. The installed global tool was still 1.0.7.

From "grab a transcript" to a released performance fix took about 1 hour 30 minutes.

Key numbers

From the review (#3)

  • Tests at v1.0.7: 26 passing. After PR perf: source-generated JSON, streamed output and fewer allocations #5: 70 passing.
  • ytx vs yt_json: 1.3–1.6 s against 3.1–4.9 s for a typical video. 5h15m podcast: about 2.2 s against 7.2 s.
  • Random slow calls: about 1 in 8 calls took about 11.5 s instead of about 1.5 s. One took 21.7 s.
  • Long output: the 5h15m video gives 1.1 MB of JSON. transcript is about 2.9x the size of transcriptRaw.
  • Wrong track: Lex Fridman #501 gave 8,144 auto-caption lines from ytx against 4,773 manual lines from yt_json.

NativeAOT (#4, net10.0, osx-arm64, Apple M1)

Build Binary / archive --version Full run CPU Peak RSS (full run)
Installed tool shim 1.0.7 runtime + 1.3 MB 38.0 ms 416 ms 132 MB
Self-contained, trimmed + R2R 35.1 / 13.7 MB 27.4 ms 208 ms 97 MB
NativeAOT 10.3 / 4.6 MB 8.6 ms 73 ms 61 MB
  • Headline: startup 38 ms to 8.6 ms. About 6x less CPU per call. Half the memory. No .NET runtime.
  • Instructions retired on --metadata-only: 2.54 billion (framework-dependent) against 0.47 billion (AOT).
  • Hybrid RID-specific tool package (.NET 10): --version in 7.3 ms against 33.5 ms for the shim. Breaks installs on SDK 8.
  • Worst build: trimmed self-contained without R2R. 51.9 ms startup and 589 ms CPU.
  • Linux arm64 AOT: 11.5 MB plus an 18 MB .dbg. Needs libssl3t64 and ca-certificates. Built on noble, it needs GLIBC 2.34.

Allocations (#4)

  • Where time goes on the 5h video: 2.1–2.2 s and 186 MB in total. ytx's own code is 28 ms + 15 ms and 7.9 MB + 26.3 MB.
  • Share: ytx is about 2% of run time and about 18% of allocations. The rest is network and YoutubeExplode.
  • NormalizeCaption over 16k captions: 754,614 B to 904 B, 3,408 µs to 581 µs.
  • Format, serialise, write (5h, BenchmarkDotNet): 7,947 µs / 10.5 MB (v1.0.7) to 3,974 µs / 4.5 MB (Tier 1) to 3,440 µs / 58 KB (Tier 2).
  • Cold single run, 5h data, no network: 42–43 ms / 34.2 MB (v1.0.7) to 23 ms / 28.5 MB (Tier 1 + source-gen) to 20 ms / 5.3 MB (Tier 2).
  • Verdict: Tier 1 is about 30 lines and worth it. Tier 2 is about 150 lines for 3 ms more. Vanity.

PR #5 byte checks

Built master and the branch, ran both on net8.0 and net10.0, compared with cmp. All identical:

Case Bytes
default 66,092
--compact 66,071
--metadata-only 1,779
stdin {"url":...} 66,124
stdin {"URL":...} with --compact 66,071

Error paths (invalid JSON, JSON array, {}, invalid ID) gave the same stderr and exit 2.

CI evidence

Run Jobs Result
native.yml, 37830351761 osx-arm64, osx-x64, linux-x64, linux-arm64, win-x64 builds, plus osx-x64 smoke test on macos-15-intel All green. Release step skipped (no tag). About 3 min.
native.yml, 37832924672 Same, after retarget to master All green
publish.yml, 37831516382 publish Green. Released v1.0.8 in 38 s

No CI binary has been run against YouTube.

v1.0.7 vs v1.0.8 measured on the released package

Both versions were installed from NuGet: 1.0.7 into a separate tool path, 1.0.8 as the global tool. Framework-dependent, macOS osx-arm64, interleaved runs, medians shown.

Case Runs 1.0.7 wall / CPU (ms) 1.0.8 wall / CPU (ms)
--version 20 35 / 32 35 / 31
stdin JSON path (invalid ID, no network) 20 53 / 50 47 / 44
--metadata-only 8 1037 / 337 988 / 325
Full run, 17 min video 8 1661 / 454 1613 / 469
Full run, 5h15m video 6 2246 / 889 2079 / 812

What this shows:

Suggested measurements: ytx --version startup (30 runs), stdin JSON path, a full run on aCi6BhrvjhM (8 round-robin rounds, compare medians and CPU), cold 5h run, and a cmp of both versions' output. NuGet had not listed 1.0.8 at 19:36 UTC, 13 minutes after the release.

Live test matrix (v1.0.7, macOS osx-arm64)

89 recorded runs from a small harness (run.sh), covering about 40 behaviours. Each run saved stdout and stderr and logged exit code, wall time, byte count and whether stdout was valid JSON. Main test video: aCi6BhrvjhM (17 min, auto captions). Language tests: TED talk iG9CE55wbtY, which has many tracks including manual English.

Area Cases Exit Time Result
URL forms watch URL, bare ID, youtu.be (with ?si=&t=), &t=&list=&index=, /embed/, music., m., /live/, no scheme, -u 0 1.0–1.8 s (first run 4.6 s) Correct, about 66 KB JSON each
Shorts real short, normal video via /shorts/, no www 0 1.0–1.5 s, some 11.5 s Correct. The 11.5 s runs were the general slow-call issue
Repeat runs 3 shorts + 3 watch URLs alternated 0 3 of 6 took 3.5–11.5 s Slow calls hit any URL form
stdin {"url":...}, with -c 0 1.5 s Works
stdin plain ID, not JSON 2 fast Raw System.Text.Json error text
stdin wrong key, empty 2 fast "A YouTube URL or video ID is required."
stdin extra keys, stdin plus positional 0 Extra keys ignored, positional wins, no warning
Output modes --metadata-only, -c, both with -l fr 0 1.0–1.4 s Correct. -l with metadata-only accepted silently
Language, correct French, french, de, it, ar, ko, fr-CA, zh-TW, Chinese 0 1.3–3 s, Chinese once 21.7 s Correct track
Language, wrong -l fr, -l es, -l ja 0 about 1.4 s Afrikaans, Chinese and Azerbaijani. Exact tracks existed
Language, silent fallback -l pt, -l zh, -l xx, -l Klingon 0 about 1.5 s English, no warning
Default track TED, Lex #501 0 Auto-generated chosen over manual English
-l misuse -l '', -l with no value 2 0.05 s "Option '-l' requires a value."
No captions real short, two live streams, upcoming premiere 0 1.2–1.6 s Placeholder text inside transcript, exit 0
Past livestream x6p9Ri0DlNE 0 2.0 s 454 KB, works
Long video Lex #501 NYFGCESmikA, 5h15m, 4 runs 0 2.1–2.3 s, once 12.3 s 1.1 MB, timestamps up to 05:15:39
Unavailable deleted ID, private video 1 0.4 s "Video '...' is not available."
Invalid input junk string, non-YouTube host, 3 and 14 char IDs, playlist URL, channel URL 2 0.05 s "... is not a valid YouTube URL or video ID."
Parser unknown flag, two positionals, -u plus positional, --help --foo 2 0.05 s Clear message and a --help hint
IDs starting with - -lsFs2615gw bare, after --, after -u 2 / 0 / 0 Works with -- or -u. Help does not say so
Piping ytx ... | jq, | head 0 No BOM, trailing newline, nothing on stderr, no broken-pipe error
yt_json comparison 4 videos, both tools 0 ytx 1.3–2.2 s, yt_json 3.1–7.2 s Byte-identical on 2 of 4. Different on TED and Lex because of the default-track bug

The harness, for the post:

#!/bin/zsh
# usage: run.sh name args...
D=./ytx-test
n=$1; shift
s=$(perl -MTime::HiRes=time -e 'printf "%.3f", time')
~/.dotnet/tools/ytx "$@" > $D/$n.out 2> $D/$n.err
rc=$?
e=$(perl -MTime::HiRes=time -e 'printf "%.3f", time')
t=$(echo "$e - $s" | bc)
valid=$(jq -e . $D/$n.out >/dev/null 2>&1 && echo json || echo notjson)
echo "$n rc=$rc t=${t}s out=$(wc -c < $D/$n.out)B $valid err=$(head -c 300 $D/$n.err | tr '\n' ' ')"

The process: which agents did what

All work ran in one Claude Code session. The main session planned, delegated, merged results and wrote to GitHub. Background agents did the heavy work, mostly in parallel, each on its own fresh clone in a scratch folder.

Agent Started (UTC) Took Output
Review ytx source code 18:04 ~1.5 min Found the ThenByDescending and Contains bugs by reading Program.cs
Hands-on test ytx CLI 18:04 ~7 min The 89-run live matrix above, and the yt_json comparison
Survey YouTube transcript tools 18:04 ~2 min Competitor table with stars and downloads from gh, NuGet, npm and PyPI
Prototype NativeAOT build 18:18 ~19.5 min Six deployment shapes, startup, network and memory numbers, Linux in Docker, the RID tool experiment
Profile allocations and hot paths 18:18 ~14.5 min Phase instrumentation, BenchmarkDotNet project, Tier 1 and Tier 2 variants with a byte-for-byte verify harness
Branch and PR for JSON perf fix 18:55 ~7.5 min PR #5 with golden-output tests
Prepare AOT branch content 18:55 ~16.5 min PR #6 contents: write-up, scripts, benchmark project, native.yml, packaging templates
Scope issue #3 fixes 19:34 running Fix order for #3, a track-selection prototype, YoutubeExplode 6.6.2 with AOT
Audit blog-post material 19:34 running These notes

Points worth making in the post:

Mistakes and corrections

  1. The AOT --metadata-only exit code. Issue NativeAOT builds and allocation work: findings and plan #4 said the unfixed AOT build exited 0 on --metadata-only. A re-run showed it exits 1 with the reflection error and nothing on stdout. Corrected in a comment on NativeAOT builds and allocation work: findings and plan #4 and in the write-up. Lesson: re-run a surprising result before publishing it.
  2. PR feat: NativeAOT builds, benchmarks and packaging #6 was closed by deleting its base branch. feat: NativeAOT builds, benchmarks and packaging #6 was stacked on perf: source-generated JSON, streamed output and fewer allocations #5's branch. Merging perf: source-generated JSON, streamed output and fewer allocations #5 with --delete-branch deleted that branch, and GitHub closed feat: NativeAOT builds, benchmarks and packaging #6 three seconds later. The fix: recreate the branch ref from its last commit (223924a) with gh api, reopen feat: NativeAOT builds, benchmarks and packaging #6, retarget it to master, then delete the branch again. Lesson: retarget stacked PRs before deleting the base branch.
  3. Windows newlines. The Tier 1 sketch in NativeAOT builds and allocation work: findings and plan #4 used '\n'. PR perf: source-generated JSON, streamed output and fewer allocations #5 kept Environment.NewLine, so Windows output is unchanged. Noted on NativeAOT builds and allocation work: findings and plan #4.
  4. The 2025 post's "intelligent" ordering. The code praised in the original post is bug 1. Worth owning in the post.
  5. NuGet lag. NuGet accepted the push at 19:23 UTC. The flat container listed 1.0.8 at about 19:50, but dotnet tool update -g kept installing 1.0.7. Asking for --version 1.0.8 failed with "not found in NuGet feeds" for several more minutes. Lesson: the package page, the flat container and the install index update at different times.
  6. Startup numbers drift. A later re-run measured AOT at 7.3 ms and framework-dependent --help at 33.4 ms, against 8.6 ms and 38 ms earlier. The ratio held. Say so if quoting milliseconds.
  7. Benchmarks are warm, CLIs are cold. BenchmarkDotNet showed Tier 1 halving the cost. Cold single runs were needed to show the real 20 ms. Worth a short paragraph.

Competitor table (from #3, 8 Oct 2026)

Tool Size Strength Weakness
youtube-transcript-api (Python) 8.4k stars, ~15.8M PyPI downloads a month De facto standard, many formats, proxies No metadata
yt-dlp (Python) ~196k stars Fullest metadata, best anti-blocking No clean transcript text
YoutubeExplode (.NET) 3.7k stars ytx's base A library, not a CLI
Fabric (Go) 44k stars fabric -y with transcript and metadata Large framework
jkawamoto/mcp-youtube-transcript 487 stars Transcript, metadata, chunking MCP only
kimtaeyoon83/mcp-server-youtube-transcript 600 stars Language fallback MCP only
zemse/yt (Rust) new JSON for agents Few users
steipete/summarize 6.7k stars Whisper fallback Built for summaries
Hosted APIs, browser extensions Work from cloud IPs or a signed-in browser Paid, or not scriptable

Name clash: koguchic/ytx is a different Rust CLI installed as ytx-cli. Relevant for a Homebrew formula name.

Quotes and one-liners

  • "ytx's own code is about 2% of run time."
  • "A real call is about 90% network."
  • "A person running ytx once won't notice. Agents and batch jobs that run it many times will."
  • "Two bugs can silently return the wrong transcript, with exit 0 and nothing on stderr."
  • "fr matches Afrikaans, es matches Chinese, ja matches Azerbaijani."
  • "The bigger wins for users are not in this document."
  • "Tier 2 cuts allocations by 99% and saves 3 ms. Vanity."
  • "The unmodified AOT binary fetched from YouTube, then failed when writing the JSON."
  • Callback to bbx: "Test the exit code." Callback to orchat: "Trimming warnings are not noise."

Suggested titles

  1. Reviewing ytx a Year Later: Wrong Transcripts, NativeAOT and the 2% That Was Ours
  2. What Happened When I Asked Claude Code to Review My Own .NET Tool
  3. ytx v1.0.8: Source-Generated JSON, NativeAOT and Knowing When to Stop Optimising
  4. 38 ms to 8.6 ms: NativeAOT for a .NET Global Tool, and Why Allocations Did Not Matter
  5. Five Agents, Four Issues and PRs, One Release: Reviewing ytx

Suggested front matter

---
published: false
layout: post
title: <pick from above>
description: <one sentence for SEO>
summary: <one or two sentences for the home page>
cover_image: /images/ytx-review-aot-cover.svg
image: /images/ytx-review-aot-cover.png
tags:
- dotnet-global-tools
- dotnet
- dotnet-10
- csharp
- native-aot
- performance
- benchmarkdotnet
- system-text-json
- youtube
- transcripts
- claude-code
- ai-agents
- github-actions
- nuget
---

Suggested outline (house style)

Bold title-case headings with one emoji each, as in the bbx, orchat and roll-forward posts. Target 3,000–4,500 words. Close with "Success! 🎉".

  1. Overview ☀: grabbed a transcript for a SaaS-idea video, asked "what do you think of it?", ended with a release and a draft AOT PR in 90 minutes. Link the 2025 post.
  2. The Line I Called Intelligent 🎯: the ThenByDescending(t => t.IsAutoGenerated) callback.
  3. How the Review Was Run 🤖: the agent table, parallel timing, fresh clones.
  4. Testing Against Live YouTube 🧪: the harness and a trimmed matrix. Avoid caption text.
  5. The Two Bugs That Exit 0 🐛: default track and Contains matching, the fr/es/ja table, silent fallback.
  6. ytx Against the Competition 📊: short table and the niche ytx fills.
  7. Is NativeAOT Worth It? ⚡: the IL2026 and IL3050 warnings, the runtime failure, the 10-line fix, the build-shape table.
  8. Where the Time Actually Goes 🔍: the 2% finding, phase table.
  9. Warm Benchmarks, Cold CLIs 🧊: BenchmarkDotNet vs single-run numbers, Tier 1 vs Tier 2.
  10. Shipping v1.0.8 📦: PR perf: source-generated JSON, streamed output and fewer allocations #5, golden-output tests, byte checks, auto-release, NuGet lag. Then v1.0.7 vs v1.0.8 on the released package: the same for one run, 6 ms on the JSON path.
  11. The Mistakes 🧨: exit code correction, the auto-closed stacked PR, NuGet lag.
  12. The AOT Branch 🏗️: native.yml matrix, 5 green platforms, Homebrew and Scoop templates, the SDK 8 trap with RID tool packages.
  13. What I Took Away 💡: numbered list.
  14. What Is Next 🔮: the order chosen below.

A two-post split also works: "What a review of ytx found" and "NativeAOT and allocations in a .NET global tool". The roll-forward post shows single-topic posts work well too.

Diagrams to draw

  1. Session swimlane: main session plus agents on a time axis from 17:52 to 19:37, with GitHub events (Review of v1.0.7: caption track bugs, gaps and comparison with other tools #3, NativeAOT builds and allocation work: findings and plan #4, perf: source-generated JSON, streamed output and fewer allocations #5, feat: NativeAOT builds, benchmarks and packaging #6, v1.0.8) as markers.
  2. Where a run's time goes: stacked bar for the 5h video. Watch page, manifest, caption fetch, then ytx's 43 ms as a sliver.
  3. Build shapes: grouped bars for startup and CPU per call across the nine builds.
  4. Caption track selection, before and after: v1.0.7 ordering against the proposed order (exact code, exact name, prefix, substring, manual before auto).
  5. Stacked PR mishap: master ← perf: source-generated JSON, streamed output and fewer allocations #5 branch ← feat: NativeAOT builds, benchmarks and packaging #6, then the base deleted and feat: NativeAOT builds, benchmarks and packaging #6 closed, then restored and retargeted.
  6. Release pipeline: publish.yml (version, pack, NuGet, release) beside native.yml (5-RID matrix, smoke test, archives and SHA256SUMS on tag).

Screenshots to take

What is still missing

  • A Windows or Linux run against YouTube. Every live number is from one Mac.
  • A cover image (/images/ytx-review-aot-cover.svg and .png).
  • A decision on AOT release assets. The post can end open, but should say so.

What is next (decided order)

Status, 9 October 2026: steps 1, 2, 3 and 5 are done, released as v1.1.0, and chapters followed in v1.2.0. Step 4, NativeAOT (#6), is next. The rest of the story is in docs/investigations/2026-10-ytx-review-to-1.1.0.md, which covers everything through 1.2.0.

A scoping pass after v1.0.8 recommended fixing #3 first, in small PRs, and finishing AOT once the output contract settles:

  1. ✅ Track selection fix (fix: prefer manual captions and exact language matches #8, shipped in 1.1.0 rather than 1.0.9). Prototyped at +23/−7 lines plus 62 lines of tests, with 85 tests passing. On the TED talk the default gives the manual track, and -l fr, es and ja give French, Spanish and Japanese. Trap found: with only ThenBy, -l xx fell back to Afrikaans, so English stays the tiebreak.
  2. ✅ Housekeeping (chore: update YoutubeExplode, add LICENSE, remove stale doc #9). YoutubeExplode 6.6.2 drops AngleSharp, which clears NU1902, keeps AOT warning-free and gives byte-identical output. Add LICENSE and remove the stale viewer doc.
  3. ✅ Output fields and captionStatus (1.1.0) (feat!: report caption status, track and video metadata in output #10). One schema change, released as a minor version with [skip ci] and a manual run.
  4. ⏭️ Next: finish feat: NativeAOT builds, benchmarks and packaging #6 on the settled schema, so Homebrew and Scoop users start on the final contract.
  5. ✅ Features: --proxy, segments, --format and --list-languages (fix(cli): add --timeout and Ctrl+C handling, tidy caption text and help #11, feat: add --format, --segments, --list-languages and --proxy #12). MCP mode was dropped. Chapters were added in 1.2.0 (feat: chapters from the video description #16, feat: read chapters from the video description #17).

The alternative was to ship AOT straight after steps 1 and 2 and save the schema change for a 2.0. The slow 11–21 s caption fetches are not fixed by 6.6.2 or by AOT, and only appear on caption fetches, never with --metadata-only. They need their own trace.


🤖 Generated with Claude Code

https://claude.ai/code/session_01GheLxQMy85bM3Cb7mWY1CT

Activity

  1. solrevdev commented on Oct 8, 2026

    @solrevdev
    OwnerAuthor

    Update: steps 1–3 and 5 of "What is next" are done and shipped as v1.1.0. #3 is closed.

    The rest of the story, from the session handoff to the release, is in docs/investigations/2026-10-ytx-review-to-1.1.0.md. It has the timeline, each change with its evidence, the traps, measurements, the decisions not taken, a suggested outline and commands to reproduce. Together with this issue, it covers everything needed for the blog post.

    Next is step 4, NativeAOT (#6). It is up to date with 1.1.0 and targets master. The README now has install instructions for each OS and explains when to use the native binary.

    🤖 Generated with Claude Code

  2. solrevdev commented on Oct 8, 2026

    @solrevdev
    OwnerAuthor

    Update: chapters shipped in v1.2.0 (#16, #17).

    They had been left out of 1.1.0 because YoutubeExplode has no chapters API. ytx now parses them from the description using YouTube's own rules, and the Markdown transcript is split into sections by chapter. Section 6a of the write-up covers the design and the traps, so it can go in the post.

    #6 (NativeAOT) is up to date with 1.2.0 and is still the next piece of work.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    blogMaterial for a future blog post

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions