<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Shai Sachs</title>
  <link href="https://shaisachs.com/feed.xml" rel="self"/>
  <link href="https://shaisachs.com/"/>
  <updated>2026-05-09T13:39:38+00:00</updated>
  <id>https://shaisachs.com/</id>
  <author>
    <name>Shai Sachs</name>
  </author>
  <generator>Jekyll v3.10.0</generator>

  
  <entry>
    <title>Context cohesion</title>
    <link href="https://shaisachs.com/2026/05/09/context-cohesion.html"/>
    <updated>2026-05-09T09:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/05/09/context-cohesion</id>
    <content type="html">&lt;p&gt;It’s not the size of the context window, it’s the cohesion of what’s inside.&lt;/p&gt;

&lt;p&gt;That’s my latest theory of agentic coding. In my travels I’ve noticed that when I give the agent a focused, cohesive context, it can do well. Thrashing sets in when I start to throw in too much “other stuff.”&lt;/p&gt;

&lt;p&gt;My mental model of LLMs is that they’re giant dictionaries; that’s grossly over-simplified of course. With dictionaries, the better-focused your search terms, the more likely you are to get results. This approach matches my own approach to engineering: ideally everything from Jira items to microservices to individual classes should be cohesive and well-focused. Why should prompts be any different?&lt;/p&gt;

&lt;p&gt;The agents are getting smarter and smarter, of course, and I think the labs are working around the problem of incohesive context in various ways - periodic compaction and things like that. But ultimately I think it’s just so many parlor tricks around what is something of a fundamental limitation - if you try to do too much you wind up doing nothing.&lt;/p&gt;

&lt;p&gt;As a result I’ve taken to tweaking the “task list” part of my spec-driven development approach, so that each task is tightly focused on just the problem at hand, with all of the context it needs on a single line. I’ll link my approach in the comments, but the TLDR is that I start with an implementation plan and then I ask the agent to turn it into a task list; then I feed the task list through a Wiggums loop.&lt;/p&gt;

&lt;p&gt;The key learning, for me, is that the task list creation has to be somewhat dumb:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Read ./docs/plans/add-dingbats/plan.md and turn it into a task list. Each task should be specific and include all of the information it needs to complete the task. Feel free to repeat yourself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The resulting task list is verbose and repetitive, by design. If someone handed me a task list like that I’d be annoyed. But guess what, agents don’t get annoyed! Or if they do they don’t mention it and I’m not paying attention anyway. The upshot is that each iteration of my Wiggums loop is well-scoped and more likely to be successful.&lt;/p&gt;

&lt;p&gt;I’m thinking about adding a project-level “guardrails.md” file that contains “traps the agent might fall into during this project.” Then each iteration of my Wiggums loop can be:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Get the next task from ./docs/plans/add-dingbats/tasks.md. Then read ./docs/plans/add-dingbats/guardrails.md. Do the task from the task list but respect the guardrails as you do so.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I haven’t gotten there but it seems like an obvious tweak, and it keeps my agent from reading a bunch of unnecessary docs.&lt;/p&gt;

&lt;p&gt;What I’d love to see is tooling that helps me see how cohesive the context window is, on a task-by-task basis, so I can pivot over time. Right now the tooling is pretty coarse - we’re looking at the amount of context, but in my view a little bit of poorly cohesive context is worse than a lot of tightly-scoped context. I’d love to hear about tricks to get some transparency there - please share if you have any!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Abstraction Literacy and the Software Printing Press</title>
    <link href="https://shaisachs.com/2026/04/23/abstraction-literacy-software-printing-press.html"/>
    <updated>2026-04-23T08:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/04/23/abstraction-literacy-software-printing-press</id>
    <content type="html">&lt;p&gt;I’m really fascinated by the phenomenon which Nilay Patel terms &lt;a href=&quot;https://www.theverge.com/podcast/917029/software-brain-ai-backlash-databases-automation&quot;&gt;software brain&lt;/a&gt;. I think he gets a couple of things wrong, but he is absolutely right that a new skill is becoming crucial; I think of it as abstraction literacy.&lt;/p&gt;

&lt;p&gt;Software brain is the mindset that views “the whole world as a series of databases that can be controlled with the structured language of software code.” If you follow that mindset to its logical conclusion, you wind up “flattening” your life so it can fit in a database and be automated. Everything you do or experience turns into a row in a relational database.&lt;/p&gt;

&lt;p&gt;There is, indeed, something horrifying in that vision, as grotesque as a clockwork orange. Patel claims that no one wants it, though he conflates AI as a brand with automation as a concept - an interesting example of guilt by association. AI has pretty bad polling numbers, as he says, but that doesn’t mean that automation is undesirable as such. Still, I’m willing to believe that automating everything, everywhere, all at once is not all that popular, if only because it sounds so alien and uncomfortable.&lt;/p&gt;

&lt;p&gt;However, that doesn’t mean it won’t happen, to some degree or another. We have a certain taste for technological progress and legibility even at great cost - that, at least, is the argument of James Scott’s &lt;a href=&quot;https://yalebooks.yale.edu/book/9780300078152/seeing-like-a-state/&quot;&gt;Seeing Like a State&lt;/a&gt; and the reason Jared Diamond called agriculture &lt;a href=&quot;https://psyc.franklin.uga.edu/sites/default/files/CVs/Agriculture.pdf&quot;&gt;The Worst Mistake in the History of the Human Race&lt;/a&gt;. I think that if we want to avoid the traps that we’ve fallen into in the past, we need to think in terms of skill proliferation.&lt;/p&gt;

&lt;p&gt;We are entering the era of the &lt;a href=&quot;https://shaisachs.com/2025/11/25/software-printing-press.html&quot;&gt;software printing press&lt;/a&gt;, and software is becoming dramatically cheaper to produce. That does not mean that software will eat the world, exactly, but it does confer an advantage on those who know how to reshape real-world tasks so that they can be made into (cheap) software. That’s what I call abstraction literacy.&lt;/p&gt;

&lt;p&gt;Simon Willison, no slouch at abstraction, has been quite busy building &lt;a href=&quot;https://simonwillison.net/2025/Dec/10/html-tools&quot;&gt;HTML tools&lt;/a&gt; with the help of Claude Code; he’s somewhere north of 200 as of this writing. He encounters a problem, spins up a prompt, and a little while later he’s got an HTML and Javascript bundle to solve his problem. In the bargain he’s shared it out to the world. It’s one of the more charming applications of the software printing press, in my estimation - you might even say it’s artisanal.&lt;/p&gt;

&lt;p&gt;I like this style of automation quite a bit, and I think there’s something really interesting about a world in which it’s readily available to anyone whose mind is oriented in a certain way - in just the way that books became readily available to literate people after 1440.&lt;/p&gt;

&lt;p&gt;This style of working with AI is very different than what Patel is referencing in his poll numbers. ChatGPT is the flagship AI product for direct-to-consumer use cases, and &lt;a href=&quot;https://cdn.openai.com/pdf/a253471f-8260-40c6-a2cc-aa93fe9f142e/economic-research-chatgpt-usage-paper.pdf&quot;&gt;OpenAI’s Sept 2025 study&lt;/a&gt; found that only 5.1% of messages are for “technical help.” Coding agents are boasting MAU numbers that top out, generously, at 20 million for Github Copilot - a distant shadow of ChatGPT’s 900 million. Very few people, when asked about AI, think about abstraction literacy and bespoke tooling.&lt;/p&gt;

&lt;p&gt;To be clear - that may never change, and the phenomenon of HTML tools and similar artisanal automations may remain a curious niche and nothing more. But if, on the other hand, abstraction literacy proliferates, and we start to see more widespread use of the software printing press - then it’s clear that the potential really is quite exciting. And it doesn’t require a wholesale mindset shift to “software brain”; abstraction literacy is a fairly common skill, not all that different from general numeracy. It’s not trivial, but it’s hardly out of reach.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Getting started with headless coding</title>
    <link href="https://shaisachs.com/2026/04/15/getting-started-with-headless-coding.html"/>
    <updated>2026-04-15T20:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/04/15/getting-started-with-headless-coding</id>
    <content type="html">&lt;p&gt;I’ve finally had a chance to try out some headless coding over the last few weeks, and by and large it’s working out pretty well! I don’t think I’ve discovered anything particularly revolutionary - I’m mostly stealing ideas from others and adapting them to my workflow - but I’ve definitely stumbled into some useful practices. Here’s what I’ve figured out so far.&lt;/p&gt;

&lt;h2 id=&quot;what-is-headless-coding&quot;&gt;What is headless coding?&lt;/h2&gt;

&lt;p&gt;Let’s start with the basics: headless coding is the practice of writing code by prompting a coding agent, and avoiding the use of an IDE. (The IDE is the “head.”) The point is not that IDEs are bad, as such, but rather that they’re unnecessary, because your interface with the code is the prompt (as input) and the execution results (as output.) The code is a black box.&lt;/p&gt;

&lt;p&gt;Claude Code is the poster child for headless coding, but I use codex. Here’s an example of a really simple headless coding session:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &quot;Write a python script called hello.py which prints &apos;hello world&apos;.&quot;
python hello.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The same thing can be done in Claude Code, Gemini, or Cursor Agent, and most of what I have to say here should transfer to those other agents as well. (But I haven’t checked, feel free to correct me in the particulars.)&lt;/p&gt;

&lt;h2 id=&quot;one-liners-and-skills&quot;&gt;One-liners and skills&lt;/h2&gt;

&lt;p&gt;The example above is a pretty simple one-line prompt, but a one-line prompt can get you reasonably far. A more realistic example might be:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &quot;Refactor the code in WidgetService so that persistence logic lives in a new WidgetRepository. Make sure all tests pass before you finish. Then commit everything to git.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s easy to extend to multi-line prompts too - just throw together some text into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prompt.md&lt;/code&gt;, then do: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat prompt.md | codex exec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you’re using Jira you can in principle use that as your source of prompts; configure the Atlassian MCP server, and then try a prompt like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &quot;Read the specifications in Jira item SOMEPROJ-1234, then implement them. Make sure all tests pass before you finish. Then commit everything to git.&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When you are done, if your permissions are right, you should have your code waiting for you in the git commit log; you can run some smoke tests and then push.&lt;/p&gt;

&lt;p&gt;At a certain point, typing “Make sure all tests pass…” and such becomes tiresome, so I recommend using an agentic skill. I’ve created a skill for myself, which does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Accept a prompt as input&lt;/li&gt;
  &lt;li&gt;Spin up a child instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codex exec&lt;/code&gt; to actually implement the prompt&lt;/li&gt;
  &lt;li&gt;Make sure all tests pass&lt;/li&gt;
  &lt;li&gt;Commit to git when you are done&lt;/li&gt;
  &lt;li&gt;Include the prompt, as well as the name of the agent and the model used, in the extended git commit message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The skill uses a helper bash script which prepares the git commit. That means that my extended commit messages are all consistent, which may become useful if I need to parse them in the future; it also spends less tokens because my agent doesn’t need to figure out what “commit to git” means when it reads the skill.&lt;/p&gt;

&lt;p&gt;Now my one-liner is a little cleaner:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &apos;$prompt-com Refactor the code in WidgetService so that ...&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The result is a really nice git log that preserves my prompt history for posterity, and of course nicely refactored code in the bargain.&lt;/p&gt;

&lt;p&gt;Not every prompt is simple, and eventually you reach a more complex use case. The agent tries its best against your prompt, but there is too much code to inspect, too many changes to make, and it exhausts its context window. Or worse yet, the contents of the window become uncohesive and the code quality starts thrashing because the agent is no longer focused on a single “thought.”&lt;/p&gt;

&lt;h2 id=&quot;spec-driven-development-and-the-coding-loop&quot;&gt;Spec driven development and the coding loop&lt;/h2&gt;

&lt;p&gt;To manage this sort of complexity, we have to shift our attention away from the code and toward specs. We need to focus pretty carefully on the final vision of what we want to happen, including clear acceptance criteria, desired structure of the code, and anticipated changes or future directions we want to accommodate.&lt;/p&gt;

&lt;p&gt;I recommend spending a good amount of time drafting specifications that lay out as much detail as possible along these lines. Sometimes the Jira item description is good enough that you can pull it directly. In any case I strongly recommend versioning specifications alongside my code, and incorporating the Jira item into the file path. For example the specs for Jira item SOMEPROJ-1234 should live in a location like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./docs/plans/SOMEPROJ-1234-brief-desc/specs.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Commit that thing, then get an implementation plan started:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &apos;$prompt-com Read ./docs/plans/SOMEPROJ-1234-brief-desc/specs.md, then write an implementation plan. If there are any clarifying questions, include them in the plan in a &apos;Questions&apos; section. Store the plan at ./docs/plans/SOMEPROJ-1234-brief-desc/plan.md&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s worth giving the implementation plan a decent review, and if there are questions, provide the agent with answers and revise, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codex exec &apos;$prompt-com The WidgetService does not need to know about joins to the fidget table - modify the implementation plan at ./docs/plans/SOMEPROJ-1234-brief-desc/plan.md accordingly.&apos;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the plan is in order, create a task list:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;codex exec &apos;$prompt-com Turn the implementation plan at ./docs/plans/SOMEPROJ-1234-brief-desc/plan.md into a Markdown-formatted task list at ./docs/plans/SOMEPROJ-1234-brief-desc/task.md.&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The purpose of the task list is to create an artifact which the agent will burn down (as we’ll see in a minute.) As the agent moves to implementation, the plan should remain mostly stable, but the task list will drive the coding loop.
x
The task list should be a fairly straightforward translation of the implementation plan, although it’s worth a glance just to make sure nothing went haywire.&lt;/p&gt;

&lt;p&gt;Now it’s time for the fun part!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tasklist=&quot;./docs/plans/SOMEPROJ-1234-brief-desc/task.md&quot;
while true ; do
  incomplete_count=$(grep -E &apos;^\s- \[ \]&apos; &quot;$tasklist&quot; | wc -l)
  if [[ &quot;$incomplete_count&quot; -lt 1 ]]; then
    break;
  fi

  codex exec &quot;Find the first incomplete task in $tasklist. Execute it with the \$prompt-com skill. Then update the task list to mark the task complete.&quot;
done

echo &quot;Task done&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This loop is known as the “Ralph loop” or the “Wiggums loop” owing to &lt;a href=&quot;https://ghuntley.com/loop/&quot;&gt;Geoffrey Huntley&lt;/a&gt;. The idea is simple but quite clever: we break a large task down into small tasks, and feed those tasks to the agent one-at-a-time until we’re done. Each iteration of the loop is a fresh context window for the agent, so there is no need to do anything clever with context compaction and the like. You could say it’s context engineering taken to its logical conclusion.&lt;/p&gt;

&lt;p&gt;I’ve created a little skill called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$task-do&lt;/code&gt; to manage the task list mechanics for me, so in practice I just tell the agent: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codex exec &quot;\$task-do $tasklist&quot;&lt;/code&gt;. That’s a nice convenience, but it does reduce the token spend a little because the skill includes a deterministic script to do things like “Find the first incomplete task” - the agent doesn’t need to think about that.&lt;/p&gt;

&lt;p&gt;The results are pretty astounding: lots and lots of code gets written, and it’s all hands-off-keyboard time. I spend an hour or two on the specs/implementation plan phase, depending on the complexity of the task, but then I kick off the coding loop and go do something else. Days’ worth of code can be written this way, and the resulting code is pretty decent and generally works well. The specs and implementation plan are interesting artifacts that could be brought to bear on future maintenance, if needed, and become useful documentation of my original intent.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;There are definitely some places to explore improvements to this process. Most obviously, how can I improve the specs-writing process, and can I gave the agent an “implementation-plan-writing” skill that will ensure specs get translated to plans with good fidelity? How do I ensure that the implementation plan follows red/green TDD practices routinely?&lt;/p&gt;

&lt;p&gt;Relatedly, I need to incorporate Architecture Decision Records (ADRs) into the process more snappily. The agent should read ADRs and judge the implementation plan against them. It should also propose new ADRs that may be needed - and maybe I can draft those while it’s coding.&lt;/p&gt;

&lt;p&gt;From a token mechanics perspective, there are obviously places to improve efficiency. The planning step clearly needs a rigorous thinking model like Opus, but simple tasks can be readily offloaded to a speedy model like Composer. Consequently it may be a good idea to mix-and-match agents so I’m not tied to GPT models for everything I do.&lt;/p&gt;

&lt;p&gt;Moving forward, how do we review all this code that’s being generated? I haven’t yet, but I hope to start implementing some of the ideas Ankit Jain presented in &lt;a href=&quot;https://www.latent.space/p/reviews-dead&quot;&gt;How to Kill the Code Review&lt;/a&gt;, and incorporate these into my loop; for example, once the coding is done, spin up a QA agent, identify bugs, and feed those back to the coding agent.&lt;/p&gt;

&lt;h2 id=&quot;thoughts&quot;&gt;Thoughts&lt;/h2&gt;

&lt;p&gt;For someone who’s used to coding by hand, this process is extremely weird.&lt;/p&gt;

&lt;p&gt;You can watch the commits roll in, refreshing git log every now and again, and they will steadily accumulate. At least in my setup they have my name attached, so it looks like I’m writing code at spectacular velocity.. but I definitely did not write them! It’s the dictionary definition of alienation: code appears with my name on it, but it does not feel like mine and I don’t have a meaningful relationship to it.&lt;/p&gt;

&lt;p&gt;There is also an interesting question around when to cross over from one-liners to coding loops. Essentially, what kind of task is too complicated for the agent’s context window? I think answering this question becomes a kind of art that software engineers will learn over time, in the same way that “decompose big functions” is an art form that we’ve been refining for some time now.&lt;/p&gt;

&lt;p&gt;This practice changes the economics of what I consider feasible. If a task can be well defined and nicely decomposed, then the thought process is, “am I willing to spend about an hour to spec it out?” rather than “I need to estimate that, work out a resource allocation plan, negotiate with stakeholders, …” Refactors are something the agent does while I’m in meetings, rather than tasks I put off to another day. Data-munging is trivial. Trolling through third-party API docs and creating a client to grab some data is a 5 minute activity (and most of those 5 minutes are spent ensuring my credentials work.)&lt;/p&gt;

&lt;p&gt;The higher-order result is that I’m beginning to think in terms of an “outer loop,” which looks something like this: prototype and experiment -&amp;gt; refine approach and experiment some more -&amp;gt; polish final product. Each of those steps is its own coding loop, but now I can accomplish weeks’ worth of trial and error inside of a day or two, and the result can be much closer to the ideal state I want before I ship off to production.&lt;/p&gt;

&lt;p&gt;It’s pretty exciting to see this new practice take shape, even though I think there are still a lot of open questions and improvements to be made. I’d love to hear your learnings and suggestions!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Agentic code review</title>
    <link href="https://shaisachs.com/2026/04/08/agentic-code-review.html"/>
    <updated>2026-04-08T20:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/04/08/agentic-code-review</id>
    <content type="html">&lt;p&gt;Everyone is talking about Ankit Jain’s great piece on &lt;a href=&quot;https://www.latent.space/p/reviews-dead&quot;&gt;How to Kill the Code Review&lt;/a&gt;, and with good reason! Jain calls out a pretty big problem - we’re generating lots of code agentically, how can we review it all? In the bargain, that piece provides a pretty decent “swiss cheese” model of agentic code review. It’s AI-as-a-judge, applied to the software development life cycle. But let’s not mince words, it still makes me uncomfortable.&lt;/p&gt;

&lt;p&gt;At the end of the day this discomfort is just “human chauvinism,” as Alan Turing called it. I trust humans to review code more than I trust AI, simply because they are humans. I’m perfectly aware of all the foibles of human code review - I’m guilty of many of them myself - so it’s not rational discomfort.&lt;/p&gt;

&lt;p&gt;The big question is, how universal is this discomfort, and what will it look like when something goes pear-shaped?&lt;/p&gt;

&lt;p&gt;It’s all well and good for me to set aside my own discomfort and decide that AI-as-a-judge is good enough, guardrails will save the day, and we can in fact ship code that no human has ever laid eyes on. But what about other stakeholders? What is their discomfort level, and what level of risk are they willing to accept? When - not if! - AI-generated-and-reviewed code causes an incident, how will we learn and improve?&lt;/p&gt;

&lt;p&gt;To be clear, these questions are a little bit forward-looking. There is some time yet before we start seeing AI-only code shipped to production en masse. But it is already reality in some places, and I think it will become the “average” experience in reasonably short order. We had better start coming up with answers!&lt;/p&gt;

&lt;p&gt;The topic is very much on my mind, and I hope to contribute useful suggestions as we move forward. But I admit I only have pretty thin thoughts right now. I’d love to hear yours!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Mermaid</title>
    <link href="https://shaisachs.com/2026/03/31/mermaid.html"/>
    <updated>2026-03-31T18:15:00+00:00</updated>
    <id>https://shaisachs.com/2026/03/31/mermaid</id>
    <content type="html">&lt;p&gt;I’ve recently started ditching Lucidchart diagrams in favor of &lt;a href=&quot;https://mermaid.js.org/&quot;&gt;Mermaid&lt;/a&gt;, and its companion &lt;a href=&quot;https://mermaid.live/&quot;&gt;live editor&lt;/a&gt;. I’m really enjoying it! It’s just another step in my gradual return to text, though I suppose there is a bigger story there.&lt;/p&gt;

&lt;p&gt;The switch from Lucidchart (or Miro, if you prefer) to Mermaid should feel familiar to anyone who has vacillated between GUIs and CLIs. The former is more intuitive and fun, while the latter is more powerful and composable. Text is a simple but powerful modality!&lt;/p&gt;

&lt;p&gt;The first thing I notice with Mermaid is that I lose the ability to do freehand layouts - some controls are available, but Lucidchart is by far more flexible and intuitive for fine-grained layout control. Instead, I keep myself to identifying the nodes and edges of a graph, and Mermaid determines the layout. That is a weakness but also a blessing - I find sequence diagrams to be a royal pain in the neck to layout freehand, but they are absolutely trivial in text. On the other hand, if I need to depict a complex information flow across a suite of microservices, and it’s important to highlight patterns and anomalies, then careful layout is crucial. So I’m unlikely to drop Lucidchart altogether, but Mermaid fits the bill for a wide variety of simpler use cases.&lt;/p&gt;

&lt;p&gt;What I really enjoy about Mermaid is that it integrates really nicely into my document-writing process. I can flip back and forth between prose narration and diagram edits without shifting context or opening a different app. In particular I find myself using Confluence’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mermaid&lt;/code&gt; command, which renders a block of Mermaid code embedded directly into the document. The mechanism is a little clunky - I tend to hide the Mermaid code in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/expand&lt;/code&gt; block to focus the reader on the graphics - but the results are really nice. With Lucidchart I unwittingly fell into a kind of waterfall process, whereby I’d write a bunch of text for a while, and when I’m done with that I turn to diagram layout. With Mermaid I find that the text and diagram remain in active conversation with each other, that tweaks in the text readily become tweaks in the diagram and vice versa. It’s a much cleaner way to think, and produces more up-to-date diagrams in the bargain. The cherry on top is that your diagram gets versioned alongside your text, with Confluence’s versioning tools, which satisfies my inner code historian. Again, none of these revelations are new to anyone who’s juggled GUIs and CLIs before - for example scientists who need to shift between LaTeX and data manipulation will likely see similar results - but it certainly is gratifying.&lt;/p&gt;

&lt;p&gt;Key to this entire transformation is the advent of text-based LLMs, which have helped me to narrow the gap between text and diagram substantially. I began this whole adventure by asking ChatGPT to turn a block of text describing an information flow into a Mermaid chart. The process needed some tweaks - at least at the outset I found that ChatGPT did not properly identify the “actors” who formed the nodes of the graph, and I had to coach it. But once I got the hang of it, I quite enjoyed the ability to more-or-less automatically traverse the bridge between prose and diagram in both directions. Sometimes I draft Mermaid code by hand, especially if the diagram in question is pretty simple, but the “automagical” tool is quite handy to have all the same.&lt;/p&gt;

&lt;p&gt;It’s not lost on me that LLMs are kicking off a Renaissance for text-based tooling. I am here for it!&lt;/p&gt;

&lt;p&gt;There is a larger story to be told, about the document generation and versioning process writ large. I am still using Confluence as the archive of record for documents, and that means I rely on Confluence version control, and that’s fine for now. But it’s an awkward fit with a more agentic workflow, in which an agent powered by a heavy-duty thinking model can take on the task of structuring a document, dig for the information to power key decisions, and revise a document according to those decisions. Recently I was working on a document, and as I was putting the finishing touches on it I realized that the system I was describing would be far simpler if I changed the eventing pattern from event-notification to event-carried-state-transfer. That in turn required digging up some more details, figuring out which pieces of the document needed to change, revising narration, tweaking the diagram, and so forth. Some day, and I think it’ll be soon, I’d like to change my workflow so that I can just prompt Opus with something like “we need to shift this approach to event-carried-state-transfer, please figure it out and make the necessary changes.” Then I could go grab some coffee and enjoy my higher layer of abstraction.&lt;/p&gt;

&lt;p&gt;I suspect that tools which automate this kind of design work are not very far off! In the meantime, if you haven’t had a chance to play with Mermaid, I highly recommend it.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>LRC for syncd lyrics</title>
    <link href="https://shaisachs.com/2026/03/22/lrc-for-syncd-lyrics.html"/>
    <updated>2026-03-22T20:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/03/22/lrc-for-syncd-lyrics</id>
    <content type="html">&lt;p&gt;I just discoverd the LRC file format, and the companion library &lt;a href=&quot;https://lrclib.net/&quot;&gt;LRCLib&lt;/a&gt;, and they are things of beauty. It’s a file format for providing time-syncd lyrics. What it enables - the ability to view lyrics that keep pace with a song as it plays on your music player - is close to miraculous, but the structure of the file is a thing of wondrous simplicity.&lt;/p&gt;

&lt;p&gt;The LRC format has some variations, but at its core it’s quite simple. It’s a newline-delimited plain text file; each line is prefixed with a timestamp, and that is followed by the lyrics which go with that timestamp. Here, for example, are the first few lines of the &lt;a href=&quot;https://lrclib.net/search/stairway%20to%20heaven&quot;&gt;Stairway to Heaven LRC&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[00:52.87]There’s a lady who’s sure&lt;/p&gt;

  &lt;p&gt;[00:56.66]All that glitters is gold&lt;/p&gt;

  &lt;p&gt;[00:59.38]And she’s buying a stairway to Heaven&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, it’s delightfully easy to read, edit, and distribute. LRCLib (which has numerous competitors) provides lyrics by UI, but also API and data product, which is exactly as it should be.&lt;/p&gt;

&lt;p&gt;My music player of choice &lt;a href=&quot;https://play.google.com/store/apps/details?id=in.krosbits.musicolet&quot;&gt;Musicolet&lt;/a&gt;, which is quite a fine specimen unto itself - if you’re on Android you’ve got to check it out. In any case LRC lyrics fit together with it like a glove. All you have to do is embed an LRC file in your MP3 file - use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USLT&lt;/code&gt; ID3 tag - and your player will nicely sync up the lyrics with the music. Magic!&lt;/p&gt;

&lt;p&gt;Obviously this find begs for a little side project, and one of these days I hope to see how many lyrics I can embed in my MP3 collection. The LRCLib database is a 21 GB SQLite file, which is quite tractable. Should be fun!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Genius.com is good, actually</title>
    <link href="https://shaisachs.com/2026/03/15/genuiscom-is-good-actually.html"/>
    <updated>2026-03-15T11:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/03/15/genuiscom-is-good-actually</id>
    <content type="html">&lt;p&gt;There is much to be said in favor of a global information network that can liberate knowledge, connect people in all corners of the earth, and so on. But a reliable way to look up song lyrics, and even song lyric meanings? Now that is genius.&lt;/p&gt;

&lt;p&gt;I am not as a rule given to shilling for odd corporate entities, certainly not for free. And let it not go unnoticed that genius.com is a mess of pop-up ads and all sorts of gunk that makes web surfing such a trial these days. That said, I tip my hat to them.&lt;/p&gt;

&lt;p&gt;I very much dig the ability to figure out what on earth a song means, and in general, genius.com delivers. It’s not particularly revolutionary, but they have a reasonably well-tuned UI for highlighting and commentating on snippets of songs, which can be useful for quirky lines or unusual words. It’s not great for competing interpretations, I should note, but it’s far superior to the default paradigm of comment-on-the-song-as-a-whole.&lt;/p&gt;

&lt;p&gt;The content itself - the song interpretations - can definitely be hit or miss. Many is the time I’ve seen purported interpretations that are shallow rewrites of the literal meaning of the words. But the content really shines for better-known, quizzical songs. Looking at you, Stairway to Heaven. The whole thing is crowd-sourced, with all of the drawbacks that entails, but the occasional flashes of brilliance are well worth the forgettable stuff.&lt;/p&gt;

&lt;p&gt;I very much wish that the business model for this kind of utility could somehow transcend the ad-driven dreck that is the rule these days, but I’m not holding my breath for that kind of magic. For now allow me to tip my hat to a site that is a really fun browse from time to time.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Songs</title>
    <link href="https://shaisachs.com/2026/02/12/songs.html"/>
    <updated>2026-02-12T20:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/02/12/songs</id>
    <content type="html">&lt;p&gt;I’ve been listening to a lot of songs lately, which is great fun. But as I am wont to do, I’ve decided to categorize them.&lt;/p&gt;

&lt;p&gt;Here is my list. You are welcome to suggest revisions!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Fantastical fever dreams. Examples: Lookin’ out my back door, The mighty quinn, Being for the benefit of Mr. Kite, C u when u get there.&lt;/li&gt;
  &lt;li&gt;Songs of national greatness. Examples: Guantanamera, American tune, 99 Luftballons, Blake’s Jerusalem. Hallelujah.&lt;/li&gt;
  &lt;li&gt;Doing crime. This category has only two songs, Mack the knife and Knockin’ on heaven’s door. But they are not to be trifled with.&lt;/li&gt;
  &lt;li&gt;Homecoming. Examples: Sloop John D, Tom Traubert’s blues, Auld lang syne,
    &lt;ul&gt;
      &lt;li&gt;Songs of search. During holidays and other special occasions, these are considered a sub-category of Homecoming. Examples: Sugar man, How much is that doggie in the window, Alice’s restaurant.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Musicals.&lt;/li&gt;
  &lt;li&gt;Closer to fine. Power of two and Tangled up in blue also belong in this category.&lt;/li&gt;
  &lt;li&gt;Love songs. If your song does not fit one of the above categories, then by common consensus (as defined in this blog post), it is a love song. Examples: Day-o, The impression that I get, Vogue. Hallelujah.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Should it not already be clear, this categorization is meant to be universal, unilateral, permanent, irrevocable, legally binding, and essentially meaningless.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>The Check</title>
    <link href="https://shaisachs.com/2026/02/01/the-check.html"/>
    <updated>2026-02-01T12:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/02/01/the-check</id>
    <content type="html">&lt;p&gt;I’ve just wrapped up publishing my short story &lt;a href=&quot;https://www.amazon.com/Check-Shai-Sachs-ebook/dp/B0GKMWYFFP&quot;&gt;The Check&lt;/a&gt; on Kindle!&lt;/p&gt;

&lt;p&gt;It’s about a quirky diner where the receipts do a little more than add up your bill, with the help of a database that has a mind of its own. Customers are confused, the owner is bemused, hilarity ensues. I wouldn’t say it’s a rom-com exactly but I won’t object if that’s how you read it.&lt;/p&gt;

&lt;p&gt;For those of you who have been following my other short stories, this one is something like the conclusion to the set of four. I’ve been working on this series for several years now, so it’s quite satisfying to put a ribbon on it. To be clear the whole thing is self-published and is very much a just-for-fun project for me. Certainly an interesting learning experience as well.&lt;/p&gt;

&lt;p&gt;This story was written quite heavily by ChatGPT, with a great deal of editing and pivoting on my part. That was a really strange process and honestly, I’m not sure how I feel about it! I will try and unpack that in a blog post some day. I tried to keep careful track of all of the twists and turns I took along the way, which makes for kind of an interesting change log.&lt;/p&gt;

&lt;p&gt;In any case, if you do want to give it a go, I’d love to hear your thoughts, and I hope you enjoy it!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Chewy Pet Health</title>
    <link href="https://shaisachs.com/2026/01/14/chewy-pet-health.html"/>
    <updated>2026-01-14T08:00:00+00:00</updated>
    <id>https://shaisachs.com/2026/01/14/chewy-pet-health</id>
    <content type="html">&lt;p&gt;This year I’m starting a new adventure, jumping over to the Pet Health team at Chewy. We’ve got a number of different products, including insurance, prescriptions, and more. The team is fresh off the launch of a pretty exciting telemedicine product last year, so part of my focus will be building on that success in the year to come. Should be quite an interesting challenge!&lt;/p&gt;
</content>
  </entry>
  
</feed>