<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>dayyan.dev</title>
        <link>https://dayyan.dev/</link>
        <description>Personal blog by Dayyan Smith</description>
        <lastBuildDate>Mon, 05 Oct 2026 20:15:12 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>© 2026 Dayyan Smith</copyright>
        <item>
            <title><![CDATA[How I Mount My Peak Design Everyday Backpack on My Bike]]></title>
            <link>https://dayyan.dev/posts/peak-design-backpack-bike-mount/</link>
            <guid isPermaLink="false">https://dayyan.dev/posts/peak-design-backpack-bike-mount/</guid>
            <pubDate>Wed, 30 Sep 2026 06:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Two years ago, I started biking to work more often. I knew I wanted to mount the backpack on the bike. Initially, I considered getting a bike bag. But I did not want to give up my <a href="https://www.peakdesign.com/eu/products/everyday-backpack">Peak Design Everyday Backpack</a>. Then I considered a <a href="https://pannierhooks.com/product/bird-of-prey-v2/">pannier kit</a> which converts any backpack into a bicycle pannier. But I thought it might make the backpack look and feel clunky. Since I would still use the backpack a lot without a bike, it was important for me that I’ll still enjoy wearing it.</p>
<p>So I figured out a way to mount my Peak Design Everyday Backpack on the side of my bike, with no additional equipment, just using the straps of the backpack.</p>
<p><img src="https://dayyan.dev/images/media/IMG_4417.JPG" alt=""></p>
<p><em>I attached the backpack to the rear rack using the external carry straps.</em></p>
<p><img src="https://dayyan.dev/images/media/IMG_4418.JPG" alt=""></p>
<p><em>To make sure the shoulder straps don't get tangled in the wheel, I fold them over and use the sternum strap to keep them in place.</em></p>
<p><img src="https://dayyan.dev/images/media/IMG_4416.JPG" alt=""></p>
<p><em>I attach the backpack as far to the back of the bike as possible to give my heal enough space when pedaling.</em></p>
<p><img src="https://dayyan.dev/images/media/IMG_4420.JPG" alt=""></p>
<p><em>When hooked in to the attachment points, the external carry straps keep the backpack securely attached.</em></p>
<p>It’s more tedious to mount and dismount than a pannier bag, and not as fool-proof. Once, one of the external carry straps came loose, likely because I hadn’t properly attached it in the first place. Because of the second strap, the backpack was still attached though.</p>
<p>I’m still looking for an easier way to mount my backpack on my bike, without getting a different backpack or adding gear to my backpack. <a href="https://pannierhooks.com/product/the-hanger/">This hanger</a> looks like it might solve my problem.</p>]]></content:encoded>
            <category>bicycle</category>
            <category>backpack</category>
        </item>
        <item>
            <title><![CDATA[Agents and AI coding]]></title>
            <link>https://dayyan.dev/posts/agents-and-ai-coding/</link>
            <guid isPermaLink="false">https://dayyan.dev/posts/agents-and-ai-coding/</guid>
            <pubDate>Sun, 28 Sep 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>When <a href="https://opencode.ai/">opencode</a> was released I started using agentic coding in my day-to-day work.</p>
<p>I had previously tried Claude Code for some personal projects, but opencode was the first terminal-based</p>
<p>AI agent I tried that worked well with my company's internal LLM proxy.</p>
<p>Recently I shared my experience with agents and AI coding with some colleagues.</p>
<p>This post is a write-up based on my preparation for that session.</p>
<h2>What are agents?</h2>
<p>There are many different definitions of "agent".</p>
<p>I'm happy with the one Simon Willison <a href="https://simonwillison.net/2025/Sep/18/agents/">settled on</a>:</p>
<blockquote>
<p>An LLM agent runs tools in a loop to achieve a goal.</p>
</blockquote>
<p>Let's break this down:</p>
<ul>
<li>LLM: The language model provides reasoning and decision-making</li>
<li>Tools: Functions the agent can call - web searches, file searches, creating and editing files, running shell commands</li>
<li>Loop: The iterative cycle of reasoning → tool use → evaluation → next action</li>
<li>Goal: A bounded objective that provides a stopping condition</li>
</ul>
<h2>Evolution of AI coding</h2>
<p>Jason Liu and Beyang Liu <a href="https://maven.com/p/be969c/rethinking-rag-from-first-principles-for-agents">describe</a> three</p>
<p>distinct areas in the evolution of AI coding:</p>
<ol>
<li>the autocomplete era</li>
<li>the RAG chat era</li>
<li>the agentic era</li>
</ol>
<p>The latest transition from the RAG chat era to the agentic era comes with an inversion of how some of the context is provided to the LLM.</p>
<p>Whereas in the RAG chat era, a RAG system first retrieved context with a similarity search on top of the original query</p>
<p>and then passed this context to the LLM to generate a response,</p>
<p>in the agentic era the LLM itself decides which tools to use and which context to fetch.</p>
<p>But this does not completely relieve the engineer from thinking about context completely.</p>
<p>While the LLM is <em>able</em> to fetch context, left unchecked, an LLM agent tends to pollute its context window with irrelevant information.</p>
<h2>Context engineering</h2>
<p>That's where context engineering comes in.</p>
<p>As Dex Horthy from HumanLayer, who coined the term "context engineering", <a href="https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-03-own-your-context-window.md">says</a>:</p>
<blockquote>
<p>Everything is context engineering.</p>
</blockquote>
<p>LLMs just turn inputs into outputs.</p>
<p>Everything that goes into the LLM is the context.</p>
<p>To get good output, you need good input.</p>
<p>Creating great context means being intentional about the prompt you give to the LLM, the additional documents that are retrieved,</p>
<p>and any chat history, including tool calls and results.</p>
<p>How can we do great context engineering in practice when using agents for coding?</p>
<blockquote>
<p>Context engineering is the delicate art and science of filling the context window with just the right information for the next step.<br>
— <a href="https://x.com/karpathy/status/1937902205765607626">Andrej Karpathy</a></p>
</blockquote>
<h2>My workflow</h2>
<p>What works well is tackling an implementation in phases.</p>
<p>Along the way, I create artifacts (markdown files) to help transition between phases.</p>
<p>This approach prevents the history of a previous phase from polluting the context window of the next one.</p>
<p>The input to one phase should only be the outcome of the previous phase.</p>
<p>The phases in my workflow (and many others') are: research, plan, implement.</p>
<p>How you got to the result of the research is not relevant when planning and how you decided on a specific plan is not relevant</p>
<p>during implementation.</p>
<p><strong>Research</strong></p>
<p>During the research phase, the goal is to understand the codebase, the data flow, potential problems and their causes.</p>
<p>Sometimes I skip this phase or include some minor research in the planning phase.</p>
<p><strong>Plan</strong></p>
<p>During the plan phase, the goal is to decide on an approach to implement.</p>
<p>I usually start by asking for possible implementation approaches, explore them, challenge the provided suggestions,</p>
<p>clear up misconceptions and then decide on an approach for which I let the agent write a plan.</p>
<p><strong>Implement</strong></p>
<p>Once the plan is set, the implementation can commence.</p>
<p>I usually do this in small iterations, following the plan and reviewing code changes along the way.</p>
<p>When possible, I start by writing failing tests and then continue by making the tests pass.</p>
<p>What do you do when the result of the implementation is wrong? Here's Dex Horthy <a href="https://x.com/dexhorthy/status/1971303611117580792">again</a>:</p>
<blockquote>
<p>Implementation is compiling the spec to code.</p>
</blockquote>
<blockquote>
<p>If your compiled program is wrong, you don't change the assembly, you rewrite the code and recompile.</p>
</blockquote>
<blockquote>
<p>If your code is wrong, don't resteer live, go fix the plan and restart the implementation.</p>
</blockquote>
<p>Put more generally, the impact hierarchy for coding agents explains what you should spend human effort on.</p>
<h2>Impact hierarchy for coding agents</h2>
<p>In keeping with my pattern of freely copying from Dex and the folks at HumanLayer, here's the <a href="https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md">impact hierarchy for coding agents</a> they propose.</p>
<table>
<thead>
<tr>
<th>Level of Abstraction</th>
<th>Error</th>
<th>Impact</th>
<th>Problem</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Core Infrastructure</strong></td>
<td>1 Bad Line of Agent Instructions</td>
<td>100,000+ Bad Lines of Code</td>
<td>Core Infrastructure</td>
</tr>
<tr>
<td><strong>Specification</strong></td>
<td>1 Bad Line of Specification</td>
<td>10,000+ Bad Lines of Code</td>
<td>Wrong Problem</td>
</tr>
<tr>
<td><strong>Research</strong></td>
<td>1 Bad Line of Research</td>
<td>1,000+ Bad Lines of Code</td>
<td>Misunderstanding the System</td>
</tr>
<tr>
<td><strong>Plan</strong></td>
<td>1 Bad Line of Plan</td>
<td>10-100 Bad Lines of Code</td>
<td>Wrong Solution</td>
</tr>
<tr>
<td><strong>Implementation</strong></td>
<td>1 Bad Line of Code</td>
<td>1 Bad Line of Code</td>
<td>1 Bad Line of Code</td>
</tr>
</tbody>
</table>
<p>At the very top with the most impact we have a bad line in your agent instructions, e.g. <code>CLAUDE.md</code> or <code>AGENTS.md</code>.</p>
<p>It affects every phase in your workflow and every session.</p>
<p>I started my AI coding journey without an <code>AGENTS.md</code> file to get an understanding of the behavior of an agent without it.</p>
<p>Over the past months I've been slowly adding some instructions, and monitoring how it affects the coding agent.</p>
<p>The remaining levels of abstraction align closely with the phases of the workflow described above.</p>
<p>The specification is the input to the research phase, the research is the input to the plan phase,</p>
<p>and the plan is the input to the implementation phase.</p>
<p>As you step down these levels of abstraction, the impact lessens.</p>
<h2>Conclusion</h2>
<p>I'm still working on getting a better understanding for what works when coding with AI.</p>
<p>For example, I'm currently interested in ways to streamline the hand-off between phases.</p>
<p>Currently, this is a very manual process for me.</p>
<p>I'm not re-using any prompts.</p>
<p>Additionally, I'm curious about how to effectively use intentional compaction to keep the context window relevant.</p>
<p>What helps me is reading others' experience with AI agents.</p>
<p>Here are some posts that I've found helpful:</p>
<ul>
<li><a href="https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md">Dex Horthy</a> on getting AI to work in complex codebases.</li>
<li><a href="https://calv.info/you-still-need-to-think">Calvin French-Owen</a> on how different AI coding tools shift your "thinking budget" between providing the right context, planning, implementation, and review.</li>
<li><a href="https://blog.nilenso.com/blog/2025/05/29/ai-assisted-coding/">Atharva Raykar</a> on the Nilenso blog on AI-assisted coding for teams that can't get away with vibes.</li>
<li><a href="https://www.seangoedecke.com/ai-agents-and-code-review/">Sean Goedecke</a> on how being good at code review translates to being effective with AI coding agents, emphasizing the importance of structural thinking over nitpicky line-by-line fixes.</li>
<li><a href="https://ashtom.github.io/developers-reinvented">Thomas Dohmke</a> on how developers are evolving through distinct stages of AI adoption, from skeptic to strategist, and how the role is shifting from writing code to orchestrating and verifying AI-generated work.</li>
<li><a href="https://vickiboykis.com/2025/07/16/my-favorite-use-case-for-ai-is-writing-logs/">Vicky Boykis</a> on her favorite use-case for AI: writing logs.</li>
<li><a href="https://lucumr.pocoo.org/2025/7/30/things-that-didnt-work/">Armin Ronacher</a> on agentic coding things that didn't work.</li>
<li><a href="https://zed.dev/blog/why-llms-cant-build-software">Conrad Irwin</a> on the Zed blog on why LLMs can't really build software.</li>
<li><a href="https://steipete.me/posts/2025/optimal-ai-development-workflow">Peter Steinberger</a> on his AI coding workflow.</li>
</ul>
<p>Bonus: <a href="https://www.sh-reya.com/blog/ai-writing/">Shreya Shankar</a> on writing in the age of LLMs.</p>
<p>Not directly related to coding but still relevant for software engineers.</p>
<p>If you're new to AI coding agents, I'd recommend:</p>
<p>Download a coding agent and try using it for most (if not all) of your coding work for a week.</p>
<p>I like opencode for its defaults and the ease with which you can switch between models, even of different providers.</p>
<p>But any other coding agent like Claude or Codex will give you a similar experience.</p>]]></content:encoded>
            <category>agents</category>
            <category>ai coding</category>
            <category>context engineering</category>
            <category>software engineering</category>
        </item>
        <item>
            <title><![CDATA[State of bahá'í song project (August 2025)]]></title>
            <link>https://dayyan.dev/posts/bahai-song-project-2025/</link>
            <guid isPermaLink="false">https://dayyan.dev/posts/bahai-song-project-2025/</guid>
            <pubDate>Thu, 28 Aug 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>bahá’í song project offers a growing collection of over 200 Bahá’í-inspired songs, with lyrics, chords, and videos.</p>
<p>The bahá’í song project YouTube channel has 4500 subscribers and <a href="https://www.bahaisongproject.com/">bahaisongproject.com</a> reaches 3000 users every month.</p>
<p>The current architecture for the website evolved from my experimentation with new technologies and leveraging free-tier services.</p>
<p>I often say I’ll re-architect and refactor everything someday—but that day has yet to come.</p>
<h2>Current architecture</h2>
<p>The song sheets containing <a href="http://chordpro.org/">ChordPro</a> files with lyrics and chords live in <a href="https://github.com/bahaisongproject/bahai-songs-chordpro">this public repository</a>.</p>
<p>On each push to the repo I build and publish the song sheet PDFs.</p>
<p>The song data, such as titles, artists, tags, languages and texts the song is based are stored in</p>
<p>a Postgres database.</p>
<p>I expose the song data with a GraphQL API.</p>
<p>I finished the first version of the GraphQL API in early 2019.</p>
<p>At the time i was nearing the end of my studies in computer science,</p>
<p>but doing more machine learning research than software engineering.</p>
<p>GraphQL was very hyped-up at the time, and so it happened that the first API I've ever</p>
<p>built was a GraphQL API.</p>
<p>I generate <a href="https://www.bahaisongproject.com/">bahaisongproject.com</a> as a static website using the GraphQL endpoint.</p>
<p><a href="https://github.com/bahaisongproject/bahaisongproject.com">This repository</a> is also public.</p>
<p>The only dynamic element is search, which I added with <a href="https://www.algolia.com/">Algolia</a>.</p>
<p>I additionally use the GraphQL endpoint in a script that I run manually when creating the song sheets to add song data</p>
<p>to the song sheet.</p>
<p>I do this so that I only have to maintain the song data in one place, the database.</p>
<h2>Current pain points</h2>
<p>I frequently get messages with corrections or submissions of new songs.</p>
<p>Currently, to add or update a song, I need to spin up <a href="https://www.prisma.io/docs/orm/reference/prisma-cli-reference#studio">Prisma Studio</a> locally.</p>
<p>When I add a song, I need to update multiple tables separately.</p>
<p>This is a lot better than directly interacting with the database, but still cumbersome.</p>
<p>This means that fixes and new song submissions are often delayed.</p>
<p>Additionally, I create a song sheet in ChordPro.</p>
<p>I link the song sheet to the song data via the slug of the song title which also serves as file name of the song sheet.</p>
<p>When the song data changes in the database, I then run a local script to update the song sheets and push them, triggering another build.</p>
<p>I also need to manually trigger a rebuild of the website to include the new or corrected data.</p>
<p>These are too many steps.</p>
<p>I spend more time thinking about the steps I need to take, than with doing the actual work of adding or correcting song data.</p>]]></content:encoded>
            <category>software engineering</category>
        </item>
        <item>
            <title><![CDATA[Structuring PRs with Narrative Commits]]></title>
            <link>https://dayyan.dev/posts/narrative-commits/</link>
            <guid isPermaLink="false">https://dayyan.dev/posts/narrative-commits/</guid>
            <pubDate>Sun, 10 Aug 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>I like using what I call narrative commits (and <a href="https://www.petecorey.com/blog/2016/07/11/literate-commits/">others</a> <a href="https://www.iamjonas.me/2021/01/literate-atomic-commits.html">have called</a> literate commits) to make a PR tell a story.</p>
<p>This is helpful for reviewers and for me while working on a PR.</p>
<p>If my commits tell a story, it's easier for me to start working on a PR again after a context switch and</p>
<p>for reviewers to quickly grasp what the PR is changing.</p>
<p>It also gives reviewers the possibility to review the PR commit by commit instead of only looking at the full diff.</p>
<h2>Mystery meat</h2>
<p>I find it difficult to review PRs that do not have a description, and where I cannot look at the</p>
<p>commit history to understand what the PR is doing.</p>
<p>I do not know what's inside, until I start dissecting it.</p>
<p>Like mystery meat.</p>
<p>The only option I have is to look at the complete diff.</p>
<p>This works for smaller PRs, but gets difficult quickly for bigger PRs.</p>
<h2>Narrative commits</h2>
<p>A good first step to reduce the mystery is to write a description for the PR.</p>
<p>The next step is to make the commits tell a story.</p>
<p>You make commits tell a story by ensuring each commit does only one thing (atomic commits) and by writing concise commit messages.</p>
<p>My story usually starts with some refactoring to prepare for the changes that I'm about to make.</p>
<p>Then, when possible, I add failing tests.</p>
<p>Finally, I implement the changes to make the tests pass.</p>
<p>Here's an example:</p>
<pre><code>a8f2c94 extract the csv parser from the handler to set up isolated changes
b3e7a01 add support for multiple pool assignments - add failing tests
c5d8f92 add support for multiple pool assignments - implement
d9a4b7e handle overlapping assignments - add failing tests
e2c1f58 handle overlapping assignments - implement
</code></pre>
<p>I like continuously rebasing my PR while I'm working on it.</p>
<p>I usually don't know the exact story I want to tell when starting, but it becomes clearer as I make progress.</p>
<p>When I feel like the story in my head is diverging from the story my commits are telling, I rebase.</p>
<p>This can happen multiple times while working on a PR.</p>
<p>I like using the interactive rebase tool in the JetBrains IDEs for this, but I when I started doing this</p>
<p>I did it with the git cli directly.</p>]]></content:encoded>
            <category>code review</category>
            <category>software engineering</category>
        </item>
        <item>
            <title><![CDATA[Understanding the Decoy Effects in Consumer Choice]]></title>
            <link>https://dayyan.dev/posts/decoy-effects/</link>
            <guid isPermaLink="false">https://dayyan.dev/posts/decoy-effects/</guid>
            <pubDate>Thu, 29 Aug 2019 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>The decoy effect is a phenomenon in consumer psychology where adding a third option can significantly influence a customer's choice between two initial options.</p>
<p>Let's explore how this cognitive bias works through the lens of mobile phone plans.</p>
<p><img src="https://dayyan.dev/images/media/decoy-effects.png" alt="decoy-effects.png"></p>
<p>The diagram above illustrates the three different decoy effects on a quality-price grid.</p>
<p>The competitor and target products are fixed points, with three distinct regions where placing a decoy product can influence consumer choice.</p>
<h2>The basic setup</h2>
<p>Our target phone plan costs thirty euros per month and includes ten gigabytes, while the competitor’s plan offers six gigabytes for twenty euros.</p>
<table>
<thead>
<tr>
<th></th>
<th>Target</th>
<th>Competitor</th>
</tr>
</thead>
<tbody>
<tr>
<td>Price</td>
<td>30€</td>
<td>20€</td>
</tr>
<tr>
<td># GB</td>
<td>10</td>
<td>6</td>
</tr>
</tbody>
</table>
<h2>Asymmetric dominance</h2>
<p>Asymmetric dominance occurs when we introduce a decoy that's clearly inferior to our target product:</p>
<table>
<thead>
<tr>
<th></th>
<th>Target</th>
<th>Competitor</th>
<th>Decoy</th>
</tr>
</thead>
<tbody>
<tr>
<td>Price</td>
<td>30€</td>
<td>20€</td>
<td>35€</td>
</tr>
<tr>
<td># GB</td>
<td>10</td>
<td>6</td>
<td>9</td>
</tr>
</tbody>
</table>
<p>Here, the decoy is both more expensive and offers less data than our target, making the target appear as a more rational choice.</p>
<h2>Attraction effect</h2>
<p>When we position the decoy slightly below the target in both price and quality we can observe the attraction effect:</p>
<table>
<thead>
<tr>
<th></th>
<th>Target</th>
<th>Competitor</th>
<th>Decoy</th>
</tr>
</thead>
<tbody>
<tr>
<td>Price</td>
<td>30€</td>
<td>20€</td>
<td>28€</td>
</tr>
<tr>
<td># GB</td>
<td>10</td>
<td>6</td>
<td>7</td>
</tr>
</tbody>
</table>
<p>The decoy's presence makes the target's premium features more attractive, despite its higher price point.</p>
<h2>Compromise effect</h2>
<p>When we position the target as the "middle ground" option, in this case by creating a decoy that's more expensive but also higher quality, the compromise effect occurs:</p>
<table>
<thead>
<tr>
<th></th>
<th>Target</th>
<th>Competitor</th>
<th>Decoy</th>
</tr>
</thead>
<tbody>
<tr>
<td>Price</td>
<td>30€</td>
<td>20€</td>
<td>50€</td>
</tr>
<tr>
<td># GB</td>
<td>10</td>
<td>6</td>
<td>12</td>
</tr>
</tbody>
</table>
<p>By introducing a high-priced option, the target appears as a reasonable compromise between price and features.</p>
<p><strong>Acknowledgement</strong></p>
<p>Based on lecture notes from the winter term 2017/18 lecture Digital Communities at TU Berlin.</p>]]></content:encoded>
            <category>consumer choice</category>
            <category>psychology</category>
        </item>
    </channel>
</rss>