<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Practice Space]]></title><description><![CDATA[All things creative and personally fulfilling. Research, music, AI, and the outdoors.]]></description><link>https://practicespace.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!2d9L!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3f22ba-363b-40e8-8db4-c9eac148a517_1280x1280.png</url><title>Practice Space</title><link>https://practicespace.substack.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 09 Apr 2026 22:45:58 GMT</lastBuildDate><atom:link href="https://practicespace.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nick Feamster]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[practicespace@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[practicespace@substack.com]]></itunes:email><itunes:name><![CDATA[Nick Feamster]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nick Feamster]]></itunes:author><googleplay:owner><![CDATA[practicespace@substack.com]]></googleplay:owner><googleplay:email><![CDATA[practicespace@substack.com]]></googleplay:email><googleplay:author><![CDATA[Nick Feamster]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How AI Agents Helped Me Go from Lecture Transcripts to Book Draft]]></title><description><![CDATA[Outlining my process for creating a book, and how AI agents are helping me get it across the finish line.]]></description><link>https://practicespace.substack.com/p/how-ai-agents-helped-me-go-from-lecture</link><guid isPermaLink="false">https://practicespace.substack.com/p/how-ai-agents-helped-me-go-from-lecture</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Wed, 11 Feb 2026 20:09:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mq82!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mq82!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mq82!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 424w, https://substackcdn.com/image/fetch/$s_!mq82!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 848w, https://substackcdn.com/image/fetch/$s_!mq82!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 1272w, https://substackcdn.com/image/fetch/$s_!mq82!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mq82!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png" width="1313" height="538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:538,&quot;width&quot;:1313,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1191564,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/187669220?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mq82!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 424w, https://substackcdn.com/image/fetch/$s_!mq82!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 848w, https://substackcdn.com/image/fetch/$s_!mq82!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 1272w, https://substackcdn.com/image/fetch/$s_!mq82!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a50ee8-e3d7-4532-832c-ec622fadcd78_1313x538.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Whether it is music, research, courses, or books, I use the following maxim as a guide:</p><blockquote><p><strong>Make the things you want to exist in the world.</strong></p></blockquote><p>The courses I teach, for example, I have created from scratch. They are the courses I wished I had as a student. One of those courses is &#8220;Internet Censorship and Online Speech&#8221;.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>When one teaches a course, it is helpful to have accompanying reading material, but material that you didn&#8217;t create yourself is always a bit of a shoehorn. One of the most valuable things we can do as instructors, especially in the age of AI, is synthesis.</p><p>For that reason, I&#8217;ve created textbooks and online courses from scratch in an attempt to synthesize everything I learn as I continue to teach the material.</p><p>As one such effort, I&#8217;ve been writing a textbook on Internet censorship and information control for the past five years. What started as a way to capture my lectures has evolved into a fascinating journey in human-AI collaboration. Here&#8217;s how I used AI tools&#8212;culminating in Claude&#8217;s new &#8220;agent teams&#8221; feature&#8212;to transform raw lecture transcripts into a polished manuscript.</p><h2><strong>The Starting Point: A Course Without a Textbook</strong></h2><p>When I began teaching my course on Internet Censorship at the University of Chicago, I faced a common problem: there was no textbook that covered the breadth of topics I wanted to address. The field spans technical mechanisms (DNS manipulation, BGP hijacking, deep packet inspection), platform dynamics (content moderation, algorithmic curation, disinformation), legal frameworks (Section 230, copyright, net neutrality), measurement techniques, and circumvention technologies.</p><p>So, I decided to write one.</p><h2><strong>Phase 1: Capturing Lectures (2021)</strong></h2><p>The first step in drafting the book was getting some initial thoughts down. During the Covid lockdown, we were all teaching online, and so I had a significant cache of online videos (now on YouTube!) comprising the course lectures. Arvind Narayanan once told me that he started some of his books from video lecture transcripts. So, rather than staring at a blank page, I recorded my lectures and extracted transcripts from YouTube. </p><p>My earliest commits tell the story:</p><pre><code><code>Feb 2021: first draft of Chapter 2 material from YouTube transcripts
Feb 2021: BGP draft text from transcript
Mar 2021: transcripts through first seven chapters/weeks
Mar 2021: transcripts for legal aspects</code></code></pre><p>The raw transcripts were messy&#8212;full of verbal tics, digressions, and the natural meandering of spoken explanation. But they contained the core ideas, organized roughly the way I wanted the book structured. Back in 2021, there were no LLMs, and so I spent a fair amount of time manually editing the spoken prose. This, frankly, was a painstaking process, and not particularly creative&#8212;it mainly involved changing my spoken &#8220;lecture voice&#8221; into something more appropriate for a book, while preserving the content.</p><h2><strong>Phase 2: Transcript to Prose (2021&#8211;2025)</strong></h2><p>Prior to AI, transforming spoken lectures into readable prose was tedious work. This past fall, I began to use Claude to help me. I would record all of my lectures and get transcripts which now included not only my lecture but also student questions.</p><p>Again, this step was painstakingly manual at first, but as AI models and agents have improved over the past several years, I&#8217;ve been able to leverage these tools to really speed up this part of the process.</p><ul><li><p><strong>Clean up the language</strong>: Removing filler words, fixing grammar, smoothing transitions</p></li><li><p><strong>Restructure for reading</strong>: What works in a 75-minute lecture doesn&#8217;t always work on the page</p></li><li><p><strong>Add pedagogical scaffolding</strong>: Signposting, summaries, clearer section breaks</p></li></ul><p>Sample commits from this period:</p><pre><code><code>Edit DNS and TCP sections into polished book prose
Enhance BGP section with class discussion insights
Enhance traffic shaper explanations with clearer pedagogical flow</code></code></pre><p>I kept teaching the course while continuing to write, saving notes, questions, and presentations from students. Each semester gave me new material:</p><ul><li><p><strong>Student questions</strong> revealed where explanations were unclear</p></li><li><p><strong>Class discussions</strong> surfaced interesting angles I hadn&#8217;t considered</p></li><li><p><strong>Student presentations</strong> brought in current case studies and examples</p></li></ul><p>I fed these back into the manuscript:</p><pre><code><code>Add points and case studies raised in Fall 2025 class presentations
Add citations and content from student project references (782 words)
Enhance BGP section with class discussion insights</code></code></pre><h2><strong>Phase 3: Case Studies, Examples, and Sources</strong></h2><p>Writing of this nature requires up-to-date examples and case studies, with citations&#8212;lots of them. Of course, left to their own devices, AI models have a well-known tendency to hallucinate citations, inventing plausible-sounding papers that don&#8217;t exist.</p><p>I developed a rigorous citation workflow, codified in a custom <code>/add-citations</code> command for Claude Code. The core principle being that every single citation needs to be verified by an agent through: (1) download; (2) analysis of the abstract; (3) inclusion of a URL that I can subsequently go manually read myself.)</p><p>The workflow uses a hierarchy of academic APIs:</p><ol><li><p><strong>DBLP API</strong> for computer science papers (returns clean BibTeX directly)</p></li><li><p><strong>CrossRef API</strong> when you have a DOI</p></li><li><p><strong>arXiv API</strong> for preprints</p></li><li><p><strong>Semantic Scholar API</strong> for discovery</p></li></ol><p>Every citation must be verified with WebFetch on the actual publisher page before being added. If the title doesn&#8217;t match, it doesn&#8217;t get added. Period.</p><pre><code><code># Example: Search DBLP and get BibTeX directly
curl "https://dblp.org/search/publ/api?q=censorship+measurement&amp;format=bib&amp;h=5"

# Verify with CrossRef
curl -LH "Accept: application/x-bibtex" https://doi.org/10.1145/...</code></code></pre><p>This approach takes longer than just asking an AI to &#8220;add some citations,&#8221; but it produces a bibliography you can actually trust.</p><h2><strong>Phase 4: Agent Teams for Deep Editing (February 2026)</strong></h2><p>Recently, Claude Code introduced an &#8220;agent teams&#8221; feature that lets you spawn multiple AI agents to work on a task in parallel. I decided to use this for a comprehensive editing pass.</p><h3><strong>The Workflow</strong></h3><p><strong>Step 1: Launch Six Parallel Editors</strong></p><p>I spawned six agents simultaneously, one for each chapter:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2Kmk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2Kmk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 424w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 848w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 1272w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2Kmk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png" width="501" height="173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:173,&quot;width&quot;:501,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25878,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/187669220?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2Kmk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 424w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 848w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 1272w, https://substackcdn.com/image/fetch/$s_!2Kmk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F80d298b6-171e-4789-8c8b-2d8d2f9cb2ba_501x173.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Each agent received detailed instructions:<br>- Read all chapter files thoroughly<br>- Add verified citations (using the citation workflow)<br>- Edit for clarity without changing structure (it matches my course syllabus)<br>- Report back on edits made, citations added, and cross-chapter issues</p><p><strong>Step 2: Cross-Chapter Consistency Review</strong></p><p>After the initial edit, I had the agents swap chapters. Each agent reviewed a chapter they hadn&#8217;t edited, specifically looking for:<br>- Voice consistency across the book<br>- Working cross-references between chapters<br>- Consistent terminology<br>- Flow and length balance</p><p><strong>Step 3: Image Pipeline</strong></p><p>I also used a specialized four-agent pipeline for figures:</p><ol><li><p><strong>Image Sourcing Agent</strong>: Reviewed ~400 images from my own lecture slides, identifying useful diagrams, charts, and maps</p></li><li><p><strong>Image Quality Reviewer</strong>: Checked each candidate for accuracy, currency, copyright permissions, and resolution</p></li><li><p><strong>Placement Finder Agent</strong>: Located exact insertion points in the LaTeX source</p></li><li><p><strong>Insertion Agent</strong>: Actually added the figure code to the manuscript</p></li></ol><p>The agent teams processed six chapters in parallel, adding dozens of verified citations, improving clarity throughout, and ensuring consistency across the book. Work that would have taken me weeks of tedious editing happened in under an hour.</p><h2><strong>Lessons Learned</strong></h2><p><strong>1. Start with your own voice.</strong> The transcripts captured how I actually explain these concepts to students. AI helped refine the prose, but the pedagogical approach and examples are mine.</p><p><strong>2. Iterate with students.</strong> Teaching the course while writing the book created a feedback loop. Student confusion pointed to unclear explanations. Their presentations brought in fresh case studies.</p><p><strong>3. Build guardrails for citations.</strong> AI-generated citations are a minefield. Building a verified citation workflow was essential for producing something I could stand behind academically.</p><p><strong>4. Parallel agents are powerful for editing.</strong> Having multiple agents work simultaneously&#8212;then swap and review each other&#8217;s work&#8212;catches issues that a single pass would miss.</p><p><strong>5. AI is useful, but the author must be in the loop at every stage.</strong> At every stage, I reviewed what the agents produced. Ultimately, the book reflects my voice, expertise, and judgment; AI was a tool that accelerated the work. </p><p>6. <strong>Work with AI agents like you might a collaborative human editor</strong>. The agents did not &#8220;write the book&#8221; per se; rather, they incorporated all of my inputs, including full chapter drafts that came from my own words (either through transcripts or my own typing). They helped me take care of annoying formatting things, identified thematic gaps, helped me find places to integrate content and examples that I devised (often &#8220;on the fly&#8221; in lecture), and served to provide me with important editorial feedback along the way.</p><h2><strong>What&#8217;s Next</strong></h2><p>The manuscript is nearing completion. It&#8217;s been a five-year journey from &#8220;I need a textbook for this course&#8221; to a full manuscript with six chapters, hundreds of citations, and dozens of figures.</p><p>The tooling has evolved dramatically over that time. What started with simple transcript cleanup has progressed to sophisticated multi-agent workflows. I&#8217;m excited to see where these tools go next&#8212;and what other professors might be able to accomplish with them.</p><div><hr></div><p><em>The book, tentatively titled &#8220;Filtered,&#8221; covers Internet censorship and information control, based on my course at the University of Chicago (<a href="https://noise-lab.net/censorship-course/">course website</a>). The techniques described here could apply to any textbook project built from lecture materials.</em></p>]]></content:encoded></item><item><title><![CDATA[How to Get (Coding) Agents to Work Well]]></title><description><![CDATA[My workflow with spec-driven development in Claude Code]]></description><link>https://practicespace.substack.com/p/how-to-get-coding-agents-to-work</link><guid isPermaLink="false">https://practicespace.substack.com/p/how-to-get-coding-agents-to-work</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Tue, 03 Feb 2026 07:04:52 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ce4306f5-ee67-4c6e-ab83-80e91bbdc4f6_806x584.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A few people have asked about my coding workflow, so I thought I would write it up. Here&#8217;s how it actually works, and why I think it works. (Note: I use this for coding, but the same general principles apply across a variety of agentic tasks.)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IO5x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IO5x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 424w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 848w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 1272w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IO5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png" width="806" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:806,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:735177,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/186706618?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IO5x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 424w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 848w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 1272w, https://substackcdn.com/image/fetch/$s_!IO5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0d8e09a-b914-46e0-a6c3-c78cb1e5ccdd_806x584.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I&#8217;ve found that agents work best under three conditions:</p><h3>1. Limited Context</h3><p>LLMs have finite context windows, and even within those windows, attention degrades over distance. When you ask an agent to work on a 50-line function with a clear input/output contract, it can hold the entire problem in focus. When you ask it to &#8220;refactor the whole application,&#8221; it starts losing track of things&#8212;dependencies, side effects, earlier decisions.</p><blockquote><p>The practical implication: <strong>decompose your tasks aggressively</strong>. Break big tasks into small ones. </p><p>Give the agent a piece it can fully comprehend. This isn&#8217;t just good practice for AI; it&#8217;s good software engineering. But with agents, it&#8217;s mandatory.</p></blockquote><p>I&#8217;ve found that when Claude Code starts making inconsistent changes or forgetting earlier context, the problem is almost always that I&#8217;ve let the scope creep too wide. The fix is to step back, carve off a smaller piece, and let it finish that completely before moving on. Carve a task up into sub-agents, if necessary (something I myself am still learning how to do).</p><h3>2. Tight Constraints</h3><p>The problem space is bounded. You&#8217;re not wandering through infinite possibilities&#8212;you&#8217;re meeting a spec, passing tests, satisfying types.</p><p>Constraints are liberating. When you tell an agent &#8220;write a function that takes a list of integers and returns the sum,&#8221; there&#8217;s not much room for hallucination. When you tell it &#8220;build something useful,&#8221; you get chaos.</p><p>This is where the spec becomes critical. A good spec is a set of constraints that bounds the solution space. Types are constraints. Tests are constraints. &#8220;Use this library, not that one&#8221; is a constraint. &#8220;Follow the existing code style&#8221; is a constraint.</p><blockquote><p>The more constraints you provide, the less the agent has to guess&#8212;and guessing is where things go wrong. </p></blockquote><p>I&#8217;ve started thinking of spec-writing as constraint-specification: <strong>what are all the ways this could go wrong, and how do I rule them out in advance? </strong>Inevitably, you will miss some constraints. This is where the third factor comes into play</p><h3>3. Verifiable Outputs</h3><p>First of all, tests pass or fail; code compiles or doesn&#8217;t. This simple fact actually makes coding very suitable for agentic tasks, because the models can do some amount of verification simply based on whether the code runs. </p><p>But, just because code runs doesn&#8217;t mean it is correct. I started writing MCP servers in Claude in the domain of music; it became painfully clear when something wasn&#8217;t working because <em>I could hear it</em> (four measures played instead of eight, dissonant sounds wildly out of the diatonic, etc.)</p><p>The verifiability of coding and its outputs make it particularly amenable to agentic coding.  Verification creates a feedback loop. The agent can try something, check if it worked, and iterate. This is why agentic coding tools run the code they generate, execute the tests, read the error messages. They&#8217;re not just generating&#8212;they&#8217;re generating, checking, and refining. </p><p>Verification can be automated, but it doesn&#8217;t have to be. Human review is verification too. The key is that verification is <em>possible</em> and <em>cheap enough</em> to actually do. In coding, you get both automated checks (tests, types, linters) and human review of outputs. </p><blockquote><p>There is an important lesson here, too: <strong>You want to make sure that what is generated is actually verifiable. </strong></p></blockquote><p>I work in Internet measurement and so the code I generate often involves data analysis; there are easy ways to check the output of analysis. One way is simple sanity checks and knowing &#8220;the back of the envelope&#8221; (e.g., how many seconds in a day, what&#8217;s the round-trip latency across the United States, etc.). </p><p>Having both specific and general domain knowledge internalized allows one to quickly spot non-sensical or incorrect output. But, regardless of the domain, the output must be checked&#8212;these days, still by a human&#8212;and thus it is imperative that whatever the model generates is easy to check. You can instruct the model to do this! I tend to provide instructions that include both automated checks and instructions that make it easy for me to verify outputs (think &#8220;clicking and reading&#8221; to verify).</p><h3>Takeaway: Specify Constraints, Limit Context</h3><p>Rich tooling and clear feedback are immensely helpful in this context. But the tooling isn&#8217;t what makes this work&#8212;it&#8217;s how the domain lets you structure the problem. The magic isn&#8217;t in the compiler or the shell. It&#8217;s in the fact that coding naturally decomposes into small, constrained, verifiable pieces.</p><p>This matters because <strong>the better you specify constraints and limit context, the better the agents do.</strong> </p><p>This insight forms the foundation of the workflow I describe below.</p><div><hr></div><h2>My Development Cycle</h2><p>Here&#8217;s the short version:</p><ol><li><p><strong>Specify and document.</strong> Specify requirements, tools, structure, language, basic test cases and expectations. Importantly, specify constraints (what the agents should not do!). The spec is often incomplete at first because step 1 is hard. Humans are bad at specs. <strong>Fortunately, the model is probably better at writing a good spec than you are.</strong></p><p>I often start by telling Claude Desktop what I want to build, and asking it to help me write the spec. We iterate. I refine. Then, when I&#8217;m happy with it, I take that spec to Claude Code. I&#8217;ve found that this can be an iterative process. Part of why I hadn&#8217;t written this up earlier is that I haven&#8217;t fully wrapped my head around what really works well versus what doesn&#8217;t. But a little supervision and independent thinking goes a long way.</p><p>This is the question I ask myself when creating a spec and documentation on which to build a piece of software: <strong>Imagine that you are starting up Claude Code for the very first time and want it to read the docs and run the code. What would it need to know?</strong></p></li><li><p><strong>Feed the specification into Claude Code to get a first pass. </strong>This is the part that feels like magic. You hand it a spec, and code appears. But don&#8217;t get drunk on the magic. The output needs to be checked. This isn&#8217;t &#8220;fire and forget.&#8221;</p></li><li><p><strong>Iterate.</strong> Try using the code, check all outputs, supervise, take notes of errors and missing features. Use Claude itself to note things like missing features, things that are not working correctly, etc. Use the tool for a while. Check the outputs. Does it actually do what you wanted? Does it handle edge cases? Does it fail gracefully? This is where you catch the hallucinations, the subtle bugs, the things that &#8220;work&#8221; but don&#8217;t work <em>correctly</em>. Or, you notice that something you wanted the code to do, it simply &#8230;can&#8217;t, because you forgot something in your spec.</p></li><li><p><strong>Push documentation to &#8220;memorialize&#8221;.</strong> Take note of (a) what went wrong and how you ended up fixing the issue; (b) make sure that updates and fixes to the code are also memorialized in the updated specification and documentation. Before I close a Claude Code project, I always take time to work on the documentation. Think of it like this: If I were to come back to this later, what would I want Claude to immediately pull into context and not have to type again? That should all be in the updated docs.</p></li><li><p><strong>Use Git for everything.</strong> Commit early, commit often, push often. Agents make mistakes. You will make mistakes supervising them. You need to be able to roll back, and you will. Treat every commit as a potential restore point. Be very careful with rebasing; consider disallowing it unless you explicitly ask for it&#8212;I've lost work by letting Claude Code "clean up" commit history or resolve a merge conflict when I actually needed that history preserved.  As with other parts of your project, if you are not explicit about constraints, the agents will fill in the gaps and you may not like the results.</p></li></ol><div><hr></div><h2>Why Things Break, When They Break</h2><p>Here&#8217;s what I&#8217;ve learned:</p><ul><li><p><strong>Poor specification or constraints &#8594; limited (or unwanted!) functionality.</strong> The specification is king. If the spec doesn&#8217;t capture what you actually want, you&#8217;ll get something that technically meets the spec but doesn&#8217;t solve your problem and may also do things you never asked for. It is thus critically important to specify constraints.</p></li><li><p><strong>Context window exceeded &#8594; weird failures.</strong> The model starts losing track of things. You get inconsistencies, repeated mistakes, or outputs that ignore earlier instructions. The trick here is to limit the context window. I am still working on ways to do this; for example, I am learning a bit more about sub-agents. I am interested to hear how others deal with this.</p></li><li><p><strong>Missing implementation &#8594; need to update the server.</strong> Sometimes the model assumes a feature exists that doesn&#8217;t. This is a signal that your spec or your tooling has a gap. The model won&#8217;t often tell you that it&#8217;s missing a feature; you have to intuit from the output that you&#8217;re asking it to do something that it doesn&#8217;t know how to do. From there, you can go back to iterating on a spec.</p></li><li><p><strong>Config sprawl</strong> &#8594; When you&#8217;re building tools, configurations multiply, and agents are not particularly good at keeping configuration organized and tidy. Periodically step back and ask: &#8220;If I had to set this up on a new machine, how painful would it be?&#8221; If you couldn&#8217;t migrate in under a minute, or you have to think about where every part of your project configuration is living (auth, environment settings, etc.), this your signal to consolidate. I periodically blow all of my software away and re-install just to make sure my processes are streamlined.</p></li></ul><div><hr></div><h2>Example Workflow: Desktop MCP &#8596; Code Iteration</h2><p>Claude Desktop and Claude Code don&#8217;t know about each other. They&#8217;re separate tools with separate contexts. But with good specs and MCP connections, I&#8217;ve found that you can stitch them together to really enhance productivity. I now have MCPs for calendaring, briefing, email triage, invoicing, &#8230; not to mention countless creative projects, as well.</p><p>My typical pattern is as follows:</p><ul><li><p><strong>Desktop for ideation and spec writing</strong>. I think out loud with Claude, brainstorm approaches, write the spec collaboratively.</p></li><li><p><strong>Code for execution</strong>. I copy the spec over and let Claude Code generate.</p></li><li><p><strong>In the case of MCP, back to the Desktop</strong>. I try to use my MCP servers. At the outset, I trust nothing. I verify what the agents are doing manually, because often they will make mistakes&#8212;and typically the source of the mistake was a failure in my specification. When something breaks or does not work as planned, I often talk through it with Desktop first, figure out exactly what the MCP is not seeing, then work on an updated specification, and bring the fix back to Code.</p></li></ul><p>I use the spec, not the conversation, as the conduit. The conversation is ephemeral. The spec persists and is continually being updated. </p><div><hr></div><h2>Note: &#8220;AI Failures&#8221; are Often User Failures</h2><p>We&#8217;ve all seen the headlines: AI loses money, AI gets tricked, AI does something absurd. For example, recently the Wall Street Journal ran an experiment where they let an AI agent run a vending machine. It gave away inventory for free, bought a PlayStation 5, ordered a live fish. Chaos, laughs, great clickbait.</p><p>A closer read reveals what actually happened, though: the user gave an agent vague instructions (&#8221;generate profits&#8221;), no guardrails, no supervision, and let 70 journalists red-team it unsupervised. When it predictably fell apart, the diagnosis was &#8220;the context window filled up&#8221;&#8212;which they present as an inevitable AI limitation rather than a design failure.</p><p>While this might be an entertaining cautionary tale, that&#8217;s not AI &#8220;failing&#8221;, but simply a user failing to understand how the tools work. A clear spec, incremental testing, active supervision, and documented fixes would have caught every one of those problems. The vending machine wasn&#8217;t a case study in AI limitations. It was a case study in not having a workflow.</p><h2>Bottom Line: Understand How Your Tools Work</h2><p>If you think you know how these systems work (and how they fail), you can understand what is likely to work for input and how to check the output. </p><p>There is a lot of benefit to structured thinking and clear spec. The limited context window is something to be aware of&#8212;so I&#8217;m continually refining the docs and code as I go, almost like a &#8220;compressed&#8221; version of what I want the model to be remembering. Truly thinking about it as a collaborator or &#8220;coding engineer who can meet a spec&#8221;... but a little supervision and independent thinking goes a long way. None of this is by any means a substitute for thinking. If anything, it pushes us to think more clearly than ever, because errors in specification end up even more amplified.</p><blockquote><p><strong>Agents work best when you give them limited context, tight constraints, and clear ways to verify their outputs. Coding happens to be a domain where all three are natural. But the lesson generalizes: if you can structure </strong><em><strong>any</strong></em><strong> problem that way, you can make these tools work.</strong></p></blockquote><p>I must admit that I still don&#8217;t really know &#8220;how to write a good spec&#8221; for these systems. But that can be a bit of an iterative process too, and one that the models are pretty good at, themselves. </p>]]></content:encoded></item><item><title><![CDATA[I Had Safeguards in Place. AI Hallucinated Anyway.]]></title><description><![CDATA[Cautionary tale: AI is designed to fill in gaps. If you don't explicitly define your workflow, AI will make one up for you (even if you don't ask), and you may not like the result.]]></description><link>https://practicespace.substack.com/p/i-had-safeguards-in-place-ai-hallucinated</link><guid isPermaLink="false">https://practicespace.substack.com/p/i-had-safeguards-in-place-ai-hallucinated</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 26 Jan 2026 18:35:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2d9L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3f22ba-363b-40e8-8db4-c9eac148a517_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8zHl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8zHl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8zHl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8zHl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!8zHl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9a7d0c-8ded-4047-a5c0-620e4b059725_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I was finishing up an NSF grant proposal with Claude Code when my collaborator flagged something odd. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>She&#8217;d been reviewing the bibliography and couldn&#8217;t find some of the papers I&#8217;d cited. First of all, here&#8217;s one of the fabricated entries Claude created:</p><pre><code><code>@inproceedings{chanenson2023,
    title={Privacy in K-12 Schools},
    author={Chanenson, Emily},
    booktitle={Proceedings of CHI},
    year={2023}
}
</code></code></pre><p>The real paper, which my collaborator is a co-author on, was this:</p><pre><code><code>@inproceedings{chanenson2023K12PrivacySecurity,
    title={Uncovering Privacy and Security Challenges In K-12 Schools},
    author={Chanenson, Jake and Sloane, Brandon and Rajan, Navaneeth 
            and Morril, Amy and Chee, Jason and Huang, Danny Yuxing 
            and Chetty, Marshini},
    booktitle={Proceedings of the 2023 CHI Conference on Human Factors 
                in Computing Systems},
    year={2023},
    pages={1--28},
    doi={10.1145/3544548.3580777}
}
</code></code></pre><p>Wrong first name. Simplified title. Missing six co-authors. No DOI. </p><h2>Safeguards aren&#8217;t enough if you don&#8217;t define the workflow</h2><p>I traced the problem back through git history to understand how this happened. I&#8217;d been using Claude to adapt a &#8220;PI Qualifications&#8221; paragraph describing my co-PI&#8217;s prior work that I had from a previous proposal, a simple request that should have been a small text edit based on text that was already in the proposal elsewhere.</p><p><strong>I never asked Claude to find or create citations.</strong> My workflow was designed to be safe&#8212;Claude was supposed to reference only my existing .bib file. I thought that was sufficient.</p><p>But Claude knew my co-PI had expertise in educational technology privacy, VPN user studies, and privacy mental models. So when it wrote the qualifications paragraph, it included citations:</p><pre><code><code>Chetty brings expertise in empirical studies of privacy attitudes 
and technology adoption, including NSF CAREER-funded research on 
educational technology privacy~\cite{chanenson2023}, prior work on 
VPN mental models~\cite{kumar2023understanding} and privacy 
adoption~\cite{wagman2023}.
</code></code></pre><p>Then&#8212;without being asked&#8212;Claude created bibliography entries to match. It didn&#8217;t have the actual papers. It didn&#8217;t verify they existed. It didn&#8217;t check my existing .bib file. It invented plausible-sounding entries based on what it thought the papers should be about. I didn&#8217;t immediately catch it either, because the text itself read well-enough; the error was in a citation that was added that I didn&#8217;t ask for.</p><p>This is more subtle than the typical &#8220;AI hallucinated a citation&#8221; story you hear about. I wasn&#8217;t asking Claude to find papers. I had safeguards in place. But because I didn&#8217;t explicitly bound the capabilities of the agents, they went off-script anyway, proactively (&#8220;helpfully&#8221;) fabricating entries that looked like they belonged.</p><h2>Plausible-looking output is the danger zone</h2><p>The fabricated entries had proper BibTeX formatting, reasonable titles, plausible author names. If my collaborator hadn&#8217;t caught them during review, they might have made it into the final submission. And once fake citations enter a bibliography file, they propagate&#8212;other researchers copy them, students cite them, the misinformation spreads.</p><p>This is a known problem with large language models. The technical term is &#8220;confabulation&#8221;&#8212;filling gaps with plausible-sounding but false information. LLMs can generate text that looks right but can&#8217;t reliably distinguish between &#8220;plausible&#8221; and &#8220;true.&#8221; That&#8217;s not something that gets fixed by trying harder or being more careful. It&#8217;s a fundamental limitation that requires external verification.</p><h2>If you don&#8217;t define the workflow, the AI will</h2><p>The incident revealed something important: <strong>I didn&#8217;t have a citation workflow. So Claude invented one.</strong> And the workflow it invented was wrong&#8212;create content with citations first, create bibliography entries to match, never verify they&#8217;re real.</p><p>That&#8217;s the core lesson here. If you don&#8217;t explicitly define how citations should be handled, the AI will fill the gap with its own approach. And its approach prioritizes plausibility over truth.</p><p>So I built an actual workflow around a simple principle: verify first, not after. Search for and verify papers exist first, add verified entries to bibliography, then write content citing them. No exceptions, no &#8220;I&#8217;m pretty sure this exists.&#8221;</p><p>I also added explicit rules for Claude. If it&#8217;s creating BibTeX entries for papers it hasn&#8217;t verified via web search, or guessing at author names or titles, or writing about someone&#8217;s prior work without their actual paper list&#8212;stop. For co-PI qualification sections specifically, it&#8217;s faster and more accurate for Claude to just ask me &#8220;What are the key papers on educational privacy?&#8221; I have her CV. I know her work. I can point to citation keys already in my .bib file.</p><p>I documented all of this in an <code>check-citations.md</code> command file (included below) that includes the exact failure mode, step-by-step verification procedures, and mandatory checklists. The goal is to make it impossible to repeat this mistake through inattention. <strong>I also added a step to add DOI and URL to every single citation so that human verification becomes easy</strong>&#8212;all one has to do is go through the citations and click the links to perform manual verification on each.</p><h2>This isn&#8217;t just about citations</h2><p>This incident captures a fundamental tension in AI-assisted work. These tools can genuinely increase productivity&#8212;Claude can help one become significantly more efficient at formatting, restructuring, finding inconsistencies, even drafting prose. But agents require explicit workflows <em>with constraints</em> because they will, inevitably, fill gaps with plausible-sounding fabrications. Citations are just one example. The same problem applies to any task where the AI needs to reference external facts: legal documents, financial data, technical specifications, historical records.</p><blockquote><p><strong>For anyone using AI assistants: trust but verify.</strong> Every factual claim needs human verification. Design your workflows assuming AI will occasionally fabricate things. <em>Make verification cheap and easy so you&#8217;ll actually do it. And when AI makes a mistake, analyze it, update your workflows, share what you learned.</em></p><p><strong>For AI developers:</strong> confabulation is the hard problem. Don&#8217;t just generate content&#8212;build in verification steps. Flag unverified claims. When uncertain, say &#8220;I need to verify this&#8221; instead of generating something plausible-looking. It&#8217;s better to be slow and right than fast and wrong.</p></blockquote><p>It would be great if citation verification APIs integrated directly into tools like Claude&#8212;automatic checks against CrossRef, Semantic Scholar, DBLP before any citation gets added. Confidence scoring that distinguishes &#8220;verified from publisher&#8221; from &#8220;generated from context (UNVERIFIED).&#8221; Audit trails tracking where each citation came from.</p><p>In the meantime, I&#8217;ve built my own workaround: a Claude Code command that enforces verification before any citation gets added, requires WebFetch to confirm titles match actual webpages, and checks for broken references in the bibliography. It&#8217;s not foolproof, and I&#8217;ll continue verifying manually. But it makes the workflow explicit instead of leaving gaps for Claude to fill with fabrications. In some ways, it is actually better than what I had before <strong>and</strong> better than humans&#8212;the process ended up finding several other erroneous citations that humans had entered.</p><p>My collaborator caught these errors. Otherwise, fake citations would have landed in an NSF proposal. AI assistance is valuable, but human verification remains essential.</p><blockquote><p><strong>AI will improve, but we need critical self-examination and post-mortems like this.</strong></p></blockquote><p>Finally, I will note that git revision history was extremely valuable in helping diagnose the root cause of how this error occurred. AI will make mistakes. The answer is not to avoid it, but rather to firmly understand why and how it makes mistakes, and improving our systems and workflows so that the tools can work better for us. A careful, critical, honest eye towards mistakes is how we make progress, which is why I thought it was important to share this cautionary tale.</p><p><strong>Update:</strong> A friend tells me that even this approach below may not be good enough. Relying on WebSearch is not constrained enough, and that all information that comes in should be brought in via an API, not via the web. Additionally, dividing up tasks with subagents helps preserve the context window, so this approach I have laid out above may ultimately require a bit of re-design.</p><pre><code><code>## Citation Verification Workflow

1. **Never create citations without verification**
   - Search for the actual paper using WebSearch
   - Use WebFetch to verify the title on the publisher's page
   - Cross-check authors, year, venue against official sources
   - Test that DOIs/URLs actually work

2. **Verify before you write, not after**
   - Search for and verify papers exist first
   - Add verified entries to bibliography
   - THEN write content citing them

3. **When citing someone's prior work**
   - Ask the user: "Which papers should I cite for [topic]?"
   - Search their Google Scholar or DBLP page
   - DO NOT fabricate entries based on what you think should exist

4. **Red flags that require stopping**
   - Creating BibTeX entries for papers not verified via web search
   - Guessing at author names or titles
   - Writing about someone's prior work without their actual paper list
   - Adding incomplete metadata
</code></code></pre>]]></content:encoded></item><item><title><![CDATA[Initial Lessons from My First Experience in the Recording Studio]]></title><description><![CDATA[Twenty years later, I'm back in Atlanta, getting out of my comfort zone again.]]></description><link>https://practicespace.substack.com/p/initial-lessons-from-my-first-experience</link><guid isPermaLink="false">https://practicespace.substack.com/p/initial-lessons-from-my-first-experience</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Thu, 01 Jan 2026 22:38:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7Bl5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On this week in 2005, I moved to Atlanta to start my first job as an assistant professor at Georgia Tech. Twenty years later, I returned to Atlanta to work on a completely different project. I&#8217;m right back where I like to be: just beyond the edge of my comfort zone, riding an exponential learning curve.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I spent a couple of days in the studio this week, working on my first professionally produced track. Here&#8217;s what I learned.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Bl5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Bl5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Bl5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg" width="1456" height="680" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:680,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2552257,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/183185914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Bl5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7Bl5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9d068a-3f63-4683-9786-1b732d79941c_4000x1868.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>1. Get a chord chart on a grid.</strong></p><p>I did this with MIDI over my demo track before going in, and it ended up saving hours. There will be many opportunities to re-track things with different arrangements - bass, synths, guitars - and this goes much faster if your producer knows the chords you&#8217;re using rather than figuring them out on the fly.</p><p><strong>2. Know how to play your songs in different ways.</strong></p><p>If you&#8217;re layering tracks, there will be countless opportunities to &#8220;paint&#8221; in the mix. A part that sat one way in your bedroom demo might need to breathe differently when there&#8217;s a live drummer pushing the energy.</p><p><strong>3. Be flexible.</strong></p><p>Some things will change. Having a complete song is critical - not because it&#8217;s necessarily &#8220;done,&#8221; but because it gives you a foundation to make small adjustments from. Sometimes we&#8217;d spend an hour or two on eight bars of just one track. (&#8221;How is this going to sound? Only one way to find out!&#8221;) This isn&#8217;t writing the song in studio. It&#8217;s being willing to experiment with what best brings out the emotion of what&#8217;s already written.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iOIK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iOIK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iOIK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg" width="1456" height="680" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:680,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2360943,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/183185914?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iOIK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iOIK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72102047-3e82-4e80-b793-a57a5a9ce261_4000x1868.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>4. Basic music theory is critical.</strong></p><p>Theory can be limiting if the rules pen you in, but in the studio, it&#8217;s essential because it gives you a common language. It lets you communicate efficiently with session musicians and your producer, and helps you understand why different layers work together.</p><p><strong>5. Practice the new parts.</strong></p><p>In pre-production, your producer may send back additional ideas - new riffs, alternate bass lines, different voicings. Practice playing anything you like, because you&#8217;ll likely be playing it yourself. In hindsight, I would have saved time if I&#8217;d practiced some of those parts on bass guitar before showing up.</p><p><strong>6. Learn about production.</strong></p><p>The goal isn&#8217;t necessarily to become a professional producer yourself. It&#8217;s to know what&#8217;s possible and speak the language. You don&#8217;t have to be an expert in compression, reverb, or EQ, but knowing what they do helps you communicate the sound you want.</p><p><strong>7. More survives than you&#8217;d think.</strong></p><p>Much more of the original composition survives the demo process than I expected, even though almost everything gets re-tracked.</p><p><strong>8. There is no substitute for a human drummer.</strong></p><p>Enough said. It&#8217;s good to go in with programmed tracks to give a feel for groove. We definitely also layered drum machine tracks over the human drummer, because that&#8217;s the sound I&#8217;m going for. But, nothing quite captures the energy like a live human drumming to a track you wrote.</p><div><hr></div><p>I&#8217;ve always wanted to make music, and do it at a high level. Two years ago, I had not written a single song. How did I get here? </p><p>The same way I end up doing anything. Little by little. With consistency and focus, and a healthy dose of fearlessness. Approaching the practice with humility and curiosity. Not being afraid to be bad at first. Asking countless stupid questions. Surrounding myself with good, kind, generous people who are better than me at the craft and trying to learn from them as much as possible.</p><p>It&#8217;s all worth it. Because what a beautiful thing, to make something where there was once nothing.</p>]]></content:encoded></item><item><title><![CDATA[SwiftQueue: A Small Transformer Model for Per-Packet Latency Prediction]]></title><description><![CDATA[We reduced tail latency for real-time applications with a 100K-parameter Transformer.]]></description><link>https://practicespace.substack.com/p/swiftqueue-a-small-transformer-model</link><guid isPermaLink="false">https://practicespace.substack.com/p/swiftqueue-a-small-transformer-model</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Wed, 17 Dec 2025 15:59:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!bZOb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>L4S is finally getting deployed. After years of talking about reducing latency at the router level, ISPs are actually rolling this out&#8212;Verizon, Nokia, and others are on board. The basic idea is simple: mark your packets with an ECN bit, and L4S-enabled routers put them in the appropriate queue. Low-latency traffic gets the fast lane.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I was fortunate to be able to present this morning at the <a href="https://understandinglatency.com/">Understanding Latency 4.0</a> Conference on our new technology, <a href="https://arxiv.org/abs/2410.06112">SwiftQueue</a>. </p><p><a href="https://arxiv.org/abs/2410.06112">SwiftQueue</a> uses a compact transformer model to perform sub-millisecond prediction of traffic latency, allowing per-packet queue assignment and reduction of tail latency by as much as 45%.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tt81!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tt81!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 424w, https://substackcdn.com/image/fetch/$s_!tt81!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 848w, https://substackcdn.com/image/fetch/$s_!tt81!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 1272w, https://substackcdn.com/image/fetch/$s_!tt81!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tt81!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png" width="1456" height="452" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:452,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:518839,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180711519?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tt81!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 424w, https://substackcdn.com/image/fetch/$s_!tt81!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 848w, https://substackcdn.com/image/fetch/$s_!tt81!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 1272w, https://substackcdn.com/image/fetch/$s_!tt81!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28ae9577-b89c-404e-baf3-713503e4fb50_1779x552.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>But there&#8217;s a problem with how L4S works today. It treats every packet in a flow the same way. All your video call packets get the same queue assignment, even though congestion is bursty. Some packets sail through; others hit a traffic jam and spike your tail latency. It&#8217;s that variance that kills real-time apps&#8212;not the average, the outliers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QfDR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QfDR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 424w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 848w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 1272w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QfDR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png" width="605" height="318" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:318,&quot;width&quot;:605,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180711519?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QfDR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 424w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 848w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 1272w, https://substackcdn.com/image/fetch/$s_!QfDR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd61379b-5fa4-44d9-bca3-995288e3a02f_605x318.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Current L4S marks all packets in a flow identically, missing per-packet optimization opportunities</strong></figcaption></figure></div><p>We asked a simple question: what if we could predict <em>which</em> packets are about to get hammered, and route them differently?</p><h3>The Approach</h3><p>SwiftQueue uses a Transformer&#8212;the same architecture behind large language models like ChatGPT&#8212;to predict per-packet latency based on the timing of recent ACKs. The insight is that packet-level latency variations aren&#8217;t random. They follow patterns from complex interactions at shared router queues: video apps have periodic bursts, TCP congestion control creates predictable queue buildups and back-offs. Traditional time-series models can&#8217;t capture these patterns efficiently. Transformers can.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!89v0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!89v0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 424w, https://substackcdn.com/image/fetch/$s_!89v0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 848w, https://substackcdn.com/image/fetch/$s_!89v0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 1272w, https://substackcdn.com/image/fetch/$s_!89v0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!89v0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png" width="573" height="163" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:163,&quot;width&quot;:573,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20335,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180711519?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!89v0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 424w, https://substackcdn.com/image/fetch/$s_!89v0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 848w, https://substackcdn.com/image/fetch/$s_!89v0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 1272w, https://substackcdn.com/image/fetch/$s_!89v0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c7914b9-ae1f-48a6-b331-e2cbdb362d01_573x163.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><strong>SwiftQueue predicts latency per packet and chooses the appropriate queue for each</strong> packet.</figcaption></figure></div><p>Armed with that prediction, the sender dynamically marks each packet&#8217;s header to route it to whichever queue has lower predicted latency&#8212;even if that means packets within the same flow end up in different queues.</p><h3>Why Transformers?</h3><p>The core innovation in Transformers is self-attention: the model learns to weigh which elements in a sequence matter for predicting what comes next. In language, &#8220;bank&#8221; means different things depending on whether &#8220;river&#8221; or &#8220;financial&#8221; appeared earlier. The same logic applies to packet latencies&#8212;a spike three packets ago might be highly predictive, or irrelevant, depending on context.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bZOb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bZOb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 424w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 848w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 1272w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bZOb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png" width="569" height="351" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:351,&quot;width&quot;:569,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66647,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180711519?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bZOb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 424w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 848w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 1272w, https://substackcdn.com/image/fetch/$s_!bZOb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d61818c-40a4-4112-8fd6-3aa14c6d50ca_569x351.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Custom Transformer architecture optimized for this task.</figcaption></figure></div><p>RNNs and LSTMs can learn sequences, but they suffer from vanishing gradients and memory limitations. Transformers parallelize attention across the whole context window, making them faster to train and better at long-range dependencies.</p><p>SwiftQueue&#8217;s Transformer is deliberately small&#8212;about 100K parameters, nothing like the billions in language models. Two encoder attention blocks, two linear layers. Input features include latency, timestamp, packet size, flow ID, and receiver ID. The history window is sized to the bandwidth-delay product of the link.</p><p>One nice result from the paper: even when two packets have nearly identical recent latency histories, the Transformer maps them to completely different positions in its internal feature space if one is about to experience a spike. The model learned to detect signals that aren&#8217;t obvious to human inspection.</p><h3>Key Design Choices</h3><p><strong>Custom loss function.</strong> Standard MSE tries to minimize error everywhere. We don&#8217;t care about predicting smooth periods&#8212;we care about catching spikes. SwiftQueue uses a 10&#215; penalty when true latency change exceeds 20ms and 20% relative difference. Trades slightly higher average error for dramatically better spike detection.</p><p><strong>Fast online fine-tuning.</strong> Network conditions change constantly. SwiftQueue only fine-tunes the linear layers using the most recent minute of data&#8212;takes under 30 seconds on a commodity GPU.</p><p><strong>Batched predictions.</strong> At 200 Mbps, you can&#8217;t wait for each ACK before predicting the next packet&#8217;s latency. SwiftQueue predicts batches of up to 8 future packets simultaneously, keeping inference under 400 microseconds.</p><p><strong>Oscillation prevention.</strong> A naive controller could thrash between queues. SwiftQueue includes un-ACKed packets (with queue assignments but not latencies) in the prediction input, so it knows how many packets it&#8217;s already assigned to each queue.</p><h3>Results</h3><p>Evaluated on real traces (Netflix and Facebook traffic over WiFi and Ethernet) and NS-3 simulations:</p><ul><li><p><strong>Prediction accuracy:</strong> 45-65% higher F1 scores on sharp latency changes vs. LSTM and XGBoost baselines</p></li><li><p><strong>Tail latency reduction:</strong> P99 latency drops 36-45% compared to default L4S or LSTM-driven selection</p></li></ul><p>Show Image</p><p><em>SwiftQueue achieves better prediction on sharp changes by 45-65% and reduces P99 tail latency by 36-45% compared to baseline approaches.</em></p><p>Results hold across different network conditions&#8212;even with 500 concurrent flows or 200ms propagation delay.</p><h3>Deployment Reality</h3><p>SwiftQueue has some deployment considerations:</p><ul><li><p><strong>Hardware.</strong> Needs a GPU for fast inference, albeit a cheap one (TITAN RTX, 2GB peak memory utilization). Datacenter-scale with 10+ Gbps links would need beefier hardware.</p></li><li><p><strong>Delayed ACKs.</strong> High propagation delay means less recent information to predict from. The model degrades gracefully but can&#8217;t overcome fundamental information constraints.</p></li><li><p><strong>Scaling.</strong> Handles hundreds of concurrent flows well; thousands would need architectural changes.</p></li><li><p><strong>Congestion control coupling.</strong> SwiftQueue only does queue selection&#8212;doesn&#8217;t touch congestion control. The predictor is trained on specific CC algorithms (primarily DCTCP+L4S) and may not generalize perfectly. TCP BBR&#8217;s probing behavior creates more random-looking patterns.</p></li><li><p><strong>L4S availability.</strong> Assumes L4S-enabled routers along the path. Deployment is growing but not ubiquitous.</p></li></ul><h3>Why This Matters</h3><p>This is part of a broader trend: using ML to make fine-grained, per-packet decisions that were previously impossible. Traditional congestion control operates at the flow level because that&#8217;s what humans could reason about. Neural networks don&#8217;t have that limitation.</p><p>You also don&#8217;t need billions of parameters. A 100K-parameter model, purpose-built for the domain, beats larger general-purpose architectures. Match the architecture to the problem structure.</p><h3>Read More</h3><p>SwiftQueue will appear at the <a href="https://nines-conference.org/">New Ideas in Networked Systems (NINeS) Conference</a> in 2026.</p><div><hr></div><p><em>SwiftQueue: Siddhant Ray, Xi Jiang, Jack Luo, Nick Feamster, Junchen Jiang. University of Chicago. <a href="https://arxiv.org/abs/2410.06112">arXiv:2410.06112</a></em></p>]]></content:encoded></item><item><title><![CDATA[AI Use is not "Cheating". It is Normalized. We Must Teach to This New Reality.]]></title><description><![CDATA[It's well past time to stop talking about "AI detection" snake oil software and think more critically about learning objectives.]]></description><link>https://practicespace.substack.com/p/ai-use-is-not-cheating-it-is-normalized</link><guid isPermaLink="false">https://practicespace.substack.com/p/ai-use-is-not-cheating-it-is-normalized</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Fri, 12 Dec 2025 22:06:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!dYCY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A <a href="https://www.sagepub.com/docs/default-source/corp-comms/ai-and-the-future-of-pedagogy.pdf">recent white paper on AI and pedagogy</a> landed in my inbox the same week my university is debating whether to adopt yet another AI detection tool, at the same time as my university is debating rolling out purported &#8220;AI detection&#8221; software, which I argue in this post is both technologically and pedagogically flawed.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dYCY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dYCY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 424w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 848w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dYCY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2858915,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/181466657?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dYCY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 424w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 848w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!dYCY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fefcc0-132d-4796-9907-7d6123d83dc6_3968x2232.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Teaching AI to high school students earlier this week.</figcaption></figure></div><h2>&#8220;AI Detection&#8221; Software is the Wrong Approach</h2><p>Simply put: Surveillance and policing is the wrong response to pedagogy. </p><p>First, AI detection tools are unreliable at best. Even the latest tools operate at a 5% false positive rate in ideal scenarios. In more challenging conditions&#8212;like a university where students are smart and motivated&#8212;accuracy drops further.</p><p>Second, the harm to students from inevitable false positives is asymmetric. A student accused of academic dishonesty carries the weight of that accusation, regardless of outcome.  </p><div class="pullquote"><p>Perhaps the only good thing about AI detection software is that it is ineffective at achieving the ill-considered goal that it sets out to achieve.</p></div><p>What concerns me more than the technical failures is that <strong>this is fundamentally the wrong way to think about pedagogy</strong>.</p><h2>What I&#8217;ve Learned Actually Using AI in My Teaching</h2><p>I&#8217;ve written before about my approach: I fully encourage the use of AI tools in all my courses. The core principle is simple: <strong>you must understand what you&#8217;re turning in.</strong> I&#8217;ll ask you about it on exams, in discussions, and during assessments. Use whatever tools help you learn and complete your work, but you&#8217;re responsible for understanding the output. I also require attribution&#8212;tell me what assistance you used.</p><p>The classroom is a simulator for the real world, and in the real world, these tools are everywhere. Ignoring them doesn&#8217;t serve our students well.</p><p>But I don&#8217;t just permit AI use&#8212;I&#8217;ve restructured my teaching around it:</p><ul><li><p><strong>Automated class notes.</strong> I take transcripts of my lectures and use LLMs to generate summaries and notes for students. These get posted immediately after every class. (Example: <a href="https://github.com/noise-lab/systems-fall-2024/blob/main/agenda.md">my agenda files on GitHub</a>)</p></li><li><p><strong>AI-assisted exam creation.</strong> I use past exams and instruction files with LLMs to generate draft copies of exams. Even better&#8212;I share the prompts with students so they can generate their own practice exams based on past materials and covered topics. (See <a href="https://github.com/noise-lab/systems-fall-2024/tree/main/exams">the exam generation setup</a>)</p></li><li><p><strong>Discussion preparation.</strong> I use AI to organize student reading responses to prepare better class discussions.</p></li><li><p><strong>Reduced friction.</strong> AI helps me set up environments so students focus on concepts, not configuration.</p></li><li><p>The result? Students spend less time on grunt work and more time on higher-level thinking about security, privacy, and online speech. That&#8217;s what my courses are actually about.</p></li></ul><h2>The Mode Switch</h2><p>Here&#8217;s what I&#8217;ve learned using AI for both pedagogy and my own creative work (I&#8217;ve been building MCP servers to control my Digitakt sequencer and drum machine, learning about music production as a lifelong learner): there&#8217;s a critical distinction between modes of operation.</p><blockquote><p><strong>Are you in push-button mode or evaluation mode?</strong> </p></blockquote><p>When you&#8217;re creating something, are you expressing yourself or having something else do it for you?</p><p>Push-button outputs from LLMs are usually terrible. They produce statistical token completion&#8212;the most likely next word. That&#8217;s exactly what you don&#8217;t want in creative work. You want emotion, lived experience, surprise.</p><p>But using AI to break through a block? To help figure out how to express something that&#8217;s already inside you? That works.</p><p>The principle applies in teaching: Use the tools, absolutely, but ultimately the goal is to further your understanding. If you just copy-paste, you didn&#8217;t learn anything, and the learning objectives were not met. We must instead focus on how to design our pedagogy to achieve the learning objectives.</p><h2>It is Time to Stop with &#8220;AI Shaming&#8221; </h2><p>A colleague recently shared something striking from a survey of undergraduates at our university: about 40% won&#8217;t admit to using AI but are happy to say their peers do. That&#8217;s mathematically impossible if students and their peers are the same population.</p><p>What does this mean? Our students are deeply ashamed of using AI, regardless of whether that use is detrimental or instrumental to learning.</p><p>This culture of &#8220;AI shaming&#8221; harms students&#8212;psychologically and in terms of their ability to leverage their educational experience to prepare for the real world. </p><p>Are policies that encourage policing and punishment of AI use conducive to making our institutions the best they can be right now? I&#8217;d argue no. Blanket bans prevent the very conversations that would help students and faculty distinguish between beneficial and harmful uses.</p><h2>AI as Normal Technology</h2><p>AI is the latest in a long line of cultural and social technologies&#8212;like writing, print, and the internet. I&#8217;ve been making this point for two years: this is just another tool&#8212;like IDEs, Stack Overflow, or GitHub before it. Potentially more powerful, but fundamentally another instrument in the problem-solving toolkit.</p><p>Assessment should be conversation, not surveillance. The question moves from &#8220;What do you know?&#8221; to &#8220;How do you think?&#8221; That&#8217;s exactly what my approach operationalizes: I test comprehension, not compliance.</p><h2>What Forward-Thinking Pedagogy Looks Like</h2><p>Pedagogy will vary widely by course, learning objective, design, mode of interaction, type of assignment, level. I would caution against any prescriptive approach, especially one that generalizes.</p><p>But here are some principles that have worked for me:</p><ul><li><p><strong>Make AI use visible, not hidden.</strong> Build tasks that incorporate AI into the learning process. Require students to explain how they used it, what they learned, what choices they made.</p></li><li><p><strong>Teach prompt design as critical thinking.</strong> Crafting effective prompts is itself a lesson in precision and clarity.</p></li><li><p><strong>Restructure tasks around critical thinking, evaluation of outputs, judgment, testing, and debugging.</strong> Design assignments that require uniquely human contributions and insist on transparent, reflective use of technology.</p></li><li><p><strong>Use AI as complement to group work, not substitute.</strong> Treat interactions with AI as opportunities for consolidating core skills to support participation in peer discussions.</p></li></ul><h2>CS Education Is More Important Than Ever</h2><p>Computer science degrees are becoming more important than ever. These models can assist us and make us more efficient, but they can&#8217;t (yet) do the same level higher-level reasoning and creative thinking that we are capable of&#8212;they automate tasks we specify and lead us to probabilistic likely outcomes and outputs. Such tools are hugely useful&#8212;but only if we know how to integrate them into our workflows and thought processes and adapt them for new ones.</p><p>The real differentiators are what CS degrees teach: abstraction, specification, testing, debugging, and reasoning about complex systems.</p><p>Entry-level isn&#8217;t &#8220;junior developer&#8221; anymore&#8212;it&#8217;s project manager and test engineer. The thinking doesn&#8217;t change. The tools do.</p><p>The real question isn&#8217;t whether to use AI in education&#8212;students are already using it. The question is: Are we teaching them to use it thoughtfully, critically, and ethically? Or are we leaving them to figure it out alone while we chase an unwinnable arms race?</p><div><hr></div><p><em>My previous post on this topic: <a href="https://practicespace.substack.com/p/embracing-ai-in-the-classroom">Embracing AI in the Classroom</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Students Aren’t Asking for Help Anymore. That Could Be a Good Thing.]]></title><description><![CDATA[AI is rapidly disrupting how both students and faculty teach in their classroom. There is no single right approach. The only wrong approach is to ignore it.]]></description><link>https://practicespace.substack.com/p/students-arent-asking-for-help-anymore</link><guid isPermaLink="false">https://practicespace.substack.com/p/students-arent-asking-for-help-anymore</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Tue, 09 Dec 2025 17:25:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9sYD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="pullquote"><p><strong>Bespoke AI tutors and teaching assistants are here and they are replacing the traditional functions of professors and teaching assistants. This is a wake-up call.</strong></p></div><p>Earlier today, a colleague recently shared some striking data from his course this quarter: page views on Ed Discussion down 65%, discussion threads down 48%, comments down 44%. TA office hours are ghost towns. </p><p>Other instructors in our department are reporting similar trends. While it&#8217;s important to distinguish between correlation and causality, the hypothesis is clear: Students are increasingly asking for help from LLMs instead of human instructors (specifically, professors and teaching assistants in office hours).</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Some of my colleagues have responded in particular ways: concern, a bit of alarm, suggestions that we should run all assignments through GPT before releasing them to see what it spits out.  One colleague noted that even plain Google searches now surface LLM-generated responses&#8212;making AI assistance essentially &#8220;unavoidable&#8221; (as LLMs were a technology to be avoided).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9sYD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9sYD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 424w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 848w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 1272w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9sYD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png" width="888" height="453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:453,&quot;width&quot;:888,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:415199,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/181158949?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9sYD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 424w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 848w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 1272w, https://substackcdn.com/image/fetch/$s_!9sYD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7af8159-4853-4b53-9b12-f44bab7d932d_888x453.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Teaching AI to high school students in 2017.</figcaption></figure></div><p><strong>I think this discussion needs a careful re-thinking and framing.</strong></p><h2>The Uncomfortable Reality</h2><div class="pullquote"><p><strong>LLMs are already good tutors and teaching assistants, and they are going to get better.</strong></p></div><p>If students are consulting &#8220;bots&#8221; instead of humans, we should consider the uncomfortable reality that the way we used to do our jobs is potentially quite replaceable. <br><br>As students become more skilled at using these tools and evaluating their outputs&#8212;which is, in part, what we should be training them to do&#8212;the old model of &#8220;ask the TA how to fix your code&#8221; becomes less central to learning.</p><p>This presents both disruption and opportunity.</p><h2>A Different Approach</h2><p>In my courses, I&#8217;ve leaned into this shift rather than fighting it. I give students all of my old homeworks, midterms, and finals. I share full lecture summaries and transcripts. I even share the prompts I used to generate draft exams, so students can create essentially infinite practice material. I&#8217;ve written about my approach to AI in the classroom this year <a href="https://practicespace.substack.com/p/embracing-ai-in-the-classroom">in a previous post</a>.</p><p><strong>I was really nervous about how this would work out. The result? Students loved it.</strong> <br><br>Just as many students came to my office hours as in the past&#8212;and the discussions were much more interesting. They were engaged at a <em>higher</em> level, asking deeper questions rather than asking &#8220;how do I get this to compile?&#8221;-style debugging questions</p><p>I did discover, that, in allowing my students to use LLMs to assist with assignment completion&#8212;a couple of assignments were completed more quickly than in past years. I noted several where it was clear that the assignment was perhaps too &#8220;AI-friendly&#8221;, in the sense that my earlier assignment design makes it a little too easy for students to &#8220;phone it in&#8221; without understanding the learning objectives. </p><p>My response to that, &#8220;in the offseason&#8221;, will be to think about how to tune the assignments and syllabus accordingly&#8212;probably adding a couple more, as well as asking students to think more deeply about the outputs, testing them more on exams on the concepts I want them to be learning. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CKI_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CKI_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 424w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 848w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 1272w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CKI_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png" width="435" height="593.6034115138593" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:469,&quot;resizeWidth&quot;:435,&quot;bytes&quot;:454438,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/181158949?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CKI_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 424w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 848w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 1272w, https://substackcdn.com/image/fetch/$s_!CKI_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd7d6699-7707-49c3-8dd0-12a892eb81bc_469x640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">I, too, used to use a chalkboard.</figcaption></figure></div><p><br><br>In short, we need to think hard about how we adapt learning objectives to these new realities training our students to work with the tools as we prepare them for their eventual occupations. </p><p>And, as educators ourselves, we need to be thinking hard about how to incorporate these tools into our own occupation as educators. That ultimately makes us better educators for two reasons: one, we can teach better having had direct experience with the tools, and two, we can improve our own teaching efficiencies with AI to improve the delivery of our own content and steamlining the logistics of teaching (and anyone who has taught before can appreciate, there are a <em>lot </em>of rote logistics that are ripe for automation).</p><h2>Caveat: Your Mileage May Vary</h2><p>It&#8217;s early days here, and nobody has the answers. In my courses, I treat my students as &#8220;co-learners&#8221; and partners in the journey. I bring value to the classroom, and AI can also bring value&#8212;to myself as an educator, and to the students as learners. The answers are not all clear, but one thing I think is clear even in these early days: The answer is not to ban or police the tools or deny their existence, but to think hard about what integrative approaches can help us achieve learning objectives, which themselves are ultimately going to to evolve.</p><p>And finally, I&#8217;d caution against any prescriptive approach here, especially one that generalizes across all courses and contexts. Pedagogy, material, learning objectives, style of instruction, and general philosophy all matter. What works for a systems course may not work for discrete math. What works for a Master&#8217;s seminar may not work for an intro programming class.</p><p>But if the old indicators of engagement&#8212;Piazza/Ed posts, TA queues&#8212;are dropping, maybe we should ask whether those were ever the right metrics for learning in the first place.</p>]]></content:encoded></item><item><title><![CDATA[To Understand How AI Will Affect Productivity, Look to Agents]]></title><description><![CDATA[Or, how I built a collection of AI agents to act as my personal administrative assistant.]]></description><link>https://practicespace.substack.com/p/to-understand-how-ai-will-affect</link><guid isPermaLink="false">https://practicespace.substack.com/p/to-understand-how-ai-will-affect</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 08 Dec 2025 03:20:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yK30!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>An investor friend asked me today: What&#8217;s your take on AI and workplace productivity?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yK30!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yK30!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!yK30!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!yK30!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!yK30!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yK30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yK30!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!yK30!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!yK30!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!yK30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3030f2e8-9253-4b4e-b3a2-b371e09eaf76_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After some moderanvestment of time and energy on my side, I now have my own administrative assistant. I&#8217;ve spent a chunk of time building model context protocol (MCP) servers that run against my calendar, email, notes, and meeting transcripts. The setup wasn&#8217;t trivial&#8212;this took actual work, actual code, actual debugging&#8212;but the payoff has been immediate and substantial.</p><p>Now I can fire off queries like &#8220;brief me for my meetings today&#8221; or &#8220;find the emails related to my 2pm&#8221; or &#8220;when&#8217;s the best time to schedule a meeting with this person based on my preferences,&#8221; and while the system cranks away, I go do something else. Play guitar. Go for a run. Do laundry. Or&#8212;radical thought&#8212;get on with the actual work that requires my brain.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HvUi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HvUi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 424w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 848w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 1272w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HvUi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png" width="648" height="263" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:263,&quot;width&quot;:648,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42585,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/181007309?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HvUi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 424w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 848w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 1272w, https://substackcdn.com/image/fetch/$s_!HvUi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759f90eb-bac7-40d3-a00e-4df76267fe79_648x263.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The time savings alone would justify the effort. But the real win isn&#8217;t just efficiency. I show up to meetings prepped and briefed. My meetings get scheduled with my actual preferences in mind, the way a human admin would do it. I&#8217;m not burning mental cycles on calendar optimization, or trying to remember what that person emailed me about three weeks ago (or search for it with bad email search tools).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!67aw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!67aw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 424w, https://substackcdn.com/image/fetch/$s_!67aw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 848w, https://substackcdn.com/image/fetch/$s_!67aw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 1272w, https://substackcdn.com/image/fetch/$s_!67aw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!67aw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png" width="629" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:629,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37486,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/181007309?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!67aw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 424w, https://substackcdn.com/image/fetch/$s_!67aw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 848w, https://substackcdn.com/image/fetch/$s_!67aw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 1272w, https://substackcdn.com/image/fetch/$s_!67aw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08ba36d3-a71a-480a-85d4-1e82c209d111_629x220.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>What actually matters: I&#8217;ve reduced time spent on rote tasks significantly, but more importantly, my brain is free for creative thinking&#8212;the kind where I can actually add value. The stuff that requires human judgment, intuition, synthesis. The work that <em>matters</em>.</p><p>I feel like this is the AI productivity story that isn&#8217;t getting enough attention. </p><blockquote><p><strong>It&#8217;s not about AI doing your job for you. It&#8217;s about AI handling the cognitive overhead that prevents you from doing your job well.</strong> </p></blockquote><p>When used well, AI can help us minimize the endless context-switching, the administrative tax, and the mental load of keeping track of everything. We talk a lot about &#8220;augmenting human intelligence&#8221; in the abstract, and this is one example of what it looks like in practice. </p><p>The tools I built are open source: </p><ul><li><p><a href="https://github.com/feamster/spark-mcp">spark-mcp</a> for email and meeting transcripts, and </p></li><li><p><a href="https://github.com/feamster/calendar-mcp">calendar-mcp</a> for calendar management. </p></li></ul><p>They&#8217;re hardly &#8220;production ready&#8221; for the masses, but they work for my needs. They&#8217;ve changed how I work. </p><p>And that idea of &#8220;just good enough&#8221; bespoke tools brings me to my final point. It has become so easy to build these bespoke tools for ourselves, what may ultimately happen to all of the companies that build these kinds of bespoke &#8220;productivity&#8221; tools that revert to the common case but never seem to quite fit anyone&#8217;s specific workflow. I do wonder if many of us will simply build these kinds of tools for ourselves now instead of paying for things that don&#8217;t quite work.</p>]]></content:encoded></item><item><title><![CDATA[The First College of Computing in the U.S. is Now 35 Years Old]]></title><description><![CDATA[Georgia Tech launched a College of Computing years before the commercial Internet.]]></description><link>https://practicespace.substack.com/p/the-first-college-of-computing-in</link><guid isPermaLink="false">https://practicespace.substack.com/p/the-first-college-of-computing-in</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Fri, 05 Dec 2025 05:16:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!g73m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With all of the news of new colleges of computing these days, I find it all the more incredible to think that Georgia Institute of Technology has had a College of Computing for 35 years now. In 1990. Years before the commercial Internet, even.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g73m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g73m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 424w, https://substackcdn.com/image/fetch/$s_!g73m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 848w, https://substackcdn.com/image/fetch/$s_!g73m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 1272w, https://substackcdn.com/image/fetch/$s_!g73m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g73m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png" width="1089" height="742" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:742,&quot;width&quot;:1089,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:786466,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180771075?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g73m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 424w, https://substackcdn.com/image/fetch/$s_!g73m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 848w, https://substackcdn.com/image/fetch/$s_!g73m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 1272w, https://substackcdn.com/image/fetch/$s_!g73m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde53fc5b-b3e3-40f6-b4ce-149508fc8073_1089x742.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Think about that timing for a moment. In 1990, Tim Berners-Lee was still working on the first web browser at CERN. Most people had never heard of email. The idea that computer science would become as fundamental to modern life as it has&#8212;that it would reshape everything from how we communicate to how we work to how we think&#8212;was far from obvious. And yet Georgia Tech made a bet that computer science deserved to stand on its own, separate from electrical engineering, as a full college.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4LEz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4LEz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4LEz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:301549,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/180771075?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4LEz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4LEz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F987610ca-effe-42c7-916e-b3d309c1c4ee_1600x1200.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While I don&#8217;t know the full history of the establishment of the College, I remember hearing stories about how the restructuring was quite controversial at the time. I can only imagine what those faculty meetings must have been like. Academic reorganizations are never easy, and this one was particularly bold. It meant pulling computer science out from under the traditional engineering umbrella and giving it independence, resources, and autonomy. That kind of move doesn&#8217;t happen without fierce debate and, I imagine, some bruised egos along the way.</p><p>Even when I started there as an assistant professor in 2006&#8212;sixteen years after the College was established&#8212;I remember thinking that the structure was pretty unusual. As a fresh Ph.D. graduate, I really couldn&#8217;t wrap my head around it. The thought of CS in a completely separate department from EE seemed utterly foreign to me at the time. I had come from a world where computer science and electrical engineering were tightly coupled, where the organizational chart reflected the historical reality that computing had emerged from electrical engineering. Separating them felt almost unnatural.</p><p>But so many faculty there, including and especially Ellen Zegura, sold me on the College, saying how advantageous this structure was. I took a leap of faith at the time, but over the years it has become increasingly clear to me how right she was about this&#8212;and many other things. Organizational structure is critical for innovation, in scholarship as it is in anything. When you give a field room to define itself on its own terms, rather than as a subset of something else, it can move faster and think bigger.</p><p>I think it&#8217;s one of the reasons Georgia Tech has been able to remain so agile in thinking about CS over the years. The Online MS in CS program, which launched in 2014 and ultimately reached over a million students worldwide, was a radical experiment in making high-quality graduate education accessible at scale. The Threads curriculum reimagined how to teach computer science by letting students weave together their own path through the discipline rather than following a rigid sequence. And more recently, the School of Cybersecurity and Privacy represents yet another structural innovation, recognizing that security and privacy have become foundational concerns that deserve their own institutional home.</p><p>None of these innovations were guaranteed to work. All of them required institutional flexibility, a willingness to experiment, and the kind of autonomy that comes from having your own college rather than being a department within someone else&#8217;s college. When you have to negotiate with other departments over every curriculum change or new program, innovation slows to a crawl. When you have the independence to move quickly, you can try things that other institutions can&#8217;t.</p><p>The more experience and perspective I accrue, the more impressed I am that Georgia Tech did this so early, and even more so that they pulled it off in the face of what must have been incredible resistance at the time. It amazes me every time I think about it. Someone&#8212;or more likely, a group of people&#8212;had the vision to see that computer science was going to be massive and the courage to fight for the institutional structure to support that vision. They were willing to endure the controversy and discomfort of reorganization for something that wouldn&#8217;t fully pay off for years or even decades.</p><p>Now, 35 years later, other universities are catching on. We&#8217;re seeing new colleges of computing announced with great fanfare, as if the idea is novel. And maybe for those institutions, it is. To me, this just makes it all the more incredible that Georgia Tech figured this out in 1990, when it was far from obvious that this was the right move.</p><p>That kind of foresight and institutional courage is worth celebrating, and learning from.</p>]]></content:encoded></item><item><title><![CDATA[The Router Configuration Checker at 20: The Birth of Static Network Configuration Analysis]]></title><description><![CDATA[This year marks the 20-year anniversary of rcc, our pioneering research and software on static verification of router configurations.]]></description><link>https://practicespace.substack.com/p/the-router-configuration-checker</link><guid isPermaLink="false">https://practicespace.substack.com/p/the-router-configuration-checker</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Wed, 03 Dec 2025 06:31:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!H74D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>On <a href="https://www.nbcnews.com/news/us-news/amazon-web-services-outage-websites-offline-rcna238594">October 20, 2025</a>, Amazon Web Services experienced a massive outage that took down Snapchat, McDonald&#8217;s app, Ring doorbells, Roblox, Fortnite, and thousands of other services worldwide. The culprit? A DNS resolution failure triggered by a faulty configuration update. Just over a year earlier, <a href="https://en.wikipedia.org/wiki/2024_CrowdStrike-related_IT_outages">CrowdStrike&#8217;s configuration error</a> caused what has been called the largest IT outage in history, crashing 8.5 million Windows systems and causing an estimated $10 billion in damage. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Twenty years after these kinds of configuration errors first motivated my Ph.D. thesis research, they remain one of the primary causes of network and system outages.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!H74D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!H74D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!H74D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!H74D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!H74D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!H74D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!H74D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!H74D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!H74D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!H74D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799aaff3-a8e9-4226-96f3-ace98f9b2905_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>In May 2005, my advisor Hari Balakrishnan and I published <a href="https://www.usenix.org/legacy/event/nsdi05/tech/feamster/feamster.pdf">&#8220;Detecting BGP Configuration Faults with Static Analysis&#8221;</a>. The tool was called rcc (Router Configuration Checker), and it introduced static analysis of router configurations before deployment. Studies at the time showed that 50-80% of network outages were caused by configuration errors. Two decades later, that fundamental problem persists&#8212;though the systems have gotten vastly more complex.</p><h2>The Problem in 2005</h2><p>In the mid-2000s, network operators were managing increasingly complex routing infrastructures with no systematic way to verify correctness. The state of the art was to push configurations to production routers and see what breaks. When something went wrong, operators would scramble to diagnose the problem and roll back changes.</p><p>Configuring routers in an autonomous system is essentially writing a distributed program, but we were doing it with none of the verification tools that software engineers take for granted. BGP&#8217;s flexible configuration language made it powerful but error-prone. Operators had to manually decompose network-wide policies into device-level configurations across potentially thousands of BGP sessions, with complex interactions between iBGP, eBGP, route reflection, and filtering policies.</p><h2>The Approach</h2><p>rcc introduced static analysis of router configurations before deployment to detect faults automatically.</p><p>The approach was to parse vendor-specific configuration files, normalize them into a vendor-independent representation using relational database tables, and then check constraints based on a correctness specification. No need to run configurations in a live network or build expensive emulation environments.</p><p>rcc focused on detecting two broad classes of BGP configuration faults:</p><p><strong>Route validity faults</strong>: Where routers might learn routes that don&#8217;t correspond to usable paths. This included issues like:</p><ul><li><p>Invalid AS paths being propagated</p></li><li><p>Next-hop addresses unreachable via IGP</p></li><li><p>Undefined references to filters and route maps</p></li><li><p>Improper or missing route filtering</p></li></ul><p><strong>Path visibility faults</strong>: Where routers fail to learn routes for paths that exist in the network. The classic example was iBGP configuration errors&#8212;particularly with route reflection&#8212;that could cause network partitions where some routers never learn about certain destinations.</p><h2>What We Found</h2><p>We analyzed BGP configurations from 17 real-world networks. rcc found errors in every network. Most operators were unaware of these errors, which ranged from simple single-router problems like undefined variables to complex multi-router interactions.</p><p>The errors we uncovered included:</p><ul><li><p>Potential network partitions caused by route propagation problems</p></li><li><p>Invalid routes being propagated due to improper filtering</p></li><li><p>Routers forwarding packets inconsistently with high-level policy</p></li><li><p>420 incomplete iBGP sessions across the networks we studied</p></li></ul><p>Many of these errors were latent&#8212;not actively causing problems yet, but violations of correctness that would manifest under certain conditions. For example, misconfigured backup paths that would only fail after a primary link went down.</p><h2>Why Configuration Errors Happen</h2><p>Our analysis revealed three main causes:</p><ol><li><p><strong>Complex propagation mechanisms</strong>: The techniques used to scalably propagate routes within a network&#8212;particularly route reflection with clusters&#8212;are easily misconfigured.</p></li><li><p><strong>Levels of indirection</strong>: Even simple policy specifications get implemented using multiple layers of indirection in configuration files (distribute lists, prefix lists, route maps, community values).</p></li><li><p><strong>No systematic process</strong>: Most operators had no disciplined approach to network configuration. There were no configuration management tools, no testing frameworks, no verification.</p></li></ol><h2>The Impact</h2><p>rcc won Best Paper at NSDI 2005. The tool was open-sourced and is still on GitHub at <a href="https://github.com/noise-lab/rcc">github.com/noise-lab/rcc</a>. Operators used it to find and fix bugs before deployment.</p><p>The bigger impact was establishing static configuration verification as a research area. rcc showed that you could reason formally about network behavior from configuration files alone, without needing access to live networks or running emulation.</p><h2>The Research Lineage</h2><p>Over the past 20 years, researchers have built on rcc&#8217;s foundation with increasingly sophisticated techniques:</p><p><strong>Header Space Analysis (2012)</strong>: Kazemian, Varghese, and McKeown extended static analysis from the control plane to the data plane, introducing geometric representations of packet header spaces.</p><p><strong>Batfish (2015)</strong>: Fogel, Mahajan, Millstein and colleagues built a general-purpose configuration analysis tool using Datalog and logic programming, extending beyond BGP to multi-protocol networks.</p><p><strong>Minesweeper (2017)</strong>: Beckett et al. developed SMT-based verification for a wide range of properties including reachability, waypointing, and fault tolerance.</p><p>These tools advanced the techniques for network verification&#8212;new representations, new algorithms, broader protocol coverage. But they all built on the paradigm rcc established: that you can and should verify network configurations statically before deployment.</p><h2>Key Design Decisions</h2><p>Several design decisions proved important:</p><p><strong>Vendor-independent representation</strong>: By parsing vendor configs into normalized relational tables, we separated the parsing problem from the analysis problem. This pattern has been followed by every subsequent tool.</p><p><strong>Focus on correctness, not optimality</strong>: rcc didn&#8217;t try to find the &#8220;best&#8221; configuration&#8212;it found wrong configurations.</p><p><strong>Constraint-based approach</strong>: Rather than requiring operators to write formal specifications, rcc checked constraints that must hold for any correct configuration.</p><p><strong>Static analysis</strong>: No need for live network access, no emulation overhead, no waiting for convergence. You could verify configurations as fast as you could parse and analyze them.</p><h2>What&#8217;s Changed in 20 Years</h2><p>Networks have gotten more complex. We&#8217;ve added software-defined networking, cloud and multi-cloud environments, container networking, network functions virtualization, and programmable data planes. Configuration errors are more consequential than ever. A misconfiguration in a cloud environment can expose thousands of customers&#8217; data. An error in SDN controller logic can take down an entire data center. A faulty configuration update can crash millions of systems worldwide, as we saw with CrowdStrike.</p><h2>Looking Forward: LLMs and the Next Generation</h2><p>While outages persist and are often due to increasingly complex software and configuration errors, there is hope that tools with more sophisticated reasoning capabilities will ultimately help us reason about these errors. The rise of large language models has opened new approaches to the problems rcc was designed to solve.</p><p>Our recent work on <a href="https://arxiv.org/abs/2411.14283">CAIP (Context-Aware Iterative Prompting)</a> demonstrates how LLMs can detect router misconfigurations with over 30% better accuracy than traditional model checkers and consistency checkers, finding over 20 previously undetected misconfigurations in real-world configurations. Unlike traditional tools that require significant manual effort to develop and maintain for each new protocol or vendor, LLMs can learn patterns from vast datasets and apply them across layers and vendors.</p><p>This makes the verification that rcc pioneered feasible for much larger and more complex systems&#8212;from multi-protocol networks to cross-vendor translations to intent-based configuration generation. The fundamental insight remains the same: configuration errors are preventable through analysis before deployment. But LLMs are making that analysis practical at scales and across domains we couldn&#8217;t have imagined in 2005.</p><p>The AWS and CrowdStrike outages remind us that configuration errors remain a critical challenge. But they also show us that the problem rcc addressed two decades ago is more important than ever&#8212;and that new techniques building on that foundation offer genuine hope for finally getting ahead of these errors.</p><p><em>The original rcc paper: &#8220;Detecting BGP Configuration Faults with Static Analysis,&#8221; Nick Feamster and Hari Balakrishnan, NSDI 2005. <a href="https://www.usenix.org/legacy/event/nsdi05/tech/feamster/feamster.pdf">PDF</a></em></p><p><em>Recent work: &#8220;CAIP: Detecting Router Misconfigurations with Context-Aware Iterative Prompting of LLMs,&#8221; Xi Jiang, Aaron Gember-Jacobson, and Nick Feamster, 2024. <a href="https://arxiv.org/abs/2411.14283">arXiv</a></em></p><pre><code><code>@inproceedings{feamster2005rcc,
  title     = {Detecting {BGP} Configuration Faults with Static Analysis},
  author    = {Feamster, Nick and Balakrishnan, Hari},
  booktitle = {2nd USENIX Symposium on Networked Systems Design and 
               Implementation (NSDI &#8216;05)},
  year      = {2005},
  month     = {May},
  address   = {Boston, MA},
  publisher = {USENIX Association},
  url       = {https://www.usenix.org/legacy/event/nsdi05/tech/feamster/feamster.pdf},
  note      = {Best Paper Award}
}
</code></code></pre>]]></content:encoded></item><item><title><![CDATA[A New Home for Networking and AI Research]]></title><description><![CDATA[Re-launching the Network Operations and Internet Security Lab website to better reflect the lab's mission]]></description><link>https://practicespace.substack.com/p/a-new-home-for-networking-and-ai</link><guid isPermaLink="false">https://practicespace.substack.com/p/a-new-home-for-networking-and-ai</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Fri, 28 Nov 2025 20:51:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9gBQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <a href="https://noise-lab.net/">NOISE Lab</a> website has a new look. After some long-overdue updates, <a href="https://noise-lab.net/">noise-lab.net</a> now better reflects the breadth and depth of our research program at the <a href="https://cs.uchicago.edu/">University of Chicago</a>. The redesign organizes our work around four interconnected research themes:</p><ul><li><p><strong>AI and Machine Learning for Networking</strong> &#8212; generative models for synthetic traffic, traffic classification, and operational analytics</p></li><li><p><strong>Internet Access and Broadband Measurement</strong> &#8212; tools and data for understanding network performance in homes and communities</p></li><li><p><strong>Internet Censorship and Online Speech</strong> &#8212; measuring and circumventing global Internet filtering</p></li><li><p><strong>Security and Privacy</strong> &#8212; protecting users from threats posed by IoT devices and network traffic analysis</p></li></ul><p>Here&#8217;s a quick tour of what you&#8217;ll find.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>AI and Machine Learning for Networking</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9gBQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9gBQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9gBQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9gBQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!9gBQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e113f40-aa60-4fc0-b0a7-0a98640f4228_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is perhaps the area where we&#8217;ve seen the most exciting recent progress. The scarcity of high-quality, labeled network traffic datasets has long been a bottleneck for applying machine learning to networking problems&#8212;privacy concerns, data staleness, and access restrictions have made it difficult to train models effectively.</p><p>Our response has been to develop generative AI techniques that can produce realistic, protocol-compliant synthetic network traffic. <a href="https://github.com/noise-lab/NetDiffusion_Generator">NetDiffusion</a> uses a fine-tuned <a href="https://stability.ai/stable-diffusion">Stable Diffusion</a> model to generate packet captures that closely mimic real network data while adhering to protocol specifications. More recently, <a href="https://arxiv.org/abs/2503.22663">NetSSM</a> applies state-space models to generate multi-flow network traces that capture the complex temporal dependencies between simultaneous network conversations. These tools are helping researchers train better ML models for traffic classification, anomaly detection, and network security&#8212;without needing access to sensitive real-world data.</p><p>Beyond data generation, we&#8217;re developing techniques for traffic classification, predictive modeling, and operational analytics. This includes work on efficient representations for network data through tools like <a href="https://github.com/noise-lab/netml">netml</a>, and models that can handle the practical challenges of deployment, like cost sensitivity and <a href="https://netml.io/blog/2023/leaf/">model drift</a>. <br><br>You can read more about our ML for networking research on <a href="https://netml.io/">netml.io</a>.</p><h2>Internet Access and Broadband Measurement</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GiN4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GiN4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GiN4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GiN4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!GiN4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F687a7e85-81ef-4c6e-ad0b-b2250b5aa0b7_1024x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Understanding how people actually experience the Internet requires measuring it where it matters most: in homes and communities. Our <a href="https://internetequity.org/">Internet Innovation Initiative</a> develops new tools to measure broadband access and performance, working with community partners to make high-speed Internet accessible to all.</p><p>This work builds on a long history of broadband measurement, including the <a href="https://projectbismark.net/">BISmark</a> project and our collaborations with the <a href="https://www.fcc.gov/">FCC</a> to develop technologies for understanding access network performance across the United States. Today, we deploy <a href="https://github.com/internet-equity/netrics">Netrics</a> devices in homes across Chicago and beyond, gathering continuous, granular data that enables comparisons of Internet experience across neighborhoods with different socioeconomic profiles. The goal isn&#8217;t just measurement for its own sake&#8212;it&#8217;s producing actionable insights that can inform policy and investment decisions to close the digital divide. </p><p>You can explore our open-source tools and datasets at <a href="https://internet-innovation.github.io/">internet-innovation.github.io</a>.</p><h2>Internet Censorship and Online Speech</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zmu1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zmu1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zmu1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zmu1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!zmu1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9471a73-bad2-4409-af5b-297a1c43901d_1024x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>More than 60 countries perform some form of Internet censorship. Our group has been developing technologies to measure and mitigate censorship for over two decades, producing a series of firsts: <a href="https://dl.acm.org/doi/10.1145/964725.633156">Infranet</a> (2002), the first system to use covert channels for circumvention; <a href="https://www.usenix.org/conference/usenixsecurity10/collage-defeating-censorship-user-generated-content">Collage</a> (2009), which used user-generated content platforms as drop sites; <a href="https://dl.acm.org/doi/10.1145/2785956.2787485">Encore</a> (2015), the first system for global, real-time measurement of Web censorship; and <a href="https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/pearce">Iris</a> (2017), the first system to detect widespread DNS manipulation.</p><p>Current work focuses on <a href="https://datascience.uchicago.edu/news/using-ai-and-data-science-to-reliably-detect-internet-censorship-in-real-time/">applying AI to detect censorship in real time</a>. We&#8217;re training models to identify the &#8220;fingerprints&#8221; of filtering devices by analyzing how they manipulate traffic, with the goal of creating a real-time &#8220;weather map&#8221; for censorship&#8212;where observers can see Internet interference as it happens, which sites are being targeted, and in which countries. Recent work has developed more robust <a href="https://arxiv.org/abs/2302.02031">machine learning techniques for censorship detection</a> that can discover new blocking signatures missed by existing heuristics.</p><h2>Security and Privacy</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nv7P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nv7P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nv7P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png" width="1024" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Nv7P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!Nv7P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd1686b23-e63a-4082-bf69-ae1ad17205d5_1024x608.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The proliferation of connected devices creates new security and privacy challenges. Smart home IoT devices interact with multiple people, respond to environmental triggers, and operate in a fragmented ecosystem&#8212;none of which fits well with traditional security approaches designed for single-user, keyboard-and-screen computing.</p><p>Our <a href="https://noise-lab.net/iot-lab.html">IoT Lab</a> provides a testbed for studying these devices, where we&#8217;ve investigated everything from the <a href="https://dl.acm.org/doi/10.1145/3319535.3354198">tracking behavior of Smart TVs</a> to <a href="https://dl.acm.org/doi/10.1145/3139937.3139939">cleartext data transmissions in consumer medical devices</a>. We developed <a href="https://inspector.engineering.nyu.edu/">IoT Inspector</a>, a tool that crowdsources labeled network traffic from smart home devices to detect hidden security and privacy violations. We&#8217;re also working on <a href="https://noise.cs.uchicago.edu/security.html">DNS privacy</a>, designing protocols and systems to improve privacy properties even when encrypted DNS solutions are in use.</p><p>A key insight from this work is that network traffic itself reveals information users may want to keep private&#8212;eavesdroppers can <a href="https://arxiv.org/abs/1708.05044">infer in-home behaviors</a> just from traffic rate patterns, even when the content is encrypted. Our research explores both how to detect these threats and how to mitigate them through techniques like <a href="https://petsymposium.org/2019/files/papers/issue3/popets-2019-0040.pdf">smart traffic shaping</a>.</p><h2>Education and Courses</h2><p>We&#8217;re committed to making our research accessible through teaching. </p><p>I regularly offer courses on <a href="https://noise-lab.net/courses.html">machine learning for network security</a>, <a href="https://noise-lab.net/courses.html">Internet censorship</a>, and <a href="https://noise-lab.net/courses.html">security and privacy</a> to undergraduate and graduate students at UChicago. </p><p>For online learners, our <a href="https://www.coursera.org/learn/sdn">Software Defined Networking</a> and <a href="https://www.coursera.org/learn/applied-machine-learning">Applied Machine Learning</a> MOOCs on Coursera have reached millions of students worldwide&#8212;the SDN course was one of the first of its kind and helped launch Georgia Tech&#8217;s <a href="https://omscs.gatech.edu/">Online Masters in Computer Science</a> program. </p><p>Free instructional videos are also available on the <a href="https://youtube.com/c/nfeamster">nfeamster YouTube channel</a>. </p><p>See the full list of courses at <a href="https://noise-lab.net/courses.html">noise-lab.net/courses.html</a>. I continue to add more courses and content on these topics, so please subscribe and stay tuned for more updates! </p><div><hr></div><p>The redesigned site also highlights our commitment to <a href="https://github.com/noise-lab/">open-source software</a>, real-world deployments, and <a href="https://noise.cs.uchicago.edu/outreach.html">outreach</a>&#8212;from educational programs for underrepresented students to policy comments on spectrum allocation and data privacy. Take a look around, and <a href="mailto:feamster@uchicago.edu">reach out</a> if you&#8217;re interested in learning more about the group or how to get involved.</p><p><a href="https://noise-lab.net/">noise-lab.net</a></p>]]></content:encoded></item><item><title><![CDATA[Building Multi-MCP Server Workflows With Claude]]></title><description><![CDATA[I now use Claude to have my email and calendaring talk to one another]]></description><link>https://practicespace.substack.com/p/building-multi-mcp-server-workflows</link><guid isPermaLink="false">https://practicespace.substack.com/p/building-multi-mcp-server-workflows</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 24 Nov 2025 21:59:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LBcm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently built an MCP server for Google Calendar. It&#8217;s called <code>calendar-mcp</code> and it&#8217;s <a href="https://github.com/feamster/calendar-mcp">on GitHub</a>. I also have one for email and meeting transcripts called <code>spark-mcp</code> (<a href="https://github.com/feamster/spark-mcp">also on GitHub</a>). Together they let Claude access my schedule and communications in a single conversation.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LBcm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LBcm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 424w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 848w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LBcm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png" width="1456" height="1127" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1127,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:201983,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/179865146?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LBcm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 424w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 848w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 1272w, https://substackcdn.com/image/fetch/$s_!LBcm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dbebae6-9411-4b1d-8a3c-47059d50ff19_1540x1192.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>What These Servers Do</h2><p><strong>calendar-mcp</strong> gives Claude access to Google Calendar:</p><ul><li><p>List events across all calendars (primary, work, shared)</p></li><li><p>Find when I last met with someone</p></li><li><p>Create events and send invitations</p></li><li><p>Accept/decline calendar invites</p></li><li><p>Find optimal meeting times based on configured preferences</p></li><li><p>Analyze time blocks (deep work vs. flexible time)</p></li></ul><p><strong>spark-mcp</strong> gives Claude access to email and meeting transcripts:</p><ul><li><p>Search and read emails</p></li><li><p>Find emails needing responses</p></li><li><p>Extract action items from messages</p></li><li><p>Access meeting transcripts</p></li><li><p>Search transcript content</p></li></ul><h2>Using Them Together</h2><p>The useful part is running both servers at once. Claude can pull from either system as needed, which means queries can span both without any extra work on my end.</p><p>Some examples of what this looks like:</p><p><strong>&#8220;What do I need to be prepared for tomorrow?&#8221;</strong></p><p>Claude checks the calendar for tomorrow&#8217;s meetings, then searches emails for recent threads with those attendees. I get a briefing that includes both the meeting details and relevant email context.</p><p><strong>&#8220;What were the action items from my meeting with Andrew last Tuesday?&#8221;</strong></p><p>Claude finds the meeting on the calendar, pulls the transcript from spark-mcp, and extracts the action items. One query, two systems.</p><p><strong>&#8220;Do I have any emails I need to respond to before my 2pm?&#8221;</strong></p><p>Claude checks pending responses in email, cross-references with the calendar to see what&#8217;s at 2pm, and prioritizes accordingly.</p><p><strong>&#8220;Find a time to meet with Sarah next week and draft an email inviting her.&#8221;</strong></p><p>Claude uses calendar-mcp to find available slots (respecting my preferences), then uses the email context to draft an appropriate message.</p><h2>Why LLMs Beat Existing Solutions: <br>Understanding Soft Preferences</h2><p>calendar-mcp has a configuration file for scheduling preferences:</p><pre><code><code>{
  &#8220;preferredDays&#8221;: {
    &#8220;Wednesday-PM&#8221;: 100,
    &#8220;Thursday&#8221;: 100,
    &#8220;Monday-PM&#8221;: 70,
    &#8220;Tuesday&#8221;: 40,
    &#8220;Friday&#8221;: 40
  },
  &#8220;preferAdjacentToMeetings&#8221;: true,
  &#8220;avoidDeepWorkBlocks&#8221;: true,
  &#8220;neverAvailablePatterns&#8221;: [&#8221;kids&#8221;]
}
</code></code></pre><p>When finding meeting times, Claude ranks options by these preferences. Wednesday afternoons and Thursdays score highest. It looks for slots adjacent to existing meetings to consolidate context-switching. It avoids blocks marked as deep work. Events with &#8220;kids&#8221; in the title are treated as immovable.</p><h2>Setup</h2><p>Both servers require OAuth setup with Google APIs&#8212;Calendar API for calendar-mcp, Gmail API for spark-mcp. The README files walk through the process. Once authenticated, you add them to your Claude Desktop config:</p><pre><code><code>{
  &#8220;mcpServers&#8221;: {
    &#8220;calendar&#8221;: {
      &#8220;command&#8221;: &#8220;python&#8221;,
      &#8220;args&#8221;: [&#8221;-m&#8221;, &#8220;calendar_mcp.server&#8221;],
      &#8220;cwd&#8221;: &#8220;/path/to/calendar-mcp&#8221;
    },
    &#8220;spark&#8221;: {
      &#8220;command&#8221;: &#8220;python&#8221;, 
      &#8220;args&#8221;: [&#8221;-m&#8221;, &#8220;spark_mcp.server&#8221;],
      &#8220;cwd&#8221;: &#8220;/path/to/spark-mcp&#8221;
    }
  }
}
</code></code></pre><p>Restart Claude Desktop and both servers are available.</p><h2>Why This Works</h2><p>MCP servers are additive. Each one gives Claude access to a different system, and Claude figures out which tools to use based on the query. I don&#8217;t have to think about which server handles what&#8212;I just ask questions and Claude routes appropriately.</p><p>The combination of calendar and email covers most of my organizational needs. I can check my schedule, find context from past communications, schedule new meetings, and respond to emails all in the same conversation where I&#8217;m doing actual work.</p><div><hr></div><p><em>Both projects are open source: <a href="https://github.com/feamster/calendar-mcp">calendar-mcp</a> and <a href="https://github.com/feamster/spark-mcp">spark-mcp</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Lessons from My First Live Loop Performance]]></title><description><![CDATA[I&#8217;ve been experimenting with live looping in my home studio for months now, layering guitar parts and vocals, building arrangements one pass at a time.]]></description><link>https://practicespace.substack.com/p/lessons-from-my-first-live-loop-performance</link><guid isPermaLink="false">https://practicespace.substack.com/p/lessons-from-my-first-live-loop-performance</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Sat, 22 Nov 2025 21:05:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oZus!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oZus!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oZus!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 424w, https://substackcdn.com/image/fetch/$s_!oZus!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 848w, https://substackcdn.com/image/fetch/$s_!oZus!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 1272w, https://substackcdn.com/image/fetch/$s_!oZus!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oZus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png" width="836" height="718" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:718,&quot;width&quot;:836,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:903661,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/179674214?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oZus!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 424w, https://substackcdn.com/image/fetch/$s_!oZus!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 848w, https://substackcdn.com/image/fetch/$s_!oZus!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 1272w, https://substackcdn.com/image/fetch/$s_!oZus!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a948c55-8de8-4e24-ab81-08acca19548b_836x718.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>I&#8217;ve been experimenting with live looping in my home studio for months now, layering guitar parts and vocals, building arrangements one pass at a time. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Last night, I performed with a live looper for the first time. Performing live with loops is a different animal entirely. It&#8217;s not just about the technology; it&#8217;s about managing time, recovering from mistakes, and learning to trust the layers you&#8217;re building in real-time while an audience watches.</p><div id="youtube2-KRZhhfjo3kQ" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;KRZhhfjo3kQ&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/KRZhhfjo3kQ?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Here are some lessons I took away.</p><h3><strong>Tempo Sync Gives and Takes Away</strong></h3><p>I was looping two tracks with tempo sync set, which ensures that different parts of the song, like verse and chorus, stay at a common tempo. </p><p>I learned a crucial lesson: if you&#8217;re using tempo sync, it&#8217;s best to have click or drum track running when you lay down your foundation, especially when you shift from verse to chorus. On the verse, it matters less because you&#8217;re establishing the tempo and you&#8217;re tapping out the beat. As you switch to chorus, however, the track assumes that you&#8217;re hitting exactly the same tempo, and even a little drift will cause chaos.</p><p>On one song, I started a chorus loop without the reference beat going. I was maybe 20 milliseconds off&#8212;nothing you&#8217;d notice on the first repetition. But loops are precise. That tiny error compounds with each cycle. By the fourth time through, I was noticeably chasing or dragging against my own playing. </p><p>It&#8217;s disorienting in a way that&#8217;s hard to describe: you&#8217;re simultaneously ahead of and behind yourself.</p><h3><strong>You&#8217;re the Bandmate and the Conductor</strong></h3><p>Playing with loops feels remarkably like playing with a band&#8212;with one critical difference. When you mess up in a band, the other musicians keep going and you find your way back in. With loops, the band keeps going too, but <em>you&#8217;re</em> also responsible for conducting them with your feet.</p><p>Miss your cue to transition to the bridge? The loop stays locked in the chorus. Forever. Or until you manually break the cycle.</p><p>I found myself literally stuck in a loop during the bridge transition, my foot hovering over the pedal, trying to find the exact moment to switch parts while singing and playing guitar. It requires a kind of split attention that&#8217;s genuinely difficult: you&#8217;re performing for the audience while simultaneously managing a set of time-synchronized tracks that need precise coordination.</p><h3><strong>You Always Have the Option to Clear, and It&#8217;s Often a Good Idea</strong></h3><p>Sometimes the best recovery from a drifting loop is to blow it up and start over.</p><p>If you&#8217;re noticeably out of sync, trying to force your way back into alignment rarely works. You end up fighting yourself. Instead, I learned to keep playing the current section smoothly for the audience while quietly clearing the problematic loop in the background. Then, when the progression cycles back around, you lay down a fresh, properly-synced foundation.</p><h3><strong>The Blessing of Diatonic Harmony</strong></h3><p>While loops are unforgiving masters when it comes to tempo sync, they are also more forgiving than they seem, thanks to diatonic harmony.</p><p>Afterward, multiple people told me it sounded great and they didn&#8217;t notice a single mistake. How? The layers give you cover.</p><p>When you&#8217;re working within a diatonic framework&#8212;all your chords belong to the same key&#8212;even a slightly misaligned loop won&#8217;t sound dissonant. <br><br>The worst that happens is some rhythmic ambiguity or harmonic density that might actually sound intentional. Your verse chords and chorus chords are all swimming in the same tonal pool, so as long as you recover quickly, the ear tends to forgive the temporary confusion.</p><p>This doesn&#8217;t mean you can be sloppy. But it does mean that the margin for error is wider than it feels in the moment. The perfectionism that serves you in the studio can become paralyzing on stage.</p><h3><strong>Think About Looping Like a Mix</strong></h3><p>After the set, someone gave me a tip that should have been obvious but wasn&#8217;t: treat your loop layers like you would tracks in a mix.</p><p>In the studio, you don&#8217;t record everything at the same volume with the same tone. You adjust EQ, panning, dynamics&#8212;you carve out space for each element. The same principle applies to live looping, but you have to think about it <em>before</em> you hit record on each layer.</p><p>Switch pickups between layers. Move from playing near the bridge to playing near the neck. Adjust your volume knob. Play some parts with more attack, others with a softer touch. Each layer should sit in its own part of the sonic spectrum.</p><p>This was a revelation. I&#8217;d been thinking of looping as &#8220;record parts and stack them,&#8221; when I should have been thinking &#8220;how does this layer fit in the arrangement I&#8217;m building?&#8221; That rhythm part doesn&#8217;t need to be as loud as the melody. That bass line can be warmer and rounder. That harmonic fill can be brighter and more percussive.</p><p>You&#8217;re not just a performer when you&#8217;re looping&#8212;you&#8217;re also the engineer, making mix decisions in real-time with the only tools available: your hands, your pickup selector, and your volume knob.</p><h3><strong>The Paradox of Layers</strong></h3><p>Live looping presents a fascinating paradox. Each layer you add:</p><ul><li><p>Makes the arrangement richer and more forgiving</p></li><li><p>But also makes each individual mistake more consequential</p></li><li><p>Creates more sonic space to hide in</p></li><li><p>But also requires more precise coordination to manage</p></li></ul><p>You&#8217;re simultaneously more exposed and more protected than playing solo. It&#8217;s like being in a band where all the members are slightly out-of-phase versions of yourself.</p><h3><strong>What I&#8217;m Taking Forward</strong></h3><p>For next time: click track always on during foundation building. Practice the foot transitions as much as the musical parts. </p><p>Think about each layer&#8217;s place in the mix before recording it. </p><p>Trust the diatonic safety net, but don&#8217;t rely on it. </p><p>And most importantly, stay calm when things drift&#8212;the audience almost certainly won&#8217;t notice unless you show them you&#8217;re panicking.</p><p>Live looping is less like recording and more like a very controlled form of improvisation. You&#8217;re composing in real-time with a collaborator who remembers everything perfectly but can&#8217;t adapt. </p><p>You&#8217;re also mixing in real-time with tools far more limited than any DAW. It&#8217;s challenging in ways I didn&#8217;t expect, and rewarding in ways I&#8217;m still discovering.</p><p>The loop keeps going. You keep going. Sometimes that&#8217;s in perfect sync, and sometimes it&#8217;s not. But as long as you&#8217;re both moving forward, the audience hears a song.</p>]]></content:encoded></item><item><title><![CDATA[We Built Our Own ISP to Fix the Internet. A Decade Later, It’s Still Running.]]></title><description><![CDATA[The PEERING testbed received the Test of Time Award at the 2025 ACM Internet Measurement Conference.]]></description><link>https://practicespace.substack.com/p/we-built-our-own-isp-to-fix-the-internet</link><guid isPermaLink="false">https://practicespace.substack.com/p/we-built-our-own-isp-to-fix-the-internet</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Thu, 20 Nov 2025 21:20:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VxQ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When a major service provider like Amazon or Cloudflare goes offline because of a routing error, as has happened in recent weeks, network engineers have to fix a problem they can&#8217;t see. Somewhere in the Internet&#8217;s routing system, traffic is being sent to the wrong place&#8212;maybe halfway across the world. But studying these failures used to be impossible. You couldn&#8217;t experiment with Internet routing without being an Internet service provider (ISP) yourself.</p><p>The solution? Build your own testbed ISP.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>In 2014, we published &#8220;<a href="https://dl.acm.org/doi/10.1145/2670518.2673887">PEERING: An AS for Us</a>,&#8221; describing a testbed that let researchers experiment with the Internet&#8217;s routing infrastructure for the first time. That work recently received the Test of Time Award from the ACM SIGCOMM Internet Measurement Conference. (The term &#8220;AS&#8221; in the paper&#8217;s title refers to &#8220;Autonomous System&#8221;, which is a technical term for an independently operated network like an ISP).</p><p>The project started under <a href="https://en.wikipedia.org/wiki/Global_Environment_for_Network_Innovations">GENI (Global Environment for Network Innovations)</a>, an NSF-funded program with an ambitious goal: design a future Internet architecture. GENI built infrastructure to let researchers experiment with networking at scale. The system that eventually became PEERING was called <a href="http://conferences.sigcomm.org/sigcomm/2010/papers/sigcomm/p463.pdf">Transit Portal</a>, infrastructure that my Ph.D. student <a href="https://www.linkedin.com/in/vytautas-valas-valancius-6aa382">Valas Valancius</a> and I developed at Georgia Tech to give researchers access to interdomain routing.<br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VxQ8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VxQ8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 424w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 848w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 1272w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VxQ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png" width="740" height="758" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:758,&quot;width&quot;:740,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VxQ8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 424w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 848w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 1272w, https://substackcdn.com/image/fetch/$s_!VxQ8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc20b7e-276a-4c77-9ed8-ed7cd148c82b_740x758.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The GENI and FIND programs had a vision of letting researchers actually experiment with Internet infrastructure and architectures, not just simulate it. I had this idea that it should be possible to experiment with Internet routing on the real Internet. Transit Portal was our way of making that a reality. Actually getting it working&#8212;building the control plane, the safety mechanisms, the whole system&#8212;was a huge design and implementation lift. Valas really got it off the ground.</p><p>Transit Portal leveraged Internet Exchange Points (IXPs), the points in the Internet where networks connect to exchange traffic directly. By connecting to other service providers directly at IXPs, the testbed could peer with hundreds of networks and announce routes just like a real ISP. But the Transit Portal also needed safeguards. Servers sat between researchers and the live network, filtering routes and enforcing policies so a bad experiment couldn&#8217;t break anything.</p><p>The challenge wasn&#8217;t just technical. We had to convince operators at major IXPs like AMS-IX in Amsterdam to let us plug academic research infrastructure into their production network. That required trust, and we had to earn it.</p><p>After the GENI program ended, Transit Portal might have disappeared like so many research prototypes do when funding ends and students graduate. Instead, Professor <a href="http://www.columbia.edu/~ebk2141/">Ethan Katz-Bassett</a> and his team at USC, and later at Columbia, took over leadership of the project and continue to maintain it to this day. They expanded it to more IXPs, maintained the infrastructure, developed new capabilities, and continue to actively support the research community&#8217;s use of the testbed. <br><br>PEERING has flourished because of Ethan and his team. They&#8217;ve kept it running for more than a decade, expanded it, and supported the research community. That sustained effort&#8212;deploying at IXPs, maintaining the system, making it possible for so many researchers to actually use it&#8212;that&#8217;s why the work has stood the test of time. They deserve enormous credit. This work has stood the test of time and remains one of the main lasting, impactful legacies of the GENI program, in large part due to Ethan&#8217;s ongoing dedication to the project, as well as many other students and researchers who have continued to extend and support the work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6Ifc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6Ifc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 424w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 848w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 1272w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6Ifc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png" width="1271" height="725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:725,&quot;width&quot;:1271,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6Ifc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 424w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 848w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 1272w, https://substackcdn.com/image/fetch/$s_!6Ifc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb29c83df-eb51-4348-88cc-885cba9b51e9_1271x725.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The testbed enabled research that wasn&#8217;t possible before: <a href="https://dl.acm.org/doi/10.1145/2377677.2377756">systems for repairing routing failures</a>, <a href="https://sites.cs.ucsb.edu/~arpitgupta/pdfs/sdx.pdf">prototypes for software-defined Internet exchanges</a>, and <a href="https://www.youtube.com/watch?v=ROCp9FoMNt8">tools for diagnosing path changes</a>. It&#8217;s still being used today. Transit Portal, and ultimately PEERING, demonstrated that the Internet&#8217;s core could be studied experimentally, not just observed from the outside. In some sense, this is the lasting legacy of the work, as well&#8212;that Internet researchers can improve the Internet by building systems that interact with the live network, going beyond the simulation-based experiments that were the <em>de facto</em> mode of operation prior to Transit Portal and GENI.</p><p>The impact goes beyond just the testbed itself. We demonstrated that it was possible to do empirical research on the Internet&#8217;s routing infrastructure. Prior to Transit Portal and PEERING, the predominant mode of understanding Internet routing was through simulation or theory, both of which had significant shortcomings when translated to practice. We showed that it was possible to conduct experimental research on critical infrastructure if you build the right guardrails. That principle applies to everything I work on to this day, whether it is network security and privacy, performance monitoring and inference, or machine learning models for networks. Ultimately, lasting impact in this field requires building and measuring deployed systems.&#8221;</p><p>Check out our ongoing research at the <a href="https://noise.cs.uchicago.edu/">Network Operations and Internet Security Lab</a>, focusing on AI- and data-driven security, privacy, and auditing in networked systems.</p>]]></content:encoded></item><item><title><![CDATA[Introducing netml.io: A Hub for AI-Driven Networking Research and Technology]]></title><description><![CDATA[Bringing together two decades of research on Machine Learning for Networks.]]></description><link>https://practicespace.substack.com/p/introducing-netmlio-a-hub-for-ai</link><guid isPermaLink="false">https://practicespace.substack.com/p/introducing-netmlio-a-hub-for-ai</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Wed, 19 Nov 2025 21:15:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!N0EN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N0EN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N0EN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N0EN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png" width="728" height="432.25" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/efd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:608,&quot;width&quot;:1024,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!N0EN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 424w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 848w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 1272w, https://substackcdn.com/image/fetch/$s_!N0EN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fefd1c579-a1ec-4c04-9184-ae7f952b5b2f_1024x608.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>This month marks the 20-year anniversary of the beginning of our first research project on applications of machine learning to networking, <a href="https://dl.acm.org/doi/10.1145/1159947">Understanding the Network-Level Behavior of Spammers</a>.</p><p>Since 2006, we&#8217;ve been pioneering the application of machine learning to networking problems.</p><blockquote><p>Today, we are excited to announce <strong><a href="https://netml.io/">netml.io</a></strong>&#8212;a research initiative that brings together two decades of work at the intersection of ML and networking, from security applications to performance analysis to synthetic traffic generation.</p></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Practice Space! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Announcing netml.io</h1><p><a href="https://netml.io/">netml.io</a> is the home for all things at the intersection of networks and AI&#8212;a comprehensive resource for researchers, practitioners, and students working in this space. <br><br>The goals of the project include:</p><ul><li><p><strong>Open-source tools</strong>: Implementations of <a href="https://netml.io/projects/3-netdiffusion/">NetDiffusion</a>, <a href="https://netml.io/projects/3-netdiffusion/">NetSSM</a>, <a href="https://netml.io/projects/5-traffic-refinery/">Traffic Refinery</a>, and related traffic generation and analysis tools available on <a href="https://github.com/noise-lab">GitHub</a></p></li><li><p><strong>Datasets and benchmarks</strong>: Curated resources for common ML tasks in networking, making it easier to train and evaluate models</p></li><li><p><strong>Research collaborations</strong>: Partnerships with industry and academia to tackle real-world problems at the intersection of AI and networking.</p></li><li><p><strong>Educational resources</strong>: We&#8217;re developing comprehensive teaching materials including a forthcoming book on AI and ML for networking, an online course based on our <a href="https://noise-lab.net/ml-systems/">ML Systems course materials</a>, and tutorials and practical guides for applying ML to network analysis.</p></li><li><p><strong>Community hub</strong>: A central place for the networks + AI community to share ideas, code, and datasets</p></li></ul><p>The <a href="https://netml.io/">netml.io</a> website brings together decades of research applying AI to networking problems and datasets. Read on for a history of the project.</p><h2>Machine Learning for Network Security (2006-2009)</h2><p>The NetML story begins in 2006, when we were among the first to apply machine learning to network security problems. Our early work focused on understanding and combating spam and botnets at the network level. Rather than just looking at email content, we analyzed network-level behavior&#8212;examining patterns in how messages were sent, identifying spamming infrastructures, and detecting botnet membership through DNS blacklist reconnaissance.</p><p>This collection of work on &#8220;behavioral blacklisting&#8221;, starting with this initial SIGCOMM paper, showed that network-level features were far more difficult for attackers to manipulate than message content. The <a href="https://dl.acm.org/doi/10.1145/1159947">SIGCOMM 2006 paper</a> on understanding spammers&#8217; network-level behavior became foundational work in the field, demonstrating how ML could identify malicious activity from traffic patterns alone. The paper won a Best Paper Award and formed the basis for a Presidential Early Career Award for Scientists and Engineers (PECASE) in 2008 for contributions at the intersection of AI and cybersecurity.</p><p>The key observation behind the initial work was simple: attackers behave differently from legitimate senders, and those differences are evident in network traffic and other signals evident in network data. By examining features like AS numbers, geodesic distance between sender and receiver, sending patterns across time, and recipient clustering, we could distinguish malicious from legitimate traffic without ever looking at message content. <br><br>During this period, we also developed techniques for <a href="https://dl.acm.org/doi/10.1145/1298455.1298466">characterizing botnets from email spam records</a> and <a href="https://dl.acm.org/doi/10.1145/1159935.1159948">detecting botnet membership using DNS blacklist counter-intelligence</a>.</p><p>Our initial insight was simple but profound, and one that has ultimately stood the test of time and formed the basis of much of our work over the past two decades: networks contain rich signals that machine learning can exploit for a wide variety of inference problems in security, performance, and resource allocation.</p><h2>Deploying ML in Practice (2009-2016)</h2><p>Our spam and botnet detection work quickly moved from research to real-world deployment. In 2009, we developed <strong><a href="https://www.usenix.org/legacy/events/leet09/tech/full_papers/hao/hao_html/">SNARE</a></strong><a href="https://www.usenix.org/legacy/events/leet09/tech/full_papers/hao/hao_html/"> (Spatio-temporal Network-level Automatic Reputation Engine)</a>, an automated system that could identify spammers with over 94% accuracy and just 2% false positives using only network-level features. SNARE was designed to work as a lightweight &#8220;pre-acceptance&#8221; classifier&#8212;fast enough to make decisions before even accepting an email connection. SNARE was deployed at Cisco/IronPort and Secure Computing, demonstrating that network-level ML could work at scale in commercial email security products.</p><p>We also developed <strong><a href="https://dl.acm.org/doi/10.1145/1402946.1402974">WISE</a></strong><a href="https://dl.acm.org/doi/10.1145/1402946.1402974"> (What-If Scenario Evaluator)</a>, which used statistical learning to predict the effects of configuration and deployment changes in content distribution networks. WISE was deployed at Google, where it helped evaluate &#8220;what-if&#8221; scenarios for network changes without requiring expensive real-world experiments.</p><p>During this period, our research applying machine learning to botnet detection led to the founding of <strong>Damballa</strong>, a startup based on our research on DNS-based botnet detection. Damballa&#8217;s core technology used machine learning algorithms to identify the unique traffic patterns and communication signatures that botnets generate as they interact with command-and-control servers. By monitoring DNS queries for anomalous patterns&#8212;like the Non-Existent Domain (NXDomain) responses generated by domain generation algorithms (DGAs)&#8212;Damballa could detect botnet infections weeks before traditional signature-based approaches.</p><p>Damballa grew rapidly, eventually <a href="https://gra.org/company/26/Damballa.html">monitoring nearly 15% of global Internet traffic and protecting over half a billion devices</a> for enterprise customers, ISPs, and telecommunications providers. The company&#8217;s <a href="https://www.businesswire.com/news/home/20110620005271/en/Damballa%C2%AE-FirstAlert-Detects-Cyber-Threats-Weeks-Before-the-Malware-is-Ever-Discovered">FirstAlert service could detect threats 30 days earlier on average</a> than conventional malware detection systems. This work demonstrated that academic research in ML for networking could translate directly into commercial impact.Early Warning Systems (2012-2016)</p><p>As attackers evolved, so did our detection methods. By 2012-2016, we were working on <strong><a href="https://dl.acm.org/doi/10.1145/2976749.2978317">PREDATOR</a></strong><a href="https://dl.acm.org/doi/10.1145/2976749.2978317"> (Proactive Recognition and Elimination of Domain Abuse at Time-Of-Registration)</a>, which took an even more proactive approach: detecting malicious domains <em>before</em> they were used for harm.</p><p>The insight was that malicious actors exhibit different registration behavior than legitimate users&#8212;bulk purchasing domains to take advantage of discounts, registering many similar domains at once, and using specific patterns in registration information. By analyzing these behavioral signals at registration time, PREDATOR could identify potentially malicious domains with 70% detection rate and only 0.35% false positives, all before the domains had been used for any attacks.</p><p>This work was also featured in <a href="https://www.wsj.com/">Wall Street Journal</a> CIO and resulted in several <a href="https://patents.google.com/patent/US8713676B2">patents</a>, showing that ML could provide early warning systems for network security&#8212;catching threats in their planning stages rather than waiting for them to cause damage. The proactive approach represented a fundamental shift from reactive signature-based detection to predictive, behavior-based prevention.</p><h2>Inference from Encrypted Network Traffic (2017-2020)</h2><p>By 2017, encryption was becoming ubiquitous, and network traffic also became increasingly encrypted&#8212;certainly a win for privacy, but a challenge for network management and security. At this time, we started to encounter questions concerning what we could learn about network traffic when we can&#8217;t see the data inside the packets themselves. The rise of encryption led to a new research direction: inference from encrypted network traffic. <br><br>At the intersection of ML and privacy, we demonstrated that even encrypted IoT device traffic could reveal sensitive user activities through traffic analysis. Our work on <a href="https://arxiv.org/abs/1705.06805">IoT privacy</a> showed that a Sense sleep monitor&#8217;s traffic patterns could reveal when someone was in bed, and that an Amazon Echo&#8217;s traffic could indicate when users were speaking to it&#8212;all without decrypting a single packet. We also developed <a href="https://arxiv.org/abs/1812.00955">traffic shaping techniques</a> to protect smart home privacy.</p><p>In the area of network performance and management, we developed developed techniques to <a href="https://arxiv.org/abs/1901.05800">infer video streaming quality</a> (startup delay, resolution) from encrypted Netflix, YouTube, Amazon, and Twitch traffic. This work, featured on the <a href="https://www.wsj.com/graphics/faster-internet-not-worth-it/">front page of the Wall Street Journal in 2019</a>, showed that ML models could provide ISPs with visibility into application performance even as encryption spread across the Internet. The study demonstrated that premium internet speeds above 100 Mbps provide little benefit for video streaming&#8212;valuable information for both consumers and network operators.</p><h2>Making ML Practical: Cost-Aware Representations (2020-2023)</h2><p>As our ML models became more sophisticated, we confronted a new challenge: deploying them at scale. A critical first step was developing better representations of network traffic for machine learning. <br><br>In 2020, we developed <strong><a href="https://nprint.github.io/nprint/">nPrint</a></strong>, a standard packet-based representation that was the first system to successfully apply deep learning models directly to raw network traffic without manual feature engineering. nPrint represents packets as standardized bitmaps, enabling convolutional neural networks and other deep learning architectures to automatically discover important features (like IP TTL, window size, protocol fields) across diverse tasks including device fingerprinting, operating system detection, and application identification. Combined with automated machine learning (AutoML), <a href="https://dl.acm.org/doi/10.1145/3460120.3484758">nPrint achieved higher performance</a> than state-of-the-art hand-engineered approaches while being generalizable across multiple traffic analysis problems.</p><p>Building on this foundation, we developed <strong><a href="https://dl.acm.org/doi/10.1145/3447382">Traffic Refinery</a></strong> (2020), which explored the fundamental tradeoff between model accuracy and computational cost. We showed that different ML tasks benefit from different representations of network traffic&#8212;some need raw packet data, others can work with flow statistics&#8212;and built a framework for automatically selecting cost-effective representations.</p><p>This work on cost-aware data representation was crucial because real networks need to analyze traffic at line rate (10+ Gbps). The most accurate model is useless if it can&#8217;t keep up with traffic.</p><p>We also developed techniques for handling concept drift (<strong><a href="https://dl.acm.org/doi/10.1145/3624354.3630585">LEAF</a></strong>, 2023), recognizing that network traffic patterns change over time as applications evolve, new protocols emerge, and user behaviors shift. Our work on multimodal inference (<strong><a href="https://dl.acm.org/doi/10.1145/3580857">AMIR</a></strong>, 2023) showed how combining network data with other signals could improve robustness and accuracy.</p><h2>Dynamic Model Execution: Adapting in Real-Time (2023-2024)</h2><p>Recent work has focused on making ML-based traffic analysis adaptive and efficient through dynamic model execution&#8212;systems that intelligently adapt to changing network conditions and computational constraints in real-time. The core insight: not all traffic is equally difficult to classify. A high-confidence prediction from a simple model is just as valuable as one from a complex model, but costs far less.</p><ul><li><p><strong><a href="https://www.shinan.info/">JITI</a></strong> (Dynamic Model Serving for Just-in-Time Traffic Inference): An adaptive ensemble classification framework that dynamically selects which models to use based on traffic characteristics. JITI efficiently manages a pool of classifiers with different performance and cost profiles, using an adaptive scheduler that tracks system memory availability and incoming traffic rates to determine the optimal classifier and batch size.</p></li><li><p><strong><a href="https://arxiv.org/abs/2402.03694">ServeFlow</a></strong>: A fast-slow model architecture that recognizes a key insight: inference time across models can differ by up to 141&#215;, while inter-packet waiting time is up to 6-8 orders of magnitude higher than inference time. ServeFlow routes traffic through a &#8220;fast&#8221; model first, assigning flows to a &#8220;slow&#8221; (more accurate) model only when the fast model&#8217;s predictions show high uncertainty. The system achieves a 40.5&#215; speedup on median end-to-end serving latency while maintaining comparable accuracy, processing over 48.5k new flows per second on a 16-core CPU&#8212;matching the order of magnitude of flow rates observed on city-level network backbones.</p></li><li><p><strong><a href="https://arxiv.org/abs/2412.15146">Cruise Control</a></strong>: A system-driven approach to dynamically select the best ML model for network traffic analysis based on real-time system performance and network load. Rather than selecting an optimal model offline, Cruise Control pre-trains several models with different accuracy-cost tradeoffs and continuously adapts model selection based on lightweight signals representing the system&#8217;s current traffic processing state. Evaluation on real-world traffic analysis tasks shows Cruise Control improves median accuracy by 2.78% while reducing packet loss by a factor of four compared to offline-selected models.</p></li><li><p><strong><a href="https://arxiv.org/abs/2402.06099">CATO</a></strong> (End-to-end Optimization): A framework that jointly optimizes both the predictive performance and the systems costs of ML-based traffic analysis pipelines. CATO leverages multi-objective Bayesian optimization to efficiently identify Pareto-optimal configurations across feature selection and packet capture depth, then automatically compiles end-to-end optimized serving pipelines. Compared to popular feature optimization techniques, CATO provides up to 3,600&#215; lower inference latency and 3.7&#215; higher zero-loss throughput while simultaneously achieving better model performance.</p></li></ul><p>Together, these systems represent a fundamental shift in how we think about ML deployment for networking: from static, one-size-fits-all models to adaptive systems that intelligently balance accuracy, throughput, and latency based on real-time conditions.</p><h2>Synthetic Data Generation: Generative AI for Networks (2023-Present)</h2><p>Which brings us to our current focus: generative AI for networks. The challenge that motivated this work was fundamental&#8212;how do we train better ML models when we can&#8217;t easily share network traffic data due to privacy concerns and data staleness?</p><p>In the <strong><a href="https://cs.uchicago.edu/news/university-of-chicago-researchers-revolutionize-network-traffic-generation-with-ai-breakthrough/">GATEAU</a></strong><a href="https://cs.uchicago.edu/news/university-of-chicago-researchers-revolutionize-network-traffic-generation-with-ai-breakthrough/"> (Generative AI for Traffic Engineering and Network Understanding)</a> project, we&#8217;ve been developing tools that use generative AI to create realistic, privacy-preserving synthetic network traffic:</p><ul><li><p><strong><a href="https://arxiv.org/abs/2310.08543">NetDiffusion</a></strong> applies diffusion models&#8212;the same technology behind Stable Diffusion for images&#8212;to generate high-fidelity, protocol-compliant network traffic. It doesn&#8217;t just produce flow statistics; it creates actual packet captures (.pcap files) that work with standard tools like Wireshark and tshark. Critically, models trained on NetDiffusion synthetic data outperform those trained on data from existing GAN-based approaches. As we noted in our <a href="https://cs.uchicago.edu/news/university-of-chicago-researchers-revolutionize-network-traffic-generation-with-ai-breakthrough/">recent announcement</a>, &#8220;NetDiffusion represents a breakthrough in generating realistic, protocol-compliant traffic, overcoming long-standing data access challenges and opening new possibilities for AI-driven security and network traffic analysis.&#8221;</p></li><li><p><strong><a href="https://arxiv.org/abs/2503.22663">NetSSM</a></strong> uses state space models to generate multi-flow network traces, capturing temporal dependencies across concurrent flows.</p></li></ul><h2>Looking Ahead</h2><p>Machine learning has become essential for modern network management&#8212;from detecting intrusions to optimizing performance to ensuring quality of experience. But the field faces a data crisis:</p><ul><li><p>Privacy regulations restrict data sharing</p></li><li><p>Network protocols and applications evolve rapidly</p></li><li><p>Collecting and labeling network traces is expensive</p></li><li><p>Datasets become stale quickly</p></li></ul><p>Synthetic data generation addresses these challenges head-on. High-quality synthetic traffic can supplement real data, handle class imbalance, and enable experimentation without privacy concerns.</p><h2>Announcing netml.io</h2><p>netml.io formalizes and extends this research program. </p><p>Ultimately, we aim to make it easier for researchers and practitioners to work on ML problems in networking by providing easier access to datasets and code that we have developed throughout the years, so that we can grow the community of researchers working in this area and continue to advance the discipline.</p><h2>What&#8217;s Next</h2><p>We&#8217;re actively working on:</p><ul><li><p>Extending generative models to more protocols and network conditions</p></li><li><p>Real-time deployment of ML models for security and performance monitoring</p></li><li><p>Federated learning approaches that enable collaborative training without sharing sensitive data</p></li><li><p>Understanding and addressing fairness and equity issues through ML-based Internet measurement</p></li></ul><h2>Join Us</h2><p>This work has always been collaborative, involving talented students, postdocs, and industry partners. If you&#8217;re working at the intersection of ML and networking&#8212;in security, performance, traffic engineering, or measurement&#8212;let&#8217;s connect.</p><p>The networks of the future will be intelligent. The <a href="https://netml.io/">netml.io</a> project is dedicated to advancing this future together, as a community.</p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[What Building an MCP for Music Composition Taught Me About Debugging AI Agents]]></title><description><![CDATA[When outputs aren't as expected, applying domain knowledge about expected outputs remains a critical step. And specifications remain as important as ever.]]></description><link>https://practicespace.substack.com/p/what-building-an-mcp-for-music-composition</link><guid isPermaLink="false">https://practicespace.substack.com/p/what-building-an-mcp-for-music-composition</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 17 Nov 2025 05:26:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!cELe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://practicespace.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>One of my recent side projects has been building an MCP (Model Context Protocol) server for my Elektron Digitakt&#8212;essentially teaching Claude to control my sampler and drum machine through conversation. </p><p>It&#8217;s been an amazing playground for exploring how LLMs handle complex, domain-specific tasks. But it&#8217;s also exposed some fundamental challenges in how these systems reason about context, state, and when to think versus when to act.</p><p>Last week, I hit a particularly instructive bug: an infinite loop that perfectly captured the overthinking problem plaguing current LLM agent systems.</p><h2>The Bug: The MCP &#8220;Infinite Loop&#8221;</h2><p>I was trying to automate parameter changes over a 16-bar musical phrase. The system kept passing an empty dictionary. Then it would detect the error, attempt to fix it, fail to fix it correctly, detect the same error again, attempt another fix&#8212;forever. Claude Desktop would have looped indefinitely if I hadn&#8217;t manually intervened.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cELe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cELe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 424w, https://substackcdn.com/image/fetch/$s_!cELe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 848w, https://substackcdn.com/image/fetch/$s_!cELe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 1272w, https://substackcdn.com/image/fetch/$s_!cELe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cELe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png" width="670" height="501" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:501,&quot;width&quot;:670,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91801,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/179111733?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cELe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 424w, https://substackcdn.com/image/fetch/$s_!cELe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 848w, https://substackcdn.com/image/fetch/$s_!cELe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 1272w, https://substackcdn.com/image/fetch/$s_!cELe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88409f5-bf68-4839-a4d6-77e8b7cb67e8_670x501.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The actual problem? The automation was only populating the first 4 bars of the dictionary, leaving bars 5-16 empty. I could <em>hear</em> this&#8212;I&#8217;d asked for something to happen over 16 bars, and it only happened over 4. The 16-bar loop played, but the parameter automation stopped after the first 4 bars.</p><h2>How I Debugged the MCP</h2><p>Here&#8217;s roughly what the debugging process looked like:</p><ol><li><p><strong>Desktop Claude</strong> hit the infinite loop</p></li><li><p>I stopped it and switched to <strong>Claude Code</strong></p></li><li><p>I asked: &#8220;Here&#8217;s what&#8217;s happening. Tell me what&#8217;s causing this infinite looping.&#8221;</p></li><li><p>Claude Code suggested a specific data structure to pass</p></li><li><p>I went back to <strong>Desktop Claude</strong> and said: &#8220;Here&#8217;s the data structure I want you to pass. Try that.&#8221;</p></li><li><p>It sort of worked</p></li><li><p>I asked Desktop Claude: &#8220;Tell me what would help you not infinite loop.&#8221;</p></li><li><p>It responded: &#8220;What would help me is an accurate description of this function in the MCP function description.&#8221;</p></li><li><p>I went back to <strong>Claude Code</strong> and worked on improving the function description</p></li><li><p>Finally, it worked</p></li></ol><p>The whole process took about an hour. Without AI assistance, it would have taken a day. </p><p>But here&#8217;s the key insight: <em>I</em> had to know what was causing the problem at each step. I had to notice: &#8220;You&#8217;re overthinking a simple query,&#8221; or &#8220;You&#8217;re in a loop,&#8221; or &#8220;Show me the dictionary structure.&#8221; </p><p>I had to reason about <em>why</em> parameter automation over 16 bars was only executing over 4 bars, connect that to the empty dictionary complaint, and guide the debugging process.</p><h2>Domain Knowledge About Outputs is Critical</h2><p>Having a tangible, audible application made learning faster. This reminds me of my undergrad EE days&#8212;there&#8217;s something powerful about debugging something you can hear versus just looking at code on a screen. </p><p>When I hear a 16-bar loop but only hear parameter changes in the first 4 bars, the bug becomes obvious. The domain knowledge becomes a debugging superpower.</p><h2>Enter Semantic Router</h2><p>This experience maps perfectly onto a research project I&#8217;ve started to explore with a Ph.D. student. He recently pointed me at the <a href="https://github.com/aurelio-labs/semantic-router">Semantic Router project</a> from the Aurelio Labs team, which tackles exactly these problems in agentic systems.</p><p>The main problem: current LLM systems <strong>overthink simple queries and underthink complex ones</strong>.</p><p>I encounter both failure modes constantly:</p><ul><li><p><strong>Overthinking simple queries</strong>: I ask Claude to summarize something that&#8217;s right in front of it in context. Instead, it goes off to fetch additional sources. &#8220;No, it&#8217;s right here. Stop. You&#8217;ve already done it.&#8221;</p></li><li><p><strong>Underthinking complex queries</strong>: The music automation bug is a perfect example. The system needed to reason more carefully about state across a 16-bar phrase but instead rushed to a broken solution and then got stuck in a loop.</p></li></ul><p>Semantic Router addresses this by using application state to enable correct inference. The project focuses on:</p><ul><li><p><strong>Cache persistence</strong> across multiple stages of the same LLM call</p></li><li><p><strong>Failure recovery</strong> from incorrect MCP server responses</p></li><li><p><strong>Request routing</strong> to ensure sub-requests from the same session hit the same endpoint</p></li><li><p><strong>Query classification</strong> to allocate the right computational resources</p></li></ul><h2>What&#8217;s Missing: Domain-Specific Knowledge</h2><p>Current semantic routing abstractions classify queries as &#8220;simple versus complex.&#8221; But they don&#8217;t yet leverage <strong>application-specific knowledge</strong>.</p><p>In my music MCP debugging session, the relevant signal was: &#8220;Only 4 out of 16 bars were populated.&#8221; That&#8217;s music-specific knowledge, and something I could hear directly from the output. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5uCa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5uCa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 424w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 848w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 1272w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5uCa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png" width="569" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:569,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143148,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/179111733?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5uCa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 424w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 848w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 1272w, https://substackcdn.com/image/fetch/$s_!5uCa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F882c3d68-a92e-409a-81ed-4588cea7190a_569x792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If I could pass that insight and domain-specific knowledge to the LLM or to a routing system in the right interface, it might be able reason correctly from the start.</p><p>While I encountered this mismatch in my own experience, it is evident how it can also rise in other domains:</p><ul><li><p><strong>Art generation</strong>: A query specifies &#8220;warm earth tones&#8221; but the model generates cool blues and purples. The color palette constraint is domain knowledge that should guide inference.</p></li><li><p><strong>Network debugging</strong>: A query about packet loss should trigger different reasoning than a query about DNS resolution, even if both are phrased as &#8220;connection problems.&#8221;</p></li><li><p><strong>Code debugging</strong>: Information about which data structures are populated or empty (like my dictionary) should influence how the LLM approaches the problem.</p></li></ul><h2>Research: <br>Debugging Agents with Domain Knowledge</h2><p>The opportunity here is to bridge semantic routing with domain-specific knowledge extraction:</p><ol><li><p><strong>Automated domain signal extraction</strong>: Can we automatically extract relevant domain signals from queries (like &#8220;16 bars&#8221; in my music example) and use them to guide inference?</p></li><li><p><strong>User-in-the-loop feedback</strong>: When I told Claude &#8220;you only populated 4 bars,&#8221; that&#8217;s a valuable debugging signal. Can we formalize interfaces for users to provide this kind of application-specific feedback?</p></li><li><p><strong>Multi-modal domain knowledge</strong>: In my case, the audible output was the debugging signal. For network measurement, it might be latency graphs. For image generation, visual output. How do we incorporate multi-modal domain signals into semantic routing?</p></li><li><p><strong>MCP-to-MCP debugging</strong>: I developed a pattern of bouncing between Desktop Claude (executing MCP calls) and Claude Code (debugging the MCP server code). Can we formalize this pattern? Passing error messages and context between different Claude instances dramatically sped up debugging.</p></li></ol><h2>Why This Matters for Education and Research</h2><p>This work sits at an interesting intersection. </p><p>From an education perspective, these experiences reinforce why reasoning skills remain critical&#8212;I can immediately tell when the LLM is going off the rails. From a research perspective, there&#8217;s fundamental ML work to be done on how domain knowledge should flow into semantic routing systems.</p><p>Agentic workflow papers at the upcoming HotNets workshop this week are exploring related ideas&#8212;using LLM agents for network measurement research, for example. But I suspect the real breakthroughs will come from figuring out how to inject domain expertise into the routing and reasoning process itself. </p><blockquote><p>Putting together an agentic workflow is the easy part. Figuring out how to debug it when the outputs aren&#8217;t as expected is the true challenge.</p></blockquote><h2>Try It Yourself</h2><p>If you&#8217;re building MCP servers or working with agentic LLM systems, I highly recommend:</p><ol><li><p>Choose a domain with tangible, observable outputs (music, images, network measurements)</p></li><li><p>Pay attention to when the LLM overthinks versus underthinks</p></li><li><p>Document the domain-specific signals that help <em>you</em> debug</p></li><li><p>Experiment with bouncing between different Claude instances for debugging</p></li></ol><p>The bugs are frustrating, but they&#8217;re also revealing fundamental limitations in how these systems reason. And that makes them excellent research opportunities.</p><div><hr></div><p><em>What domain-specific knowledge do you wish you could pass to your LLM agents? Let me know in the comments or reach out&#8212;I&#8217;d love to hear about your debugging experiences.</em></p>]]></content:encoded></item><item><title><![CDATA[AI and the Spectrum of Creation: A Case Study in Songwriting]]></title><description><![CDATA[Five Songs, One Question: Where Does the Human End and the Machine Begin?]]></description><link>https://practicespace.substack.com/p/ai-creativity-and-the-spectrum-of</link><guid isPermaLink="false">https://practicespace.substack.com/p/ai-creativity-and-the-spectrum-of</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 10 Nov 2025 05:47:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZrEb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://practicespace.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>I was asked to give a guest lecture for Family Weekend at the University of Chicago this past weekend. Instead of diving into network protocols or cybersecurity frameworks, I picked up my guitar.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZrEb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZrEb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 424w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 848w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 1272w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZrEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png" width="1456" height="815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:815,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2273994,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/178471289?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZrEb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 424w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 848w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 1272w, https://substackcdn.com/image/fetch/$s_!ZrEb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4b70889-ff1b-41e3-82e7-b7b477378aab_1926x1078.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I couldn&#8217;t decide whether to talk about generative AI, policy, content moderation, so I decided to combine all of these topics and use another passion of mine&#8212;music&#8212;as the lends to pose various questions about the role of AI in creation. </p><p>I gave a talk about AI, creativity, and copyright&#8212;topics that have been swirling around in my head as I&#8217;ve watched these tools reshape everything from my students&#8217; coding habits to my own songwriting process. And I figured the best way to cut through all the hype and anxiety was to run an experiment.</p><div id="youtube2-Bli5yWui90A" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Bli5yWui90A&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Bli5yWui90A?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2>The Hook: Can You Spot AI in a Song?</h2><p>The main hook for the lecture was that I played excerpts of five songs for the audience. All of them I wrote, for some definition of the word &#8220;wrote&#8221;.  (For the record, I generally do not use much AI in my own songwriting, typically stopping at #2 on this spectrum below, but for this lecture, I used Suno to create a couple of songs and then learned them on my guitar for the purposes of the experiment/demonstration).</p><p>The central question: which ones involved AI, and how much? </p><p><strong>Song 1: Pure human.</strong> I wrote this one unassisted&#8212;lyrics, melody, chord progression, etc., with no AI anywhere in the process. </p><p><strong>Song 2: LLM lyric assist.</strong> I had most of the song written, but there I had a particular couplet that just wasn&#8217;t landing. I had the imagery but I didn&#8217;t have quite the right words. So I described what I was going for to ChatGPT, and it gave me various images like &#8220;cobblestones&#8221;&#8212;exactly the mood I wanted but couldn&#8217;t articulate. AI helped me find words and imagery that I ultimately selected to integrate into my lyrics. In my view, this was very similar to what Jeff Tweedy describes as a &#8220;word ladder&#8221; in his book How to Write One Song. They main difference is that instead of having completely random words, I asked for words that matched the theme and lyrics that I had already largely composed.</p><p><strong>Song 3: Claude completes the progression.</strong> For this one, I took a D minor 6 - D major progression and fed the beginning of the chord progression into Claude. &#8220;Finish this for me,&#8221; I said. It gave me a really cool sounding Bb maj7 to A7 progression to complete the progression and even explained to me. Everything else&#8212;the melody, the lyrics, the arrangement, and even the other progressions in the song&#8212;was mine. But I wrote a lot around this foundation.</p><p><strong>Song 4: Suno from my lyrics.</strong> I took lyrics that I wrote for a completed song, threw them at Suno, and said &#8220;make me a song with these lyrics&#8221;, generally describing a lo-fi dream-pop vibe. Then I learned it and performed it. The lyrics were mine. The music, melodies, and chords? That came from the model. But the performance, the interpretation&#8212;that was all human again.</p><p><strong>Song 5: Full Prompt-Based AI.</strong> I prompted Suno with nothing but a vague idea and let it generate everything&#8212;lyrics, melody, arrangement. Then I learned it well enough to perform it. This is what people typically think about when we hear the phrase &#8220;AI-generated&#8221; , though even here, I had to interpret and embody what the machine created (&#8220;interpolation&#8221; as it is sometimes called in music).</p><h2>What People Heard</h2><p>Most people correctly identified Song 5 as AI-generated&#8212;I think partly because I didn&#8217;t know it as well, and partly because there was something missing in the emotional delivery. Several people pegged Song 2 as AI because of the lyrics, which is interesting given that only a couple of words came from AI, but people thought it was AI-generated because the lyrics felt less &#8220;personal&#8221;.</p><p>Almost nobody identified Song 3, the one where Claude completed my chord progression. And that makes sense&#8212;a chord progression is pattern-matching, it&#8217;s statistics, it&#8217;s &#8220;what usually comes next.&#8221; AI is actually pretty good at that. This was a good hook for the next part of my lecture were I talked about instances of many other artists, from Ed Sheeran to Taylor Swift, writing songs based off of extremely common chord progressions. </p><h2>AI as Normal Technology in Creation</h2><p>Here&#8217;s what struck me as I was preparing this exercise: we keep talking about &#8220;AI-generated&#8221; content as if it&#8217;s a binary. But, having now experimented with creation along this spectrum, I&#8217;ve concluded that this is a false dichotomy.</p><p>I&#8217;ve been thinking a lot about a concept called &#8220;AI as normal technology,&#8221; coined by Arvind Narayanan at Princeton. His argument is simple but profound: AI is just technology. </p><p>We panicked when calculators came along&#8212;nobody will learn math anymore! We panicked when drum machines were invented&#8212;real drummers are finished! We panicked when digital audio workstations made it possible to record and mix at home&#8212;goodbye, studio engineers!</p><p>None of those predictions came true. We still have mathematicians. We still have drummers. We still have studio engineers. </p><blockquote><p><strong>What changed was that the technology became a tool that professionals use, and the people who refused to learn the new tools got left behind.</strong></p></blockquote><p>Interesting questions of course are up for debate as far as our respective roles in creation. When I had Claude complete a chord progression, was that &#8220;AI creation&#8221; or was it more like using a calculator? What about Song 2, where ChatGPT gave me two words that unlocked an entire verse I&#8217;d been struggling with for days? When I threw my lyrics at Suno, was the result mine because the words were mine, or was it Suno&#8217;s because the music was its? What about the last one, where Suno did &#8220;everything&#8221;? Or, did it? I still had to prompt the model and ultimately learn the song. What if I had pulled stems from that last song and cut them up or remixed them? (Artists are actively doing just that these days.) And is that any less creative, or just a different form of creativity with new tools?</p><h2>We&#8217;ve Been Here Before</h2><p>The music industry has wrestled with these questions for decades, and the outcomes have shaped entire genres.</p><p>Take hip-hop. In the early days, sampling was the art form&#8212;&#8221;Rapper&#8217;s Delight&#8221; sampled Chic&#8217;s &#8220;Good Times&#8221; in 1979. But then came <em>Grand Upright Music, Ltd. v. Warner Bros. Records</em> in 1991, where Biz Markie sampled Gilbert O&#8217;Sullivan&#8217;s &#8220;Alone Again (Naturally)&#8221; without permission. The judge&#8217;s <a href="https://en.wikipedia.org/wiki/Grand_Upright_Music,_Ltd._v._Warner_Bros._Records_Inc">ruling</a> was blunt: &#8220;Thou shalt not steal.&#8221;</p><p>That decision fundamentally changed hip-hop. Suddenly, sampling became expensive and permission-based. Artists had to clear every sample, and rights holders knew they could charge for it. The creative process changed in response to the legal landscape. Hip-hop didn&#8217;t die&#8212;it evolved. But the law shaped what was possible.</p><p>Or consider Ed Sheeran&#8217;s <a href="https://www.rollingstone.com/music/music-news/ed-sheeran-not-liable-thinking-out-loud-trial-1234724464/">lawsuit</a> with Marvin Gaye&#8217;s estate over &#8220;Thinking Out Loud&#8221; and &#8220;Let&#8217;s Get It On.&#8221; Sheeran won, partly by demonstrating that chord progressions themselves can&#8217;t really be copyrighted&#8212;there are only so many combinations that sound good to human ears. He played twenty different songs back-to-back in court, showing how they all used similar progressions. The question wasn&#8217;t whether the songs sounded similar (they did), but whether that similarity constituted theft or just the natural constraints of music theory.</p><p>Now compare that to what Taylor Swift is doing. If you listen to her recent albums, you&#8217;ll hear echoes everywhere&#8212;the Pixies&#8217; bass line in one song, Jonas Brothers vibes in another, Jackson 5 in yet another. Music critics call it &#8220;interpolation.&#8221; It&#8217;s credited, it&#8217;s acknowledged, but it&#8217;s clearly building on what came before. At what point does &#8220;inspired by&#8221; become &#8220;copied from&#8221;? And would we even be asking that question if she weren&#8217;t using such recognizable sources?</p><h2>The Industry Response</h2><p>The platforms are trying to figure this out in real-time. Spotify sees <a href="https://www.musicbusinessworldwide.com/ai-music-app-boomy-spotify-stream-manipulation/">100,000 tracks uploaded every day</a> now&#8212;most of them AI-generated. They account for less than 1% of streams (Taylor Swift has the rest), but they create real problems.</p><p>Do you demonetize AI-generated music? Sounds simple, except it creates perverse incentives. Playlist curators get paid based on the royalties of the artists they include. If AI music is free to use and generates no royalties, suddenly there&#8217;s no economic reason to include real artists in your playlists. You hurt the humans you were trying to protect.</p><p>That&#8217;s why the industry is converging on disclosure rather than outright prohibition. There&#8217;s a consortium now&#8212;<a href="https://ddex.net/about-ddex/">DDEX</a> is one of the standards they&#8217;re building on&#8212;that allows artists to self-report what went into a track. &#8220;I wrote the lyrics, my friend played drums, AI generated the guitar part.&#8221; The idea is granular transparency: let listeners know what they&#8217;re hearing, let platforms make informed decisions, and let the market sort it out.</p><p>But this only works if people actually disclose. And it only works if we can agree on what counts as &#8220;AI-generated.&#8221; Is my Song 3, where Claude completed two chords, AI-generated? What about Song 2, where ChatGPT gave me two words?</p><h2>Story: That Time AI Helped Make <br>My Own Music Sound More Human</h2><p>During the lecture, I recounted a moment in my recent music-making that perfectly captures where we are right now. </p><p>I was programming a drum track on my Digitakt, and I asked Claude to &#8220;improve it&#8221;. It did and it sounded better, and I asked it why. What it told me taught me something surprising.</p><blockquote><p>Claude told me: &#8220;Human drummers never hit exactly on the beat, and they never hit with exactly the same velocity. So I shifted some notes slightly off-grid and varied the velocities.&#8221;</p><p><strong>I was talking to a machine to learn how to sound </strong><em><strong>less</strong></em><strong> like a machine.</strong></p></blockquote><div id="youtube2-eXshbtC1TUE" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;eXshbtC1TUE&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/eXshbtC1TUE?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>This is the uncanny valley we are currently traversing: AI tools are good enough to be useful, sophisticated enough to mimic human imperfection, but not yet advanced enough that we&#8217;ve figured out the etiquette and ethics of using them. My students can generate code they don&#8217;t understand. I can generate chord progressions I didn&#8217;t conceive. Artists can generate entire songs they never played.</p><p>How should we think about this? I can tell when the code is wrong because I spent years learning to code. I can tell when a chord progression works because I&#8217;ve studied music theory and played enough songs to develop an ear. The technology is a force multiplier, but only if you have something to multiply.</p><h2>Musicians Already Borrow from Other Humans. <br>How Is Borrowing from AI Different?</h2><p>As I told the audience, I&#8217;ve found that AI is terrible at writing lyrics. Why might that be? Because lyrics are emotion. They&#8217;re personal experience. They&#8217;re the thing that makes someone listen to a song and say &#8220;oh, that&#8217;s about something <em>real</em>.&#8221; That&#8217;s the human element that&#8212;so far, at least&#8212;the machines can&#8217;t fake.</p><blockquote><p>But chord progressions? Hooks? The ear actually <em>likes</em> things that sound familiar, even simple. We like patterns. We like statistical regularity with just enough variation to stay interesting. <strong>That&#8217;s literally what these models are built to do.</strong></p></blockquote><p>So now we&#8217;re in this gray area where Taylor Swift can <a href="https://www.stereogum.com/2325675/charlie-puth-explains-threshold-for-interpolation-as-tiktokers-compare-taylor-swifts-new-songs-to-old-hits/news/">interpolate</a> &#8220;Where Is My Mind?&#8221; by the Pixies into her own song, and we call it inspiration. But if I use AI to complete a chord progression that follows patterns drawn from thousands of existing songs, is that theft? Transformation? Or just another tool in the creative toolkit?</p><h2>The Hard Questions</h2><p>The question of whether AI training on copyrighted works should be allowed is the subject of much active litigation. There was a ruling last week in the UK courts saying AI models don&#8217;t violate copyright because they don&#8217;t actually make a copy&#8212;they train on data, extract patterns, then discard the original. </p><p>As the courts grapple with applying old copyright laws to this new technology, the deeper questions aren&#8217;t legal&#8212;they&#8217;re philosophical and practical:</p><ul><li><p>When does &#8220;inspired by&#8221; become &#8220;copied from&#8221;?</p></li><li><p>At what point does a tool become an active collaborator, and how does that matter for attribution&#8212;not only of the model, but also of anything that went into the process of creating that model?</p></li><li><p>Should we restrict AI tools from students (or as part of our own learning process) until we first learn to do things &#8220;the hard way&#8221;?</p></li></ul><p>That last question is one we&#8217;re actively grappling with in computer science education. I learned to code by writing everything from scratch. That means when an LLM spits out code that doesn&#8217;t meet my specifications I can typically spot it. I can work with the machine to fix it because I understand what it&#8217;s <em>supposed</em> to do.</p><p>But what about students who only ever learn to prompt? What about the next generation of musicians who never learn music theory because the tools can do it for them? Are they going to be like someone using a calculator without understanding arithmetic&#8212;unable to tell when 2+2=5? (Yes, that is a Radiohead reference.)</p><h2>What I Think (For Now)</h2><p>Here&#8217;s where I&#8217;ve landed, at least this week: AI isn&#8217;t going away. </p><p>It&#8217;s not going to replace artists or coders or writers, but it&#8217;s going to change what those jobs look like. Just like photography didn&#8217;t kill painting, and drum machines didn&#8217;t kill drummers, and DAWs didn&#8217;t kill studio engineers.</p><blockquote><p>The people who thrive will be the ones who understand both the craft <em>and</em> the tools. The ones who can tell when the machine is giving them something useful versus when it&#8217;s spitting out statistically plausible garbage. The ones who bring something distinctly human&#8212;emotion, experience, judgment&#8212;that the machines can&#8217;t replicate.</p></blockquote><p>When I played those five songs, many of people&#8217;s favorite songs were in the &#8220;grey zone&#8221;. Many felt the fully AI song lacked emotion&#8212;but the other four modes, where there was a distinct human element in creation, were very hard for humans to distinguish.</p><p>I think that&#8217;s the future (or increasingly, the present): the future of creation will  increasingly be less of a question of humans <em>or</em> machines, but rather humans <em>with</em> machines, and figuring out where the boundary between tool and collaborator actually lies.</p><p>Perhaps now the most important skill we can teach&#8212;in computer science, music, or anything else&#8212;is recognizing where that boundary lies and how to make intentional decisions about where to draw that line for various projects.<br></p><div><hr></div><p><em>This post is based on a talk I gave for a model class at University of Chicago&#8217;s Family Weekend. If you want to hear more about AI, creativity, copyright, and the messy intersection of technology and art, stay tuned. I&#8217;m still figuring this out myself.</em></p>]]></content:encoded></item><item><title><![CDATA[Embracing AI in the Classroom]]></title><description><![CDATA[A computer science education has never been strictly about coding. More than ever, it has become about specification, testing, higher-level reasoning, and understanding how systems work.]]></description><link>https://practicespace.substack.com/p/embracing-ai-in-the-classroom</link><guid isPermaLink="false">https://practicespace.substack.com/p/embracing-ai-in-the-classroom</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Wed, 05 Nov 2025 21:00:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oZ-f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://practicespace.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>I recently sat down with a student reporter from <em>The Chicago Maroon</em> to discuss how I&#8217;m incorporating AI tools into my teaching. </p><p>As someone who&#8217;s been teaching computer science for more than 20 years, I&#8217;ve watched large language models emerge as transformative tools in education. Below I talk about my philosophy towards how I encourage students to think about them in my own classes, as well as how I&#8217;ve been using AI to enhance my own pedagogy and classroom delivery.</p><h2>My Philosophy: AI as Normal Technology</h2><p>My approach is straightforward: these tools exist, students will use them in their careers, so we need to teach them how to use them effectively. As I mentioned in the interview, there&#8217;s an excellent article called &#8220;<a href="https://www.normaltech.ai/p/ai-as-normal-technology">AI as Normal Technology</a>&#8221; that captures this philosophy perfectly. This is just another tool&#8212;like IDEs, Stack Overflow, or GitHub before it. It&#8217;s potentially more powerful, but fundamentally, it&#8217;s another instrument in the problem-solving toolkit.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oZ-f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oZ-f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oZ-f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6545855,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/178121318?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oZ-f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oZ-f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99b5d62d-5fb9-4da4-9dd0-f392bb81b9fc_3968x2232.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>My AI Policy</h2><p>I fully encourage the use of AI tools in all my courses. Here&#8217;s the core principle I share with students: <strong>You must understand what you&#8217;re turning in.</strong> I&#8217;ll ask you about it on exams, in discussions, and during assessments. Use whatever tools help you learn and complete your work, but you&#8217;re responsible for understanding the output. I also require attribution&#8212;tell me what assistance you used.</p><p>The classroom is a simulator for the real world, and in the real world, these tools are everywhere. Ignoring them doesn&#8217;t serve our students well. We need to acknowledge the environment we&#8217;re operating in and teach accordingly.<br><br>Here is what I currently say in my <a href="https://noise-lab.net/ml-systems/syllabus.html">syllabus</a> for my courses.</p><blockquote><p><em><strong>Use of AI Tools and Large Language Models</strong></em></p><p>I acknowledge and even expect that you will use large language models (LLMs) and other AI tools for assistance in completing assignments. This is perfectly acceptable and encouraged. However, you are expected to understand the output these tools generate.</p><p>AI-assisted coding improves efficiency, but only if you understand its outputs. Just as I would not be able to evaluate an LLM-produced essay in philosophy if I didn&#8217;t understand the subject matter, these tools do you no good if you cannot understand, evaluate, improve, debug, and iterate on their output.</p><p>Therefore, you are allowed to use AI tools to help automate anything you are confident that you understand well enough to implement manually yourself. This approach best simulates the real world, where you will inevitably need to know how to use these tools well and to your advantage, but you will ultimately be responsible for understanding the software and code that you produce.</p><p>When using AI tools, please acknowledge their use in your submissions and be prepared to explain and defend any code or solutions you submit.</p></blockquote><h2>How I Use AI to Make Teaching More Efficient</h2><p>I also have been using AI to improve the delivery of my courses. Here are the specific ways I leverage AI tools to enhance my teaching:</p><h3>1. <strong>Automated Class Notes</strong></h3><p>I take transcripts of my lectures and use LLMs to generate summaries and notes for students. These get posted immediately after every class, giving students a resource they can reference while the material is fresh. For example, here&#8217;s the <a href="https://github.com/noise-lab/systems-fall-2024/blob/main/agenda.md">agenda.md file</a> from my <a href="https://noise-lab.net/ml-systems/">Machine Learning for Computer Systems</a> course&#8212;an automatically generated &#8220;what did we cover&#8221; summary for each class session.</p><h3>2. <strong>AI-Assisted Exam Creation</strong></h3><p>I use past exams and instruction files with LLMs to generate draft copies of exams. Even better&#8212;I share the prompts with students so they can generate their own practice exams based on past materials and covered topics. This empowers them to take control of their preparation. You can see <a href="https://github.com/noise-lab/ml-systems/tree/main/docs/midterm">examples of past exams</a> and the <a href="https://github.com/noise-lab/ml-systems/blob/main/docs/midterm/generate-midterm.md">precise instructions</a> I provide to the LLM for exam generation in my course repository.</p><h3>3. <strong>Discussion Preparation</strong></h3><p>For classes with reading responses, I use LLMs to help organize student submissions. This helps me identify themes, generate discussion notes, and prepare to lead more engaging class conversations. To date, I have organized responses thematically around three topics: (1) requests for technical clarification (allowing me to focus my lecture towards details that students actually want to hear; (2) points that could be teed up for general discussion (helpful for class discussion, breakouts, etc.); (3) case studies that people want to hear more about (helping me go do additional research on &#8220;current events&#8221; that I can speak about in class to bring more real-world examples to class.</p><h3>4. <strong>Reducing Setup Friction in Assignments and Labs</strong></h3><p>AI has made it easier to assign more hands-on work. Much of the &#8220;scaffolding&#8221; for assignments&#8212;the tedious setup that doesn&#8217;t directly relate to the concepts I&#8217;m teaching&#8212;can now be automated. This means students spend time on the concepts that matter rather than configuration headaches.</p><h2>The Real Risk: Not Understanding</h2><p>When asked about the greatest risks of AI in the classroom, my answer is simple: <strong>people not understanding what they&#8217;re turning in.</strong> That&#8217;s why my approach emphasizes comprehension over prohibition. Students can use these tools, but they must be able to explain their work, defend their choices, and demonstrate understanding on written exams.</p><h2>Computer Science has Never Been About Coding</h2><p>A CS degree has never really been about writing code&#8212;it&#8217;s been about abstraction, specification, testing, software engineering, algorithms, and data structures. If anything, AI makes these higher-level skills even more important.</p><p>We&#8217;re moving toward a world where people aren&#8217;t writing much code anymore. Entry-level isn&#8217;t &#8220;junior developer&#8221; anymore&#8212;it&#8217;s project manager, software engineer focusing on testing and specification. The &#8220;grungy and inaccessible&#8221; parts are becoming automated, which means the differentiator is exactly what a computer science degree teaches: how to think about systems, specify requirements, test effectively, and reason about complex problems.</p><p>I believe the CS degree is actually becoming <strong>more important</strong>, not less. These models aren&#8217;t capable of higher-level reasoning&#8212;they&#8217;re good at automating tasks we can specify for them. Understanding how to specify, test, debug, and reason about software remains fundamentally human work.</p><h2>The Bottom Line</h2><p>We can&#8217;t deny the existence of technology. We have to teach within the world as it is, not as we wish it were. That means embracing AI tools, teaching students to use them responsibly, and focusing on the enduring skills that make computer scientists valuable: clear thinking, specification, testing, and the ability to reason about complex systems.</p><div><hr></div><p><em>This post is based on an interview conducted for The Chicago Maroon in November 2025.</em></p>]]></content:encoded></item><item><title><![CDATA[A Handful of Companies Control the Majority of the Internet's Core Infrastructure]]></title><description><![CDATA[Presenting our research on DNS and web hosting consolidation to the IETF DINRG community.]]></description><link>https://practicespace.substack.com/p/a-handful-of-companies-control-the</link><guid isPermaLink="false">https://practicespace.substack.com/p/a-handful-of-companies-control-the</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Tue, 04 Nov 2025 20:40:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CQO_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Presented at IETF DINRG, November 2025</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://practicespace.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://practicespace.substack.com/subscribe?"><span>Subscribe now</span></a></p><p>The Internet feels vast and distributed, but the reality is far more concentrated than most people realize. In our recent presentation to the <a href="https://irtf.org/dinrg">IETF&#8217;s Decentralized Internet Infrastructure Research Group (DINRG)</a>, we shared findings that reveal just how dependent the modern internet has become on a handful of organizations&#8212;and why that matters for everyone who relies on the web.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CQO_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CQO_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 424w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 848w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 1272w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CQO_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png" width="1445" height="787" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:787,&quot;width&quot;:1445,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:728595,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/178021481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CQO_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 424w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 848w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 1272w, https://substackcdn.com/image/fetch/$s_!CQO_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca577b0-d61f-4b06-a12e-5768bd9bbd68_1445x787.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>The Main Finding: Extreme Consolidation</h2><p>Our <a href="https://arxiv.org/abs/2110.15345">research paper</a>, <strong>&#8220;Measuring the Consolidation of DNS and Web Hosting Providers,&#8221;</strong> analyzed the Tranco top 1 million domains plus the top 10,000 sites from six global vantage points. What we found was striking:</p><p><strong>Two organizations&#8212;Cloudflare and Amazon&#8212;each host over 30% of popular domains for both DNS and web hosting services.</strong> When you expand to the top five providers (adding Akamai, Fastly, and Google), these organizations control 60% of index pages in the top 10,000 websites and host the majority of external page resources.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qQU2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qQU2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 424w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 848w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 1272w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qQU2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png" width="577" height="431" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:431,&quot;width&quot;:577,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36823,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/178021481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!qQU2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 424w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 848w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 1272w, https://substackcdn.com/image/fetch/$s_!qQU2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcc6c00-4752-43d4-b8a3-cb579be63fd7_577x431.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Perhaps even more concerning is the fact that <strong>over 70% of top domains rely on a single organization for DNS resolution.</strong> This means that when one of these providers experiences an outage, the impact ripples across a massive portion of the internet.</p><h2>A Global Phenomenon</h2><p>One might assume that Internet infrastructure would vary significantly by region, with different providers dominating in different parts of the world. Our measurements from six globally distributed vantage points revealed otherwise: <strong>the consolidation trend is remarkably consistent worldwide.</strong> The same major players dominate regardless of where you&#8217;re accessing the internet from.</p><p>This wasn&#8217;t always the case. The internet was designed to be resilient through distribution and redundancy. Yet economic forces, economies of scale, and the complexity of modern infrastructure have driven websites and services toward a small number of hyperscale providers.</p><h2>Our Measurement Pipeline</h2><p>To understand consolidation, we built a comprehensive measurement pipeline that:</p><ol><li><p><strong>Identified authoritative nameservers</strong> for DNS hosting across all domains</p></li><li><p><strong>Detected web content hosting providers</strong> for both index pages and external resources</p></li><li><p><strong>Mapped infrastructure to organizations</strong> rather than just individual autonomous systems (AS)</p></li><li><p><strong>Measured from multiple vantage points</strong> to capture global patterns</p></li></ol><p>The distinction between measuring by organization versus by AS is critical. Amazon, for example, operates multiple autonomous systems (Amazon-02, AMAZON-AES, etc.), but consolidating these under the organizational umbrella reveals the true extent of concentration.</p><h2>DNS and Web Hosting is Consolidated </h2><p>Looking at our nameserver analysis, Amazon and Cloudflare dwarf all other providers. In the top 10,000 domains:</p><ul><li><p>Amazon hosts over 2,500 domains for DNS (with most being reachable)</p></li><li><p>Cloudflare serves approximately 1,300 domains</p></li><li><p>The next tier (Akamai, Google) each serve only a few hundred domains</p></li></ul><p>For web hosting, the picture is even more dramatic. Among the top 100 websites, Cloudflare alone hosts around 70% of domains. As you move down to the top 10,000 sites, the major five providers (Cloudflare, Amazon, Akamai, Fastly, Google) maintain consistent dominance at around 40-50% market share each.</p><h2>Three Risks of Consolidation</h2><h3>1. Reduced Resilience to Outages</h3><p>The consolidation of infrastructure means that <strong>single points of failure now affect enormous swaths of the Internet.</strong> We&#8217;ve already seen this play out:</p><ul><li><p>The 2016 Dyn DDoS attack took down major websites across the internet</p></li><li><p>The 2021 Facebook BGP incident made Facebook and its properties unreachable worldwide</p></li><li><p>Routine AWS degradations affect thousands of dependent services</p></li></ul><p>As one participant in at the DINRG discussion noted, the October 2025 AWS outage was caused by a race condition in automated DNS updates&#8212;a seemingly small technical issue that cascaded across services like DynamoDB, EC2, and network load balancers. </p><p>When infrastructure is this consolidated, these &#8220;unusual diseases&#8221; in one provider can become internet-wide epidemics.</p><h3>2. Increased Potential for Censorship and Content Control</h3><p>Beyond technical failures, consolidation creates concerning dynamics for online speech and content moderation. <strong>Large hosting providers exercise significant discretion over what content gets hosted and what doesn&#8217;t.</strong></p><p>As Andrew Campling astutely pointed out in the Q&amp;A, this consolidation has profound implications for free expression. We need only look at cases like Kiwi Farms&#8212;where decisions by a handful of infrastructure providers about whether to host particular content effectively determined whether that content could exist online at all&#8212;to understand the stakes.</p><p>When the majority of websites depend on the same five organizations for hosting and DNS, those organizations become de facto gatekeepers of online speech. Whether one agrees or disagrees with specific content moderation decisions, the concentration of this power in so few hands represents a fundamental shift from the internet&#8217;s original distributed architecture.</p><h3>3. Privacy and Surveillance Concerns</h3><p>With so much traffic flowing through a small number of providers, these organizations gain unprecedented visibility into internet usage patterns. The consolidation creates what amounts to surveillance chokepoints, where a handful of companies can observe&#8212;and potentially be compelled to share&#8212;information about vast portions of internet activity.</p><h2>Extending the Research</h2><p>The discussion following our presentation highlighted important directions for future work.</p><h3>Availability Zones and Backend Dependencies</h3><p><strong>Brian Trammell raised a crucial limitation of our current study</strong>: we measured front-end behavior and didn&#8217;t provide visibility into back-end dependencies within cloud providers. A website might be &#8220;hosted by Amazon,&#8221; but which availability zones? What happens when there&#8217;s an outage in US-East-1 specifically?</p><p>Future research should incorporate IP geolocation to analyze dependencies within cloud providers&#8217; infrastructure. Are sites truly distributed across availability zones, or do the consolidation patterns go even deeper than our organization-level analysis suggests?</p><h3>Building on ICANN&#8217;s Work</h3><p><strong>Christian Huitema pointed us to ongoing consolidation studies at ICANN</strong>, which are examining similar questions about DNS infrastructure. Rather than duplicate effort, we&#8217;re eager to collaborate. Our measurement pipelines and data are publicly available, and we&#8217;d like to work with ICANN and others to create an ongoing &#8220;consolidation monitor&#8221;&#8212;a dashboard that tracks these trends over time and makes the data accessible to researchers, policymakers, and the public.</p><h3>New Challenges: ECH and Encrypted DNS</h3><p>As the internet evolves, new protocols like Encrypted Client Hello (ECH) will obscure some of the signals we used in our measurements. Future studies will need to adapt methodologies to maintain visibility into consolidation trends even as more infrastructure becomes encrypted and opaque.</p><h2>What Can Be Done?</h2><p>The concentration of internet infrastructure didn&#8217;t happen by accident, and it won&#8217;t be reversed overnight. But there are concrete steps the community can take:</p><ol><li><p><strong>Establish ongoing monitoring</strong> of consolidation trends with public dashboards and regular reporting</p></li><li><p><strong>Develop resilience techniques</strong> specifically designed for data center and cloud-wide outages, not just individual server failures</p></li><li><p><strong>Create mechanisms for multi-homing</strong> that make it practical for organizations to distribute across providers</p></li><li><p><strong>Examine policy implications</strong> of infrastructure consolidation for competition, speech, and internet governance</p></li><li><p><strong>Build guardrails for automation</strong> as AI and automated systems increasingly manage critical infrastructure</p></li></ol><h2>An Invitation for Collaboration</h2><p>All of our code, data, and measurement metrics are publicly available. We&#8217;re committed to transparency in this research because we believe consolidation is a question that affects everyone who uses the internet. It&#8217;s not just an academic curiosity&#8212;it shapes the resilience, openness, and character of the global network we all depend on.</p><p>If you&#8217;re working on related questions, whether at ICANN, within a major provider, at a research institution, or as an independent researcher, we&#8217;d welcome the opportunity to collaborate. The internet&#8217;s future depends on our collective ability to understand and address these structural shifts.</p><h2>Thank You to DINRG for Re-surfacing this Work</h2><p>I want to extend my sincere gratitude to the hosts and participants of <a href="https://irtf.org/dinrg">DINRG</a> for the opportunity to present this work and for the thoughtful questions and suggestions that emerged from our discussion. </p><p>The IETF community&#8217;s commitment to understanding and improving internet infrastructure is exactly the kind of collaborative effort needed to tackle these challenges.</p><p>Special thanks to Brian Trammell for pushing us to think about availability zones and backend dependencies, to Christian Huitema for connecting us with ICANN&#8217;s parallel research efforts, and to Andrew Campling for highlighting the critical implications for free expression and online speech.</p><div><hr></div><p><strong>Read the full paper</strong>: <a href="https://arxiv.org/abs/2110.15345">Measuring the Consolidation of DNS and Web Hosting Providers</a></p><p><strong>Authors</strong>: Synthia Wang, Kyle MacMillan, Brennan Schaffner, Nick Feamster, Marshini Chetty</p><p><strong>Access our data and code</strong>: (forthcoming, stay tuned)</p><p><em>Questions, comments, or interested in collaborating? Please reach out! Subscribe to this newsletter, or reach out to me directly.</em></p><p></p>]]></content:encoded></item><item><title><![CDATA[Never Touch Overleaf Again]]></title><description><![CDATA[For people who prefer to operate in VS code, offline, or pretty much ABO (Anything But Overleaf), here&#8217;s one-time script to run that sets up a Github action that:]]></description><link>https://practicespace.substack.com/p/never-touch-overleaf-again</link><guid isPermaLink="false">https://practicespace.substack.com/p/never-touch-overleaf-again</guid><dc:creator><![CDATA[Nick Feamster]]></dc:creator><pubDate>Mon, 03 Nov 2025 15:12:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!68_N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For people who prefer to operate in VS code, offline, or pretty much ABO (Anything But Overleaf), here&#8217;s one-time script to run that sets up a Github action that:<br><br>1. Performs an hourly fetch/pull into Github from Overleaf via the Overleaf git interface (you can adjust the cron in your github action if you prefer, or obviously trigger the Github action manually).<br><br>2. Automatically pushes back to Overleaf via Overleaf git whenever you push into github.<br><br><a href="https://github.com/feamster/overleaf-sync">Github Repository</a><br><br>Aside from getting the initial project ID and Overleaf git token for the project to set up the Github action, you never even have to go to the Overleaf website. Hallelujah.<br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!68_N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!68_N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 424w, https://substackcdn.com/image/fetch/$s_!68_N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 848w, https://substackcdn.com/image/fetch/$s_!68_N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 1272w, https://substackcdn.com/image/fetch/$s_!68_N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!68_N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png" width="772" height="525" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/926752c5-5a80-484b-95ee-4d28aba339da_772x525.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:525,&quot;width&quot;:772,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88731,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://practicespace.substack.com/i/177894417?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!68_N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 424w, https://substackcdn.com/image/fetch/$s_!68_N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 848w, https://substackcdn.com/image/fetch/$s_!68_N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 1272w, https://substackcdn.com/image/fetch/$s_!68_N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926752c5-5a80-484b-95ee-4d28aba339da_772x525.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><br>(And really, if you&#8217;re still using Overleaf, you might ask yourself why...If you want to make your life difficult, go right ahead, but VS Code + Latex Workshop does everything Overleaf does but is a thousand times better in every other way.)</p>]]></content:encoded></item></channel></rss>