<?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[The Write-Ahead Blog]]></title><description><![CDATA[A place to capture my technical (and other) thoughts before they evaporate, http://tinyurl.com/writeaheadlog]]></description><link>https://writeaheadblog.com</link><image><url>https://substackcdn.com/image/fetch/$s_!Kqgb!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ce7767-13e3-429b-b0ca-c303d2236230_512x512.png</url><title>The Write-Ahead Blog</title><link>https://writeaheadblog.com</link></image><generator>Substack</generator><lastBuildDate>Sun, 12 Apr 2026 04:19:50 GMT</lastBuildDate><atom:link href="https://writeaheadblog.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Michael]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[writeaheadblog@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[writeaheadblog@substack.com]]></itunes:email><itunes:name><![CDATA[Michael]]></itunes:name></itunes:owner><itunes:author><![CDATA[Michael]]></itunes:author><googleplay:owner><![CDATA[writeaheadblog@substack.com]]></googleplay:owner><googleplay:email><![CDATA[writeaheadblog@substack.com]]></googleplay:email><googleplay:author><![CDATA[Michael]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Lobster Gating]]></title><description><![CDATA[Trust but verify with OpenClaw's Lobster plugin]]></description><link>https://writeaheadblog.com/p/lobster-gating</link><guid isPermaLink="false">https://writeaheadblog.com/p/lobster-gating</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sat, 04 Apr 2026 18:39:36 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5d4c8892-faf7-4719-a712-34cd1b7491af_5902x3935.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>OpenClaw&#8217;s a great tool but I don&#8217;t trust agents with critical flows. Like, &#8220;cancel my two o&#8217;clock tomorrow&#8221;, and toss it over the wall. No. I want confidence in the action carried out. Will the agent decide to delete all of my calendar events? Will it decide to cancel some similarly titled Task? No thanks. Whether these are carried out through CLI tools or shell commands, I need to be confident in what the agent does. To get there let&#8217;s talk about <code>exec</code>.</p><p>Imagine you have a <a href="https://github.com/steipete/gogcli">Google CLI tool</a> that lets you retrieve your Google Tasks:</p><blockquote><p>gog task list [task_list_id]</p></blockquote><p>By default, OpenClaw can make that call using <code>exec</code>. Not only can it <em>get</em> tasks but it can also <em>destroy</em> them. Agents being non-deterministic, that scares me. Let&#8217;s lock that <code>exec</code> ability down by editing OpenClaw&#8217;s <code>openclaw.json</code> config:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">...
"agents": {
  "list": [
    {
      "id": "main",
      "tools": {
        "alsoAllow": ["lobster"],
        "deny": ["exec"] // this entry
      }
    }
  ]
},
...
"tools": {
  "profile": "coding",
  "subagents": {
    "tools": {
      "alsoAllow": ["lobster"],
      "deny": ["exec"] // and this entry
    }
  }
},
...</code></pre></div><p>Let&#8217;s review this config from the bottom starting with &#8220;tools&#8221;. This uses the &#8220;coding&#8221; profile which gives <em>all </em>agents broad operational functionality like exec, file I/O, or browser access. Next, working backwards, is the &#8220;agents&#8221; declaration. It has its own &#8220;tools&#8221; configuration. In both of these places we&#8217;ve denied access to <code>exec</code>. Once you start a new session, you can confirm this restriction is in place by asking your agent, &#8220;Run &#8216;echo hello&#8217; and give me the output&#8221;. It won&#8217;t be able to. <code>exec</code> is now locked down.</p><p>Okay, so, if agents can&#8217;t use <code>exec</code> how <em>do</em> we let them run tools? Enter Lobster, a workflow shell that lets agents run multi-step tool sequences deterministically with explicit approval checkpoints.</p><p>Deterministic <em>with</em> approval checkpoints? Sign me up.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>In the JSON example above, Lobster is already configured with &#8220;alsoAllow&#8221; which is <em>additive</em> to the other capabilities provided by the &#8220;coding&#8221; profile. That means Lobster is added to the abilities which <em>are</em> allowed such as browser usage and file I/O. But enabling Lobster is only half the battle. Now we need workflow files to let agents use tools.</p><p>I&#8217;m not going to hold your hand through <a href="https://github.com/openclaw/lobster?tab=readme-ov-file#quick-start">installing Lobster</a>; it&#8217;s not installed by default alongside OpenClaw. Once you&#8217;ve got it, here&#8217;s an example Lobster <a href="https://docs.openclaw.ai/tools/lobster#workflow-files-lobster">workflow file</a> for creating a Google Task:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;yaml&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-yaml">name: tasks-add
description: "Create a task in Google Tasks with approval gate"
args:
  title:
    description: "Task title"
  due:
    description: "Due date (YYYY-MM-DD)"
steps:
  - id: build
    run: echo "gog tasks add MY_TASKLIST_ID --title \"${title}\" --due \"${due}\""

  - id: approve
    approval:
      prompt: "Create this task?"
      preview: $build.stdout

  - id: execute
    run: gog tasks add MY_TASKLIST_ID --title "$LOBSTER_ARG_TITLE" --due "$LOBSTER_ARG_DUE"
    condition: $approve.approved</code></pre></div><p>There are three steps in this flow: </p><ol><li><p>Output the intended command</p></li><li><p>Ask permission</p></li><li><p>Execute</p></li></ol><p>Steps 1 and 3 are the determinism Lobster introduces. In this example, it controls access to <code>echo</code> and <code>gog</code> (Google CLI). More specifically, the workflow surfaces the command to be executed, we can choose to approve it, and then the workflow will trigger it. <em>By using Lobster we remove non-deterministic tool calls from the agent&#8217;s tool-set.</em> That&#8217;s the critical takeaway.</p><p>The agent still needs to know when to trigger the workflow. That&#8217;s where skills come in. Here&#8217;s an example skill for creating Google Tasks:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">---
name: open-claw-create-task
description: |-
  Creates a Google Task via the Lobster tasks-add workflow.

  Use when the user:
  - Asks to create or add a task
  - Says "remind me to", "add this to my tasks", "put this on my list"
  - Wants to capture something they need to do
  - Says "make a task for", "add a to-do", "don't let me forget to"
  - Mentions a deadline and something they need to get done
  - Wants to track an action item with a due date
---

# Create Task

## Process

1. If the user hasn't provided a task title, ask for one.
2. Ask for a due date. Required. Format must be YYYY-MM-DD.
3. Invoke Lobster with the `tasks-add` workflow:

```json
{
  "action": "run",
  "pipeline": "~/.openclaw/workflows/tasks-add.lobster",
  "argsJson": "{\"title\": \"&lt;task title&gt;\", \"due\": \"&lt;YYYY-MM-DD&gt;\"}"
}
```

Lobster handles confirmation before executing. Never call `gog` directly.</code></pre></div><p>The skill tells the agent when to reach for the workflow and exactly how to invoke it. Lobster handles the rest.</p><div class="pullquote"><p><em>By using Lobster we remove non-deterministic tool calls from the agent&#8217;s tool-set.</em></p></div><p>That&#8217;s it! Deny access to <code>exec</code>, pair a Lobster workflow with a skill, and you can be confident agent-initiated actions creating, editing, or destroying are 100% approved by you &#129438;</p><div><hr></div><h4>Other Helpful Links</h4><ul><li><p>https://docs.openclaw.ai/tools</p></li><li><p>https://docs.openclaw.ai/gateway/sandboxing</p></li><li><p>https://docs.openclaw.ai/gateway/configuration-reference#agents-list-per-agent-overrides</p></li><li><p>https://docs.openclaw.ai/tools/multi-agent-sandbox-tools</p></li><li><p>https://docs.openclaw.ai/concepts/architecture</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Shorts: Encoding Correctness]]></title><description><![CDATA[Pull the thread]]></description><link>https://writeaheadblog.com/p/shorts-encoding-correctness</link><guid isPermaLink="false">https://writeaheadblog.com/p/shorts-encoding-correctness</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Mon, 30 Mar 2026 07:21:42 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/be434dce-8ca0-4402-9e76-34ac8958c4ea_1024x512.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Consider encoding the &#8220;correctness&#8221; of software into its codebase. What if this were a solution to the cognitive overhead of reviewing agent-generated code? If the agent knows the why behind what it&#8217;s building, from the immediate feature to the entire product, it becomes easier to trust the outcome. The agent no longer codes in a vacuum. And then other agents verify and keep it on track. The human review bottleneck begins to evaporate. As it does, it opens more interesting questions like how useful PR reviews are in their current form, how &#8220;eyes off&#8221; can <em>we</em> be, and even, &#8220;do we need Jira?&#8221;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Agentic Context is King]]></title><description><![CDATA[Managing context with skills and sub-agents]]></description><link>https://writeaheadblog.com/p/agentic-context-is-king</link><guid isPermaLink="false">https://writeaheadblog.com/p/agentic-context-is-king</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Thu, 19 Mar 2026 00:46:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f9e5ed36-d46a-439f-b981-fce558d0ddd8_4000x3000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It&#8217;s no longer enough to have an agent instruction file to help you code. Now you need to manage conversational context to achieve the best outputs. Agents and skills will make that happen.</p><p>To start, when you&#8217;re interacting with an LLM, like Claude or ChatGPT, you&#8217;re talking to an agent. And the back-and-forth between you and the agent is the context. You should care about this context because that&#8217;s what the agent knows. If you were to start a new session all that context would be lost. This context is what you&#8217;re managing with sub-agents and skills.</p><p>I like to think of <a href="https://code.claude.com/docs/en/sub-agents">sub-agents</a> as &#8220;side cars&#8221;, they run off to the side and have <em>their own context</em> independent of the primary conversation. What that means is the bulk of what they do is <em>lost</em> to the primary context. <em>This context is what you&#8217;re managing</em>. You might ask yourself questions like, Do I care about that lost context? Would I prefer to have that knowledge in my primary thread? Is this context something that would improve the final outputs? The answer to these boils down to whether preserving the context will be useful to you in the near-future.</p><p>Here are some examples of sub-agents I use to manage context scope, agents that</p><ul><li><p>capture architectural decision artifacts</p></li><li><p>perform adversarial functions on my code</p></li><li><p>produce project documentation</p></li><li><p>open Pull Requests</p></li></ul><p>If you need to write documentation, have an agent review your code (especially from an adversarial point of view), or fire-and-forget the opening of a PR, you can safely exclude their intermediary thinking as you often only care about the final output.</p><p>So those are sub-agents, let&#8217;s go further and talk about skills.</p><p>Skills are what I like to reach for before getting fancy with sub-agents. <a href="https://code.claude.com/docs/en/skills">Skills</a> are small, focused bits of knowledge that an agent can leverage when necessary. Examples of skills are</p><ul><li><p>common language conventions</p></li><li><p>preferences for writing tests</p></li><li><p>composing documentation</p></li><li><p>working with data models</p></li></ul><p>Unlike sub-agents, skills load directly into an agent's context; that means you get specialized knowledge without losing valuable context. For example, when I write tests for a <code>has_many</code> relationship I like to be very specific about the check. Say a parent has many children. I don&#8217;t want to test that one child exists and I don&#8217;t need to instantiate ten. I want precisely two. Why? Because I&#8217;ve seen leaky tests before where I might create two objects but there&#8217;s a third that sneaks in somehow (overly complex test harnessing). If I don&#8217;t check for precisely two and simply look for <em>inclusion</em> then I&#8217;ll get a false positive. If I check for one that doesn&#8217;t <em>prove</em> there can be many. If I check for precisely two, I catch the case that the test harness itself is bad (i.e. there are more than two). And so I encoded this in a skill&#8217;s directive like,</p><blockquote><p>Model relationships (has_many, etc.) must be tested with two associated records. Assert the collection contains exactly both using contain_exactly(item1, item2). Do not use include(one_item); that passes even when the association is broken.</p></blockquote><p>What I get from this is increased certainty that agents performing work for me take advantage of my own experience. In this case, be careful with inclusionary testing.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>What&#8217;s more, the nice thing about skills is that they can be referenced by sub-agents. That is, if I eventually want a coding agent that specializes in Ruby, I can tell it to reference all the skills I have for writing Ruby. And that&#8217;s where the two ideas link up. You can view skills as <a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">building blocks</a> to future agents; mix a little of this knowledge with that knowledge and wrap it up into a single agent that can perform the task on its own.</p>]]></content:encoded></item><item><title><![CDATA[Shifting Baselines]]></title><description><![CDATA[How quality degrades without anyone noticing]]></description><link>https://writeaheadblog.com/p/shifting-baselines</link><guid isPermaLink="false">https://writeaheadblog.com/p/shifting-baselines</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sat, 17 Jan 2026 23:24:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f95fc730-d2da-4ae1-a100-caa4a2166697_5272x3948.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Your test suite takes eleven minutes to run. When was the last time it ran in under a minute? It&#8217;s easy for that number to creep up, slowly but surely. The team grows. People come and people go. What was once two minutes became five. New engineers only knew seven minutes. Now it&#8217;s eleven. This is normal.</p><p>Ecologists have a name for this: <strong>shifting baseline syndrome</strong>. Hundreds of years ago, beavers shaped a dramatically different North American landscape. Their dams created wetland ecosystems across regions that are now dry streambeds, vast prairie, or dense forest. As trapping crashed beaver populations, those wetlands vanished and ecosystems collapsed. Each human generation grew up knowing fewer beavers and altered landscapes, accepting that inheritance as the natural state. The baseline had shifted.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>Test suites slow for many reasons, but turnover is what makes those slowdowns invisible. It shifts the baseline. The same mechanism can be seen elsewhere. Consider a team where error messages pipe into a Slack channel. Hundreds arrive daily. Most are informational, some are real errors. Extracting signal from noise becomes impossible. People stop reading it. The problem becomes invisible. New engineers join, see it&#8217;s ignored, and learn to ignore it too. The baseline shifts.</p><p>The pattern is difficult to see from inside. When someone new asks &#8220;what is going on here?&#8221; or &#8220;why does this take so long?&#8221;, the baseline hasn&#8217;t been established for them yet. That&#8217;s the moment. Listen. Then act: measure the current state, set explicit thresholds for key metrics, and schedule regular baseline audits. Document what &#8220;good&#8221; looks like before the team falls back into their normal routine.</p><p>Ecologists eventually reintroduced beavers to restore damaged ecosystems. Sometimes the equivalent intervention in software is starting fresh. More often, it&#8217;s deliberate measurement and conscious resistance to drift.</p>]]></content:encoded></item><item><title><![CDATA[Story Memory: An Agentic Programming Pattern]]></title><description><![CDATA[Preventing rework with a little extra planning]]></description><link>https://writeaheadblog.com/p/story-memory-an-agentic-programming</link><guid isPermaLink="false">https://writeaheadblog.com/p/story-memory-an-agentic-programming</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Wed, 24 Sep 2025 15:15:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2b270552-a178-4f71-abee-f77d8b7aeef9_2284x1524.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been using agent-based programming as long as the next person. It&#8217;s new. As an industry, we&#8217;re still finding our way with it. Given the bigger picture, though, it&#8217;s not going anywhere. The sooner we find best practices, patterns for taking advantage of it, the better. Here, I want to share a pattern I've been refining for nearly as long. I call it &#8220;Story Memory&#8221;. It combats an agent writing large swaths of code leaving you with little context. Let me walk you through it.</p><p>Let&#8217;s say you have some functionality to build for your software product. As nearly all devs do, you grab a story representing what needs to be done and get started. Broadly speaking, you start noodling on how to accomplish this work, you might bounce it off a coworker&#8217;s head, and then get to typing. My own take on this process has morphed to include the agent from the outset, not just when I need it to write code. And, most importantly, by the time I&#8217;m ready to build, I have a document outlining exactly what I need the agent to do.</p><p><strong>Here&#8217;s how it goes:</strong> when I get started with a story I begin by giving the agent full context. I do this in chat mode instead of coding mode. I do not want it writing yet. After the context, I tell it how I propose to frame the solution. Finally, I begin riffing on the design with the agent, leaning on my many years of software engineering experience. All the while, since I&#8217;m having an extended back and forth with the agent, I prefer to <a href="https://superwhisper.com/">talk</a> rather than type.</p><p>To be clear, this process isn&#8217;t intended to replace collaborating with a coworker, rather, its immediate purpose is to create a markdown file outlining step by step what needs to be done. You see, I do <em>not</em> want an agent running ahead of me, I do not want to lose context on what is written. I want the agent to speed me along, I want to lend it my experience, I want to maintain a high level of context on what&#8217;s written, and I want to be confident in the final results. The scaffolding I use to arrive at those final results is what I call the <code>STORY_MEMORY.md</code> file.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>This file is a synthesis of my own experience, conversing back and forth with the agent, and any additional outside influence. Once I&#8217;m happy with where I&#8217;ve arrived, I have the agent create (or edit) the file. Here&#8217;s a contrived example:</p><pre><code><code># Feature: Article Review (Interactive Q&amp;A)

## Overview
When a user searches for content and an article is returned, they should be able to open a dedicated Article Review page ...

## Implementation Checklist
- [x] **LiveView Module**
  - [x] `article_live.ex` stub created under `web_app/live/`, accepts content id via mount.

- [x] **LiveView Template**
  - [x] `article_live.html.heex` created as a blank template, to be based on `content_review_live.html.heex`.

- [x] **Route Setup**
  - [x] New LiveView route `/article/:id` added to router, following app conventions.

- [ ] **Q&amp;A Interface**
  - [x] Add a form for users to submit questions about the article.
  - [ ] On submit, use the embeddings to find relevant chunks and generate answers.
  - [ ] Display answers and supporting context in the UI.
  - [ ] Write a test to confirm this functionality.

## Notes
- Reuse as much logic and UI as possible from `content_review_live` to keep things simple and maintainable.
- Focus on the article (`content_type: "webpage"`) use case, but keep the design flexible for future expansion.
- Keep the interface clean and focused on Q&amp;A.</code></code></pre><p>The structure is simple. At the least, I like to have an overview of the task, a step by step checklist, and additional notes that might be helpful. I find the <code>[ ] </code>and<code> [x]</code> especially handy to keep track of progress. Most importantly, the work must be broken down step by step. I find this critical for working with agents when programming. It keeps us both focused on atomic tasks. This is how I maintain context, reduce rework, and speed myself along. Otherwise, I&#8217;ve found agents are liable to run ahead of me, creating files, building out functionality on their own, making assumptions, and generally leaving me with a tangled web to sort through.</p><div class="pullquote"><p>Consider adding the STORY_MEMORY.md file to your agent instructions (hence &#8220;memory&#8221;) so it always has context on the work. Additionally, you can specify how you prefer the file to be structured in the instructions as well as add it to your .gitignore file.</p></div><p>So instead of fighting with an agent to complete story work, create a file dedicated to guiding its output. Do what you always do: think the problem through, plan ahead, break the work into small steps, confer with coworkers, but add the extra step of distilling that into a <code>STORY_MEMORY.md</code> file. This way, you harness the agent's speed while maintaining control through guardrails and manageable chunks of work, while reducing the likelihood of rework and lost context.</p>]]></content:encoded></item><item><title><![CDATA[Avoiding FGA's Tuple Hell]]></title><description><![CDATA[Taming tuple explosions in Fine-Grained Authorization]]></description><link>https://writeaheadblog.com/p/avoiding-fgas-tuple-hell</link><guid isPermaLink="false">https://writeaheadblog.com/p/avoiding-fgas-tuple-hell</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Tue, 12 Aug 2025 14:54:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/690cf328-91b0-4642-87aa-5371a5af83b1_7680x4320.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Fine-Grained Authorization (FGA) is a great piece of kit. Like microservices, it adds flexibility and scale. It also brings complexity. This level of complexity is not always the right fit; sometimes, all you need is a simple role check. Easy. I don&#8217;t want to talk about those cases.</p><p>Let&#8217;s say FGA <em>is</em> the right choice. What are some initial questions to get you on your way?</p><p>For me, performance is critical. You have to avoid the &#8220;tuple explosion&#8221;. It will bring your system to its knees. To this end, think about how often your system will need to ask, <em>Can this user do this thing</em>? Now imagine all the <em>users</em>. All the <em>things</em>. All the <em>checks</em>. Those add up to pressure on the tuple store that must inform the design. It leads me to thoughts like:</p><ul><li><p>How best to shape graph traversal?</p><ul><li><p><em>Remember, we&#8217;re thinking in graphs here</em></p></li><li><p>Where are the &#8220;pivot&#8221; points in the models?</p></li><li><p>How can we reduce the number of calls?</p></li><li><p>Can we reduce how much data is retrieved?</p></li><li><p>Deep trees impact performance. Keep traversal limits in mind</p></li></ul></li><li><p>Do users switch contexts (like between organizations)?</p></li><li><p>Look for opportunities to reduce tuple count with &#8220;cascading&#8221; permissions</p><ul><li><p>This relates back to tree depth and the &#8220;pivot&#8221;</p></li><li><p>How will deletion and revocation propagate through the tree</p></li></ul></li><li><p>Can you foresee computed permissions? What might those look like?</p></li><li><p>Design around the principle of least privilege</p></li><li><p>What low-risk data is worth caching?</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>In no universe are these comprehensive. But it&#8217;s where my mind drifts first. FGA is a powerful authorization technology. And with that power comes the ability to <s>shoot yourself in the foot</s> blow your foot off. So do your future-self a favor and try to manage the size of your tuple set before it gets out of hand.</p>]]></content:encoded></item><item><title><![CDATA[From Test Suites to Outreach]]></title><description><![CDATA[My initiation into Partner-led growth]]></description><link>https://writeaheadblog.com/p/from-test-suites-to-outreach</link><guid isPermaLink="false">https://writeaheadblog.com/p/from-test-suites-to-outreach</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Wed, 30 Jul 2025 18:22:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/126b8748-8b52-4253-b67a-e5b8af4e3a8e_1024x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I got into business development as a necessity. My company was undergoing a transition that required a change in focus. And I was the senior team member in North America. Always up for a challenge, I said, &#8220;I&#8217;ll do it.&#8221; I knew where I wanted to start.</p><p>I had one partner in mind. Our team had many stories attached to their product. They had a partner program. They were growing. &#8220;Perfect&#8221;, I thought. And it was, but my na&#239;vet&#233; began to show quickly. If I could get some of their Account Executives to chat I could tell them all about our great customer stories. They&#8217;ll wave us right in, eager to collaborate. <em>Record scratch.</em> Not so fast.</p><p>The first thing to do was to become a partner. Easy enough. At this point, I felt like the gnomes from a South Park episode,</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wIpJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wIpJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 424w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 848w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wIpJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png" width="640" height="439" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:439,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:63826,&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://writeaheadblog.substack.com/i/167724082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.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_!wIpJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 424w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 848w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.png 1272w, https://substackcdn.com/image/fetch/$s_!wIpJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F638c1b91-a2b4-4e90-ba96-22cc73754d0a_640x439.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">Obviously not collecting underpants (just to be clear)</figcaption></figure></div><p>I had to start a campaign. I had to reach out. So I took to my oft-ignored LinkedIn account and began the search for partner Account Executives, Directors, and VPs. I was on the hunt for people who would resonate with my team&#8217;s stories. Some semblance of a strategy began to take shape.</p><p>I built outreach lists. I tracked the who and when of connections. I worked hard on the narrative to tell. How much was too much? What does rapport look like? What kind of stories land? How much does &#8220;What&#8217;s In It For Me&#8221; play a part? My process was far from perfect. But I was moving from <a href="https://en.wikipedia.org/wiki/Four_stages_of_competence">unconscious incompetence to conscious incompetence</a>&#8212;the fog was beginning to lift.</p><p>Filling in that &#8220;phase 2&#8221; question mark belies a lot of work. A lot of stress. A lot of stretch. Software had been my comfort place for well over a decade. Leaving it, I discovered I had traded consistent determinism for human dependencies. Test suites gave me instant feedback. An outreach email? Not so much. Was I too wordy? Was I uninteresting? Was the recipient too busy? There is no pass/fail for those.</p><p>It&#8217;s still a work in progress. It always will be. I still straddle engineering, too. What&#8217;s more, that&#8217;s been an advantage in navigating customer discussions.</p><p>Would I do it again? Yes.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[No One's Opening Your Dev Wiki]]></title><description><![CDATA[Document for lazy people. Like me. And this cat.]]></description><link>https://writeaheadblog.com/p/no-ones-opening-your-dev-wiki</link><guid isPermaLink="false">https://writeaheadblog.com/p/no-ones-opening-your-dev-wiki</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Thu, 17 Jul 2025 14:37:25 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/aea08d08-d32a-4552-abfc-8f258498aa0c_1328x1326.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I like READMEs in <em>almost</em> every directory of a project. In my mind, they&#8217;re more effective than a project wiki. Let me tell you why.</p><p>One thing I&#8217;ve learned over my career: people are lazy. And that&#8217;s okay. We all are. At different times. Under different circumstances. It&#8217;s all too easy to accept the path of least resistance. That&#8217;s not a moral failing. Instead of fighting it, we should accommodate it.</p><p>In software, think about how we design for users. Like a lazy footpath clipping a turfed corner, we expect users to take the shortest path. So we use progressive profiling to break up long sign-up flows. We offer magic links to bypass forgotten-password hell (adding a new circle to hell in the process). We tune defaults for an immediate, usable experience. When we get it right, we make the right thing easy and the wrong thing hard. Users barely notice. Perfect.</p><p>We like to think software engineers are different. We&#8217;re smart. We&#8217;ll read the docs (what are those?), follow the right process, keep everything tidy. No. We&#8217;re not. Get out of here. Worn footpath? Please. More like peregrinated goat trails. There&#8217;s a quote getting at this idea, supposedly from Bill Gates (it&#8217;s not):</p><blockquote><h3>I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.</h3></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>People are lazy. Find the easy way. Here&#8217;s an imagined project structure:</p><pre><code>project-root/
&#9500;&#9472;&#9472; README.md
&#9500;&#9472;&#9472; api/
&#9474;   &#9492;&#9472;&#9472; README.md
&#9500;&#9472;&#9472; adapters/
&#9474;   &#9492;&#9472;&#9472; README.md
&#9500;&#9472;&#9472; pipeline/
&#9474;   &#9492;&#9472;&#9472; README.md
&#9492;&#9472;&#9472; stores/
    &#9492;&#9472;&#9472; README.md</code></pre><p>You know what&#8217;s nice about this? When I&#8217;m curious about <code>/api</code>, the explanation is right there, staring me in the face. I don&#8217;t need to leave my IDE to spelunk a wiki. The structure is obvious, even if a little repetitive. And once the pattern clicks, it becomes second nature to incorporate into your workflow. If someone forgets to update a README in a PR, it&#8217;s easy to spot. Easy to nudge. &#8220;Hey, this change should be reflected in the README.&#8221;</p><p>That&#8217;s lazy.</p><p>That&#8217;s perfect.</p>]]></content:encoded></item><item><title><![CDATA[Hiring for More Than Skill]]></title><description><![CDATA[Establish a throughline with emotionally intelligent questions]]></description><link>https://writeaheadblog.com/p/hiring-for-more-than-skill</link><guid isPermaLink="false">https://writeaheadblog.com/p/hiring-for-more-than-skill</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sun, 06 Jul 2025 01:16:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f4b1a539-8b2d-4945-a451-dda451fadc44_4032x2268.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most technical hiring processes focus on ability. But software engineers rarely fail because they can't code; they fail because they don&#8217;t ask, don&#8217;t adapt, and don&#8217;t connect. It&#8217;s why Emotional Intelligence (EQ) matters so much to me when hiring engineers. It helps you see beyond the present moment, to how they&#8217;ve developed, adapted, and where they may be going&#8212;powerful hiring signals.</p><p>It&#8217;s important to be clear: EQ isn&#8217;t about being nice. And I&#8217;m not trying to dig into a candidate&#8217;s personal story. I&#8217;m trying to understand how they handle ambiguity, conflict, feedback, and failure. Research links traits like self-awareness, regulation, and empathy to <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC10543214/">real-world performance</a> and <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC6926721/">long-term success</a>. And when we hire, isn&#8217;t that what we actually care about? I can teach software design. I can&#8217;t teach emotional regulation or self-awareness. Not at work anyway. Those traits aren&#8217;t abstract. They show up in how someone talks about past projects, setbacks, or team dynamics. But you won&#8217;t find them on a r&#233;sum&#233;. You have to ask. You have to listen. You have to engage.</p><p>This is where the Big Five Personality Traits shine. It&#8217;s my preferred model because its results hold across cultures and contexts. Used well, the five traits (OCEAN) shape both your questions and your interpretation of the answers. You might ask about tradeoffs they&#8217;ve made (Openness), how they manage deadlines (Conscientiousness), how they prefer to collaborate (Extraversion), how they handle disagreement (Agreeableness), and what stress does to them (Neuroticism). But you can&#8217;t just ask. You have to care. You have to dig in. You have to grab ahold of the thread of their story, find the shape of their arc, not just look for facts.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p><p>Often, interviews cover surface-level questions. They miss the story. I don&#8217;t want that. I want to understand where someone&#8217;s come from, where they&#8217;re going&#8212;as best I can given the time constraints. Designing questions that reveal aspects of OCEAN helps me do this. To guide that, I like to ask myself, &#8220;what will help uncover this person&#8217;s arc?&#8221; I don&#8217;t want to get to know them as they are right this second, I want their story. </p><p>These are example notes I use to find someone&#8217;s thread; they help me see beyond the r&#233;sum&#233; and start to trace their throughline:</p><div><hr></div><p><strong>Q: When you get stuck on a problem, what&#8217;s your approach for getting unstuck?</strong></p><p><strong>Traits</strong>: O/C/E [<em>these map directly to OCEAN, aspects I&#8217;m looking to uncover</em>]</p><p><strong>Listen for</strong>:</p><ul><li><p>Grounding in real behaviour</p></li><li><p>A non-idealized self-concept</p></li></ul><div><hr></div><p><strong>Q: What skill(s) feel just out of reach for you right now?</strong></p><p><strong>Traits</strong>: O/C/E</p><p><strong>Listen for</strong>:</p><ul><li><p>How they frame growth. Do they emphasize team benefit (&#8220;I want to help others by learning X&#8221;) or personal mastery (&#8220;I want to be better at Y&#8221;)? Either are valid, but consider the different motivations this reveals</p></li><li><p>How is the answer rooted? Does it reflect self-awareness, or is it wrapped in vague ambition?</p></li></ul><p><strong>Potential follow-up</strong>: Tell me about a skill you had to stretch for. Why was it important? How&#8217;d you develop it?</p><div><hr></div><p><strong>Q: How do you think people perceive you when you're hashing out ideas with them?</strong></p><p><strong>Traits</strong>: A/E/N</p><p><strong>Listen for</strong>:</p><ul><li><p>Some meta-cognition/social calibration</p></li><li><p>Whether they&#8217;re aware of how they come across? Do they adapt their style, or are they fixed in how they engage?</p></li><li><p>Signs of either self-awareness or blind spots</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Cultivating Judgment in an Agent-First World]]></title><description><![CDATA[Helping Junior Devs Grow in a World of Instant Answers]]></description><link>https://writeaheadblog.com/p/cultivating-judgment-in-an-agent</link><guid isPermaLink="false">https://writeaheadblog.com/p/cultivating-judgment-in-an-agent</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Fri, 30 May 2025 13:52:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/70ae4aca-94c8-4036-bde9-d070563e5608_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Agents are beginning to reshape how we build software. We haven&#8217;t broken cleanly into that new paradigm yet, but it&#8217;s coming. The complexity juniors used to grow through&#8212;trade-off discussions, failed first approaches, awkward in-progress code (which I still write)&#8212;risks being hidden behind a polished AI-generated answer. If all they see is the final output, I worry they&#8217;ll miss the substrate where judgment used to form.</p><p>Judgment isn&#8217;t just about spotting bugs or bad smells. It&#8217;s learning to weigh one option against another, to see why one solution fits better than the rest, and why certain shortcuts backfire (sometimes spectacularly!). That tends to happen in the messy middle. The part where you spin your wheels before asking for help. That hasn&#8217;t evaporated overnight. It&#8217;s not gone yet. But it is something we should watch for. It&#8217;s a practice ground at risk of being lost. And we need to be sure something equally as useful fills its space.</p><p>We have to consciously bring juniors along for this new ride. A ride, in a way, that we&#8217;re juniors on! So let&#8217;s share our thinking, our tradeoffs, our uncertainty. In this new world where answers are instant, experience becomes harder to acquire. But it is not impossible. We just have to be deliberate.</p><p>Let&#8217;s be deliberate. Let&#8217;s ensure everyone can come along with us.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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://writeaheadblog.com/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Illuminating Patterns]]></title><description><![CDATA[Discovering a New Flow with Software Agents]]></description><link>https://writeaheadblog.com/p/illuminating-patterns</link><guid isPermaLink="false">https://writeaheadblog.com/p/illuminating-patterns</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Tue, 13 May 2025 17:58:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8d50ea02-51ad-45a4-b26b-81c325c1eb06_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I had just wrapped up work for the day. Light was still filtering in through a high, narrow window above my desk. I fidgeted in my seat, knowing I wasn&#8217;t done for the day. I had an idea. I downloaded and opened <strong><a href="https://windsurf.com/">Windsurf</a></strong>. Before this moment, I had bounced off of agents for anything beyond basic programming. Notably, I found one agent particularly good with regex (i.e. my perennial nemesis). Beyond this, however, I found agents more effort than they were worth. I was about to have that view of agents completely upturned.</p><p>I wanted to build a web scraper. This has been solved so many times, but I&#8217;m the type that enjoys projects and writing code in my spare time. So there I sat: Windsurf open, an empty project directory in front of me, an empty chat. Pure possibility.</p><p>Prior to this, I&#8217;d have begun in a single script file&#8212;the kind of personal project that is the antithesis of best practices. The file would have grown and grown as I tested and tweaked. It wouldn&#8217;t have mattered. It would be all mine. It didn&#8217;t need to pass CI. It didn&#8217;t need to be grokked by anyone else. It could be a glorious, tangled mess.</p><p>As I stared at this empty chat box, though, I had one thought:</p><blockquote><p>Whatever is built here, I want full context.</p></blockquote><p>This one thought, context, framed my interactions with Windsurf as I worked on this project. As I began to think about what I wanted, I decided I <em>didn&#8217;t</em> want a single script file. I wanted something more mature. And given my experience, I decided to carefully frame what I wanted to Windsurf. That first message was two paragraphs long. I didn&#8217;t save it. But it went something like this:</p><blockquote><p>Okay, I want to build a web scraper in python. It&#8217;s going to scrape data off of M website. I want the entry point of the script to be <strong>app.py</strong>. I want that to load all my dependencies. I want a directory structure like: X, Y, and Z. My authentication model will live in X, my specific scrapers in Y, etc. I want to use playwright for browser interactions. For any class files you create, I only want them stubbed out. I do not want any business logic to be included at all.</p></blockquote><p>The result was the first revelatory moment. In minutes I was hours into my journey. More than that, this new project followed more sustainable practices than a single tangled file. I had crossed a threshold that felt like having discovered programming all over again. It was immediately energizing.</p><p>But I wasn&#8217;t done. I had only a skeleton of an idea. Again, I thought to myself, </p><blockquote><p>As I keep building, I want full context.</p></blockquote><p>My earliest concern was to avoid something I had seen others do: ask an agent to solve a problem and receive hundreds, if not thousands, of new lines of code in return. Programming this way, it seemed to me, was a surefire way to exist in eternal Peer Review mode. Not exciting.</p><p>Instead, I gave the agent a simple, tightly bound directive:</p><blockquote><p>Great, we have a project. Now I want to start simple. When the app first boots, lets open M website in the <strong>main.py</strong> file. That&#8217;s all I want you to do.</p></blockquote><p>That&#8217;s all I asked. That&#8217;s all it did. No bloat. No surprises. No mental overhead. It was exhilarating. By keeping my questions tightly bounded I could swiftly move through the work while maintaining context.</p><p>As I sat there, with the light slowly fading through my window, I got it. It clicked. Agents aren&#8217;t for blindly writing code and hoping for the best. They&#8217;re collaborators. Think of it like onboarding a junior developer. You don&#8217;t dump the whole codebase on them and say &#8220;go.&#8221; You hand them a small, clearly defined task. You explain the context, the purpose, and the constraints. Then you check in and adjust. It&#8217;s the same here.</p><p>That&#8217;s powerful. A few hours of tinkering has convinced me we&#8217;re in the middle of a seismic shift in how software gets written. Like the early days of object-oriented programming, we&#8217;re starting to see new patterns emerge for working with agents.</p><p>I&#8217;ve already stumbled onto one: when you&#8217;re starting a project, let the agent handle broad, boilerplate setup above and beyond framework features. Once you&#8217;re into feature development, tightly bound your requests to heighten your own context. These two principles alone can dramatically improve the way you build alongside an agent.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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 The Write-Ahead Blog! Subscribe for free to receive my latest posts.</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>]]></content:encoded></item><item><title><![CDATA[How to Train Your AI (agent)]]></title><description><![CDATA[How Rules Files Turn AI Agents Into Effective Programming Partners]]></description><link>https://writeaheadblog.com/p/how-to-train-your-ai-agent</link><guid isPermaLink="false">https://writeaheadblog.com/p/how-to-train-your-ai-agent</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Wed, 30 Apr 2025 23:00:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2fae3adf-a644-4307-9571-72bcd142f663_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Programming is undergoing a paradigm shift. AI-paired development isn&#8217;t a novelty. It&#8217;s becoming the new normal. And that shift demands new workflows. One of the most essential is the <strong>rules file</strong>: a plain-text document that tells your AI how to behave inside your environment. These aren&#8217;t nice-to-haves. In AI-native development environment (IDEs) like <a href="https://www.cursor.com/">Cursor</a> or <a href="https://windsurf.com/">Windsurf</a>, they&#8217;re required infrastructure. So, what exactly is a rules file?</p><p>A rules file instructs an AI agent how to behave. For example, when you start a new chat with an agent like ChatGPT, it knows nothing about your workflow or the mode you're operating in. Rules files supply that missing context&#8212;guiding behavior with your experience and preferences to shape the output. Without these files, the output suffers. In IDEs, rules are typically markdown files (e.g. &#8220;general_rules.md&#8221;) sent with every request to shape the response.</p><p>At a high level, these files capture your preferences around things such as style conventions, architectural choices, and repeatable patterns. What follows are some basic examples to get you thinking.</p><h2>The Personality</h2><p>This is at the core of your rules files. It dictates how your AI agent should present itself and behave. A trivial example looks like: </p><pre><code><code>You are a senior software engineer. You approach problem solving from the perspective of deconstruction&#8212;you break tasks down into manageable, atomic pieces. You look for simple solutions before conceding to complexity. As you present your suggested solutions, you outline your reasoning and thinking. You engage critically with problems and ensure your solutions are well-reasoned.</code></code></pre><p>Instructions like this can affect how the AI reasons, whether it explains steps, or how assertive it is in making choices. For example, a personality set to &#8220;senior engineer who prefers clarity over cleverness&#8221; will often avoid terse one-liners in favor of clearer constructs. Depending on your experience, this can be tuned for more effective collaboration.</p><h2>The Conformist</h2><p>At the heart of every team, and developer, are conventions and styles that have developed over years. This file isn&#8217;t a preferences dump. It&#8217;s where hard-won conventions are captured. And it's the file that might see the most amount of churn. It should be actively maintained to ensure it's capturing the team's best practices. Without a file like this, you risk re-litigating the same choices with every code suggestion.</p><p>Do you prefer specific patterns in certain circumstances? Outline them here. Do you have patterns, say in testing, that are non-negotiable? Outline them here.</p><p>Here's an example: </p><pre><code><code>* When starting a new project, always include the Ruby gem dotenv
* Use string interpolation instead of concatenation
* When creating a class, always stub out a spec file
* Prefer single quotes for strings unless interpolation is needed
* Unless otherwise requested, use the Ruby gem Faraday for HTTP requests
* Use factories (not fixtures) for test data setup
* Document all environment variables in the README or .env.example</code></code></pre><h2>The Architect</h2><p>While the Conformist deals with code style and routine conventions, the Architect governs higher-level design, system behavior, preferences, and architectural principles. This file is especially useful when you have established opinions about how software should be structured, preventing drift and maintaining consistency. For example: </p><pre><code><code>* Use pub/sub for inter-service communication unless strong consistency is required
* Default to simple structs or plain classes; avoid introducing complex base classes or inheritance without need
* For persistent data models, prefer composition over deep nesting
* When creating APIs, enforce idempotency for all POST endpoints unless explicitly marked as one-time actions
* For background jobs, include an exponential retry policy and failure alerting scaffold by default
* When adding a new feature, generate a feature flag scaffold to control rollout</code></code></pre><p>Not every decision is black and white, but these rules can nudge the AI toward your defaults. They're especially useful when consistency matters more than innovation.</p><h2>Parting Tips</h2><p>Some advice for putting rules files to work:</p><ul><li><p>Keep your rules files modular, like outlined above, for easier maintenance</p></li><li><p>Treat these files as living documents, update them anytime the AI falls short of your standards</p></li><li><p>Consider versioning your rules files in a personal or team repo</p><ul><li><p>They can easily be <a href="https://en.wikipedia.org/wiki/Symbolic_link">symlinked</a> into new project directories</p></li></ul></li><li><p>Create purpose-built files (e.g. &#8220;reviewer.md&#8221; or &#8220;debugger.md&#8221;) for specialized workflows</p></li><li><p>Rules files aren&#8217;t restricted to developers, they can be useful for project managers or other professionals (e.g. ChatGPT calls them &#8220;traits&#8221;)</p></li><li><p>Add code examples, with instructions, to be explicit in your preferences</p></li></ul><div><hr></div><p>Rules files are already essential. They aren&#8217;t documentation, they aren&#8217;t optional, they&#8217;re working memory distilled from decades of collective experience driving the output of the agents your teams use. They&#8217;re how things are done.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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 The Write-Ahead Blog! Subscribe for free to receive my latest posts.</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>]]></content:encoded></item><item><title><![CDATA[Practical Agent Model Switching]]></title><description><![CDATA[Quick, effective heuristics for picking the right AI model for the job]]></description><link>https://writeaheadblog.com/p/practical-agent-model-switching</link><guid isPermaLink="false">https://writeaheadblog.com/p/practical-agent-model-switching</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sat, 26 Apr 2025 01:04:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/aeca3e17-e06b-4374-9e62-ba1db8ab7ed9_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://windsurf.com/">Windsurf AI</a> has quickly solidified its role in my development workflow. With this change comes a necessary shift in thinking about the work. New rhythms, new patterns to feel out. And unexpected new skills to refine: like knowing when to <a href="https://docs.windsurf.com/windsurf/models">switch models</a> for a given task. I classify these models into three types. They&#8217;re far from official, but they&#8217;ve held up well for me: <em>performance</em>, <em>thinking</em>, and <em>basic</em>.</p><h3>Performance</h3><p>These are often the newest, most expensive models to use. They&#8217;re built for complexity, for context-heavy tasks that need precision and depth. If I&#8217;ve got something big and tangled to accomplish, and I want it done right, I bring out the heavy artillery. It lets me pair my experience with something that doesn&#8217;t blink and doesn&#8217;t get tired.</p><h3>Thinking</h3><p>These versions I love. These models think out loud. You give them a question, and they don&#8217;t just spit out an answer&#8212;they lay the whole thought process on the table. Brilliant. When you&#8217;re venturing into unfamiliar territory you couldn&#8217;t ask for more. Like, say, implementing Postgres&#8217; <code>tsvector</code> in Elixir for the first time. You&#8217;re not just solving a problem; you&#8217;re learning. And better still, you get to catch it when it goes off the rails. You get to push back. You get smarter.</p><h3>Basic</h3><p>These models are my go-to grunts. Reliable, cheap, do-as-I-say. I use them when I know exactly what needs to be done&#8212;I just don&#8217;t feel like doing it. The work is simple, the outcome clear, and I don&#8217;t need the thing getting creative. One caveat: I keep them boxed into a single file. I&#8217;ve seen too much chaos when a basic model tries to go beyond a single file. They don&#8217;t reason well across boundaries. But if it&#8217;s a focused task you know your way around, this is your cost-effective, zero-fuss answer.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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 The Write-Ahead Blog! Subscribe for free to receive new posts as they go out.</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>]]></content:encoded></item><item><title><![CDATA[Automatic Programming, Again]]></title><description><![CDATA[Embracing the next phase of programming]]></description><link>https://writeaheadblog.com/p/automatic-programming-again</link><guid isPermaLink="false">https://writeaheadblog.com/p/automatic-programming-again</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sun, 06 Apr 2025 17:17:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ab9ce0dd-0686-455f-81c3-fd60723e56d7_474x316.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Time is a flat circle.</p><p>I read <a href="https://app.thestorygraph.com/books/8086b5d4-f71e-4f23-ba09-2682a9d6a890">Grace Hopper and The Invention of the Information Age</a> a few years ago. In the 1950s she introduced the first compiler&#8212;a program to translate human-friendly, English-like code into machine code. It was a paradigm shift, one that provoked immediate negative reaction:</p><blockquote><p>Reflecting on the negative reactions of some of her fellow programmers, Hopper expressed the belief that arguments focusing on &#8220;efficiency&#8221; and &#8220;creativity&#8221; covered far baser motivations: &#8220;Well, you see, someone learns a skill and works hard to learn that skill, and then if you come along and say, &#8216;you don&#8217;t need that, here&#8217;s something else that&#8217;s better,&#8217; they are going to be quite indignant.&#8221; In fact, Hopper felt that by the mid 1950s many programmers viewed themselves as &#8220;high priests,&#8221; for only they could communicate with such sophisticated machines. They served as the intermediaries between user and computer, and automatic programming jeopardized their exclusive position.</p></blockquote><p>These days, no one bats an eye at using compiled languages. We&#8217;ve been using Dr. Hopper&#8217;s invention to more efficiently write code for decades. Much like the days before her invention of the compiler, writing code today is deep knowledge work. Still, software engineers act as &#8220;intermediaries between user and computer.&#8221;</p><p>Time is a flat circle.</p><p>We find ourselves, again, at a clear paradigm shift. By the late 1950s, I bet you could have said the same about compilers as we now say about AI. And much in the same way as those PhD mathematicians writing machine code ultimately had to think more abstractly, we&#8217;ll have to shift our thinking.  We&#8217;ll have to step back from hand-typing every single line of code (minus handy command-line generators) to engaging with AI agents at a more abstracted level.</p><p>Time is a flat circle.</p><p>Why, now, should <em>we</em> keep building the same old directory structures, tweak migrations, or fiddle with broad-strokes of data models? Let the agents do that, so our deep knowledge work can focus on the trickiest of the tricky&#8212;let&#8217;s say the 5% of a project where reasoning and creativity matter most.</p><p>The LLM is the new compiler.</p><p>The agent, the new high-level language.</p><p>And we&#8217;re about to see a new degree of productivity echoing the gains brought on by Dr. Hopper.</p><p>Time is a flat circle.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://writeaheadblog.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 The Write-Ahead Blog! Subscribe for free to receive new posts.</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>]]></content:encoded></item><item><title><![CDATA[Conversational Signposts]]></title><description><![CDATA[How Na&#239;ve Realism & Ken Foster Improved Connection]]></description><link>https://writeaheadblog.com/p/conversational-signposts</link><guid isPermaLink="false">https://writeaheadblog.com/p/conversational-signposts</guid><pubDate>Thu, 28 Nov 2024 18:39:37 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c2aebae9-be6c-4d91-bb6e-1835033e31b4_5918x3945.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What if we could develop a perspective for asking deeper, more meaningful questions? How might it help us uncover insights we&#8217;d otherwise miss? Imagine shining a spotlight into the hidden corners of a friend&#8217;s comment or sparking deeper connections in everyday conversations&#8212;whether with a loved one, during a job interview, or even in a checkout queue. By combining the concepts of <em>na&#239;ve realism</em> and <em>ken</em> with purposeful listening we can transform the way we understand and relate to others.</p><p>To begin asking better questions, it helps to understand the concepts that can help get us there&#8212;like <em>ken</em>. And no, not the other half of a famous duo! In its simplest form, <em>ken</em> is defined as one&#8217;s &#8220;range of perception, understanding, or knowledge.&#8221; <em>Ken</em> has deep roots, tracing back to <em>kenning</em>, a term with Scottish nautical ties that refers to the limit of our vision at sea&#8212;about 20 miles. While nautical history isn&#8217;t directly relevant here, connecting dots like this can help cement understanding.</p><blockquote><p><em>Ken</em>: one&#8217;s range of perception, understanding, or knowledge</p></blockquote><p>To complete our question-asking duo, let&#8217;s bring <em>na&#239;ve realism</em> into the mix. Both a philosophical and psychological concept, it&#8217;s the counterpart to <em>ken</em> that, when paired with it, can guide us toward deeper interpersonal connection. For our purposes, we&#8217;ll focus on its psychological meaning: the <strong>belief</strong> that we see the world objectively, without biases or distortions. <em>Na&#239;ve realism</em> leads us to assume our perceptions are fully accurate and that those who disagree must be uninformed, irrational, or biased. Acknowledging this bias fosters empathy, encouraging us to see the world through the perspectives of others.</p><blockquote><p><em>Na&#239;ve realism:</em> the tendency to believe one's own senses accurately reflect reality, ignoring the influence of bias and other factors</p></blockquote><p>Now, let&#8217;s combine these two ideas. A broad, humble understanding of <em>ken</em> reminds us that our knowledge and perception are inherently limited, much like the horizon seen from a ship. At the same time, <em>na&#239;ve realism</em> challenges us to accept that our view of reality is subjective and shaped by personal experiences and biases. Together, these concepts highlight that as we navigate our lives, we experience the world not as it truly is but within the boundaries of our <em>ken</em>. Recognizing this opens the door to curiosity. It invites us to ask deeper, more meaningful questions rather than simply asking more of them. This not only stretches our understanding and expands our <em>ken</em>, but it also fosters deeper connections with those around us.</p><p>Where does this lead us? Appreciating <em>na&#239;ve realism</em> reminds us that our perceptions may not always reflect reality. <em>Ken</em>, like a spotlight with ourselves at the center, illuminates the limits of our knowledge, a landscape only partially understood. By recognizing the habitual incompleteness of our own understanding, we can better appreciate the same in others. This perspective encourages us to ask questions&#8212;not just to fill our own knowledge gaps or challenge biases, but to inspire curiosity and reflection in those we engage with. In doing so, we begin to connect with others more deeply.</p><p>Over time, questions like &#8220;how are you doing?&#8221; will begin to feel colorless and superficial, offering little room for meaningful connection; they&#8217;re routine and automatic, often answered without much thought. With practice, though, we might instead ask, &#8220;what&#8217;s surprised you today?&#8221; This type of question invites reflection and opens the door to follow-up: What&#8217;s changed for them? What was unexpected or unanticipated? How did it make them <strong>feel</strong>? Did it interrupt their day or maybe even make it better?</p><p>And, of course, what follows is the response. This is where purposeful listening comes into play, allowing us to be more present in the conversation while enabling deeper questions. Much like the horizon at sea marks the limits of our ken, &#8220;words with weight&#8221; act as signposts, offering glimpses into unexplored conversational terrain. These emotionally charged words guide us along a branching trail, transforming what might have been a brief exchange into a journey through a more vivid landscape&#8212;rich with unexpected turns, shadowed valleys, and hidden connections waiting to be uncovered.</p><p>We now have a simple framework guiding us toward asking deeper, more meaningful questions, one that acknowledges the subjectivity of our experience and the limits of our knowledge. This empowers us to create richer, more connected conversations, whether at the water cooler, in a line, or even while getting to know a prospective hire.</p><p>Together, <em>ken</em> and <em>na&#239;ve realism</em> create a foundation for conversations that lead to deeper connection and understanding, providing a pathway to richer, more meaningful relationships. And, now, with all these new signposts to explore, who knows where they&#8217;ll lead?</p>]]></content:encoded></item><item><title><![CDATA[Balancing the Heat: System Dynamics and Backpressure in Software Queues]]></title><description><![CDATA[With a sprinkling of Elixir for good measure]]></description><link>https://writeaheadblog.com/p/balancing-the-heat-system-dynamics</link><guid isPermaLink="false">https://writeaheadblog.com/p/balancing-the-heat-system-dynamics</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Tue, 03 Sep 2024 01:07:42 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/da191210-0a06-4e82-92b6-12313b78ce83_1125x750.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the 1950s, MIT professor Jay Forrester introduced <strong>System Dynamics</strong>, a framework for understanding how complex systems&#8212;whether in industry, biology, or even software&#8212;function through the interaction of individual parts and feedback loops. He arrived at this concept, in part, through his work on servomechanisms, which use feedback to regulate systems much like a thermostat controls temperature. This same thinking can be applied to modern software queues, for example, with the help of <a href="https://hexdocs.pm/gen_stage/GenStage.html">Elixir&#8217;s GenStage</a>, where balancing workloads and managing flow through backpressure are critical to keeping systems efficient.</p><p>As we interrelate System Dynamics with queuing, we&#8217;ll cover:</p><ul><li><p>Stocks, flows, &amp; rates</p></li><li><p>Delays &amp; nonlinearity</p></li><li><p>Feedback loops: reinforcing &amp; balancing</p></li><li><p>Backpressure</p></li></ul><p>Now, let&#8217;s set the <s>scene</s> table!</p><h4><strong>The Kitchen as a System</strong></h4><p>Imagine a restaurant kitchen. Orders come in from the dining room, and each chef or station (similar to <a href="https://hexdocs.pm/gen_stage/GenStage.html#module-stage-types">stages in GenStage</a>) is responsible for a part of the cooking process. The key to running an efficient kitchen, just like a software queuing system, is managing how orders flow through it and ensuring accumulated orders don&#8217;t bog it down.</p><p>In System Dynamics, we think about such systems in terms of <strong>stocks</strong>, <strong>flows, rates</strong>, and <strong>feedback loops</strong>.</p><h4><strong>From Order to Plate: Stocks, Flows, and Rates</strong></h4><p>In our kitchen, the <strong>stock</strong> represents all the orders waiting to be cooked. These are equivalent to tasks or events sitting in a queue, waiting to be processed. The <strong>flow</strong> represents orders moving from one cooking station to another. And the <strong>rate</strong> represents how quickly these orders transition from station to station.</p><p>From a System Dynamics perspective, when a queue is under heavy load, delays build up when the inflow (<a href="https://hexdocs.pm/gen_stage/GenStage.html#module-demand">demand</a> for new orders) is higher than the outflow (completed dishes) and so the stock (queue) grows. Managing this inflow is critical to avoiding show-stopping delays.</p><h4><strong>Under Pressure: Delays and Nonlinearity</strong></h4><p>In both kitchens and software systems, <strong>delays</strong> happen when tasks take longer than expected to process. For example, if too many orders arrive too quickly, the time it takes for each dish to reach the table increases, leading to unhappy diners. In other words, as orders pile up, stations in the kitchen become bottlenecks, creating a feedback loop which slows the entire workflow. This is an example of <strong>nonlinearity</strong>: a small increase in work can lead to a disproportionate slowdown, unless there's a way to manage the rate of flow.</p><p>Let&#8217;s explore nonlinearity feedback loops during the lunch rush!</p><h4><strong>Handling the Rush: Feedback Loops and Backpressure</strong></h4><p>Left alone, nonlinearity introduced by delays contributes to a <strong>reinforcing loop</strong> which can quickly overwhelm the kitchen. As more orders pile up, delays increase, leading to slower service. This is the dreaded feedback loop that every busy kitchen&#8212;and every overloaded software system&#8212;seeks to avoid.</p><p>To manage this, <strong>backpressure</strong> mechanisms can be put in place to relieve the system of having to process a potentially overwhelming number of orders. For example, in the kitchen, this could be represented as waiters slowing down their rate of order taking, a shorter, quicker-to-prepare menu may be provided to new diners, or other employees could even help out in the kitchen! All of these options help relieve demand on the kitchen, our stand-in for a queue.</p><p>This <strong>balancing loop</strong>, one that takes advantage of backpressure strategies, helps keep the system stable, avoiding the long delays that come from overwhelming the queue. Elixir&#8217;s GenStage, again, comes in handy here with its <a href="https://hexdocs.pm/gen_stage/GenStage.html#module-example">baked-in implementation</a> for enabling demand to be communicated, much like a chef telling the waiters to reduce their order taking.</p><h4><strong>Queues Through a System Dynamics Lens </strong></h4><p>A queue is an essential tool for handling workflows at scale, providing enormous benefits. Paired with efficient tools like Elixir, it can accelerate outcomes in a well-built system. Even more, when combined with knowledge from other disciplines, like System Dynamics, you can gain a deeper understanding of data flow, feedback loops, and backpressure mechanisms to maintain efficient systems.</p><p>And you never know where System Dynamics thinking may come in handy&#8212;from kitchens, to cities, to software, to manufacturing!</p>]]></content:encoded></item><item><title><![CDATA[Interdisciplinary Latticework]]></title><description><![CDATA[Increasing empathy through adjacent understanding]]></description><link>https://writeaheadblog.com/p/interdisciplinary-latticework</link><guid isPermaLink="false">https://writeaheadblog.com/p/interdisciplinary-latticework</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Wed, 24 Apr 2024 13:55:29 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/012bb0e5-3c31-4e88-988f-702c297d7e0b_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>What is elementary, worldly wisdom? Well, the first rule is that you can&#8217;t really know anything if you just remember isolated facts and try and bang &#8216;em back. If the facts don&#8217;t hang together on a latticework of theory, you don&#8217;t have them in a usable form&#8230; You&#8217;ve got to have models in your head. And you&#8217;ve got to array your experience&#8212;both vicarious and direct&#8212;on this latticework of models.</p><p>~ Charlie Munger</p></blockquote><p>Years ago I came across the above quote and it&#8217;s stuck with me ever since; pulling together understanding from multiple disciplines can create the opportunity for deeper revelations. In a way it&#8217;s like the <a href="https://writeaheadblog.substack.com/i/141677470/the-adjacent-possible">Adjacent Possible</a>.</p><p>In this vein, one example I occasionally think about is the <a href="https://blogs.cardiff.ac.uk/sarahlethbridgelean/trust-thermoclines/">Trust Thermocline</a>. The short of which is that as a company makes the misstep of continually taking advantage of its customers a sudden breaking point is reached and their userbase collapses. Completely unrelated to business is the &#8220;thermocline&#8221; which comes from a large gradient shift in temperature in the ocean as you descend into its depths.</p><p>And so you get this interlacing of business and marine science to demonstrate a particular phenomenon - models in your head that can contribute to deeper understanding versus isolated facts.</p><p>Recently I&#8217;ve noticed this latticework form as I&#8217;ve engrossed myself in the workings of the <a href="https://en.wikipedia.org/wiki/Autonomic_nervous_system">Autonomic Nervous System</a> (ANS). From <a href="https://en.wikipedia.org/wiki/Polyvagal_theory">Polyvagal Theory</a> to <a href="https://en.wikipedia.org/wiki/Internal_Family_Systems_Model">Internal Family Systems</a> to more commonly known brain structures like the prefrontal cortex and the amygdala, it&#8217;s been interesting to explore the interplay between all of these. Where I didn&#8217;t expect to see a crossover was in my interpersonal connections. And not from my own perspective but from theirs.</p><p>From personal to professional life, it&#8217;s important to me to cultivate empathy in my relationships. Connecting all of these dots, this latticework, has enabled me to recognize ANS anxiety storms in others and adjust my interactions with them to be more supportive. The result is engendering deeper empathy during difficult times.</p><p>Now I just need a cool name for it like the Trust Thermocline! &#129300;</p>]]></content:encoded></item><item><title><![CDATA[Employees Aren't Resources]]></title><description><![CDATA[Compassionate Management]]></description><link>https://writeaheadblog.com/p/employees-arent-resources</link><guid isPermaLink="false">https://writeaheadblog.com/p/employees-arent-resources</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Wed, 06 Mar 2024 20:23:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c2cccf7e-7077-407d-9813-34e47b6a960a_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I joined a software company in 2018 that opened my eyes in more ways than one. One of those ways was the deep respect this company had for its employees. This has left an indelible mark on me.</p><div class="pullquote"><p>Employees are not &#8220;resources.&#8221;</p></div><p>In the event this term came up, the owner of the company would gently stop the speaker, mid-sentence, and inform them that their coworkers were not to be referred to as &#8220;resources.&#8221;</p><p>It&#8217;s an easy thing to overlook.</p><p>The word &#8220;resources&#8221; is used so frequently it even identifies a critical department in many companies: Human Resources. I would argue &#8220;resources&#8221; has become a form of euphemistic labeling*. It lets us distance ourselves from the people we work with so that the bottom line of business becomes easier to execute.</p><p>Nowadays &#8220;resources&#8221; is like nails on a chalkboard for me. I think we should all take a moment to consider if this is the environment we want to foster at work. Or if a little more recognition of the humanity all around us, with all that entails, can lead to richer work environments. </p><h4>References</h4><ul><li><p><a href="https://engagingpeace.com/?p=35">Euphemistic Labeling</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Hype Adjacency]]></title><description><![CDATA[Exploring adjacent innovation alongside the Gartner Hype Cycle]]></description><link>https://writeaheadblog.com/p/hype-adjacency</link><guid isPermaLink="false">https://writeaheadblog.com/p/hype-adjacency</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Tue, 20 Feb 2024 22:27:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PgBJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One concept I&#8217;ve enjoyed exploring lately is the concept of the &#8220;adjacent possible.&#8221; This posits that there are a set of ideas, new innovations and possibilities, achievable from the current state of affairs. In addition to this, I&#8217;ve been reflecting on Gartner&#8217;s Hype Cycle. This cycle presents stages through which emerging technologies progress, from initial excitement and inflated expectations to eventual maturity and widespread adoption.</p><p>Now imagine a journey where every hype cycle opens up new doors of adjacent possibilities, where every peak and trough can lead to accelerated expansions in technology. In this post, I want to explore how I see these two concepts intertwine and feed additional pathways for innovation and development.</p><h3>The Adjacent Possible</h3><p>The adjacent possible refers to potential innovations and opportunities that are achievable from our current state of affairs. It was originally coined by <a href="https://www.ted.com/talks/stuart_kauffman_the_adjacent_possible_and_how_it_explains_human_innovation">Stuart Kauffman</a>. At the heart of it, it suggests that some advancements are beyond immediate reach, that there is a close-by frontier of reasonable developments that may be reached or, at least, explored with some effort. What&#8217;s more, is that the idea behind the Adjacent Possible is that innovation may occur through smaller steps that continually open new possible pathways. It advocates for the idea that progress is driven by what is achievable given our existing knowledge, resources, or technology.</p><p>I think it&#8217;s also important to note that this idea was originally presented through a lens of biology, but is applicable far more broadly.</p><h3>The Gartner Hype Cycle</h3><p>The Gartner Hype Cycle illustrates the stages of expectations for specific technologies over time. Created by the advisory firm <a href="https://www.gartner.com/en/research/methodologies/gartner-hype-cycle">Gartner</a>, it consists of a curve that charts the maturity, perceptions, and mind share of a technology from its inception in the public consciousness to its widespread adoption and integration into everyday use.</p><p>The cycle typically begins with an "Innovation Trigger," marking the emergence of a new technology or innovation often highlighted by media interest. This is then followed by a steep rise in wider consciousness know as the &#8220;Peak of Inflated Expectations,&#8221; where excitement and hype produce countless positive as well as negative stories. Subsequently, the curve descends into the "Trough of Disillusionment," as reality sets in, and the technology fails to meet the inflated expectations. Through gradual learning and practical applications, the technology eventually proceeds through the "Slope of Enlightenment" and, finally, the "Plateau of Productivity," where its true value and potential become more widely understood, realized, and embraced.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PgBJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PgBJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 424w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 848w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 1272w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PgBJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png" width="1456" height="873" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:873,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:524337,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PgBJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 424w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 848w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.png 1272w, https://substackcdn.com/image/fetch/$s_!PgBJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa624d387-c3e9-42fd-80ae-e532f5f0a9f4_5652x3388.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><h3>Enlightening Adjacency</h3><p>The convergence of these two, in my opinion, is most potent during the &#8220;Slope of Enlightenment&#8221; phase of the hype cycle. It&#8217;s at this point that the technology going through the hype cycle has begun to &#8220;settle in&#8221; to everyday life. The reality of exploring the adjacent possible with this new technology is most concrete during this phase. That&#8217;s not to say exploring adjacency isn&#8217;t present elsewhere.</p><p>That said, the "Innovation Trigger" and "Peak of Inflated Expectations" phases also present opportunities to explore the adjacent possible as new ideas and possibilities emerge, pushing the boundaries of what is currently achievable. Innovators and early adopters will be actively exploring the adjacent possible, experimenting with different approaches and applications of the technology to capitalize on its perceived potential. At this early stage, though, that potential may be murky and rife with failure, especially from the perspective of a wider audience.</p><p>I&#8217;d argue it's during the "Slope of Enlightenment" that the adjacent possible truly becomes the most pronounced and tangible. As the cycle settles in, as early adopters refuse to give up, this phase yields a deeper understanding of the technology's capabilities and limitations, leading to more practical and informed exploration of adjacent opportunities. As real-world applications emerge and successes are demonstrated, the adjacent possible expands, offering new pathways for innovation and development.</p><h3>Resources</h3><ul><li><p>https://www.gartner.com/en/research/methodologies/gartner-hype-cycle</p></li><li><p>https://en.wikipedia.org/wiki/Gartner_hype_cycle</p></li><li><p>https://fs.blog/gates-law</p></li><li><p>https://www.ted.com/talks/stuart_kauffman_the_adjacent_possible_and_how_it_explains_human_innovation</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Building A Competency Matrix]]></title><description><![CDATA[Empowering team members in their career growth]]></description><link>https://writeaheadblog.com/p/building-a-competency-matrix</link><guid isPermaLink="false">https://writeaheadblog.com/p/building-a-competency-matrix</guid><dc:creator><![CDATA[Michael]]></dc:creator><pubDate>Sun, 11 Feb 2024 00:05:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8n0o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A Competency Matrix informs how team members can grow from one role to another. Reviewing a matrix from left to right, a team member can understand how skills, on the Y axis, inform career growth along the X axis. Below is a slimmed down example for a software engineering matrix:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8n0o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8n0o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 424w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 848w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 1272w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8n0o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png" width="1456" height="329" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:329,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140268,&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;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8n0o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 424w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 848w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 1272w, https://substackcdn.com/image/fetch/$s_!8n0o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0866d48e-c771-49aa-a606-f00d3bf28d48_1878x424.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>The benefit of a matrix like this is that it makes clear what is required for a person in one role to grow into the next role. During reviews, the team member can can point to their accomplishments within this matrix to aid in promotion discussions.</p><h2>Getting Started</h2><p>The best place to start is with an existing engineering ladder. For example, this might look like roles similar to Associate Software Engineer, Software Engineer, Senior Software Engineer, and Principal Software Engineer.</p><p>A problem with simply having a ladder with job descriptions is that they don&#8217;t clearly lay out how an engineer can grow from one position to the next. There may even be little overlap from one position to the next. This is where the competency matrix shines. Going through the process of creating one will help tighten up a career ladder and ensure there is a clear path from one position to the next.</p><p>The first step in this process is to be confident that the existing roles are still relevant to the organization. These roles will directly inform the X axis of the matrix. In the example above these are represented as <strong>E1</strong>, <strong>E2</strong>, and <strong>E3</strong>.</p><h2>The X Axis</h2><p>The X axis has three components: Role, Impact, and Focus.</p><p>Role is an individual title that exists on your ladder. For example, this may be Associate Engineer or Principal Engineer.</p><p>Impact is a quick visual of how an engineer&#8217;s work is expected to be felt by the wider team. A Junior Engineer, for example, may only have small contributions to a project. On the other hand, a Principal Engineer&#8217;s impact is expected to be much broader and deeper.</p><p>Focus helps an engineer understand where their energies should be directed. In this case, I&#8217;ve chosen to highlight &#8220;Self&#8221;, &#8220;Mentorship&#8221;, and &#8220;Advocacy&#8221;. For example, a freshly minted Associate Engineer will be better served to focus on their own growth versus advocating for technologies or methodologies.</p><h2>The Y Axis</h2><p>The Y axis has two components to it: a Theme and a Competency.</p><p>Let&#8217;s start with Competencies since they&#8217;re more granular. These are individual skill sets that engineers can grab a hold of. For example, you might choose &#8220;Code Reviews&#8221;, &#8220;Troubleshooting&#8221;, &#8220;Writing Tests&#8221;, &#8220;Identifying Risk&#8221;, or &#8220;Technical Project Management&#8221;. These are areas team members will directly focus on in order to grow into the next position on the X axis. Later on we&#8217;ll discuss clearly defining these Competencies.</p><p>Themes are more broad than Competencies. Themes capture multiple, similar Competencies under a single heading. An example of this may be Competencies of &#8220;Writing Tests&#8221;, &#8220;Writing Code&#8221;, and &#8220;Architecture &amp; Design&#8221; being grouped under a &#8220;Development&#8221; Theme. Themes help categorize your Competencies but are, overall, less important to the matrix than the Competencies.</p><h2>Competency Scaling</h2><p>The last part of the Competency Matrix is the most important: the descriptions of the Competencies as they scale from a junior role to more senior roles. It&#8217;s important, as well, that these individual scales tie in to job descriptions to keep everything in alignment.</p><p>When writing these, be mindful that they properly scaffold the team member from one step to the next. Each description needs to be achievable from the step preceding it. A role description starting out as &#8220;An engineer observes best-practices from team members&#8221; and immediately scaling to &#8220;An engineer advocates for and disseminates best-practices&#8221; leaves an enormous gap in scaffolding how someone grows from observation to advocacy.</p><p>An example of scaffolding may be starting with this:</p><blockquote><p><strong>Associate Engineer, Security Competency</strong></p><p>Understands the importance of security.</p></blockquote><p>Which leads to the next role:</p><blockquote><p><strong>Engineer, Security Competency</strong></p><p>Utilizes growing security knowledge to ask more senior engineers for help on making decisions which may have security implications.</p></blockquote><p></p><h4>Helpful Links</h4><p>I didn&#8217;t pull all of this out of thin air. Not only did I spend a lot of time brainstorming to understand the various pieces of the matrix and what might best support my team members, but I also benefited from examples of teams that came before me:</p><ul><li><p><a href="https://paper.dropbox.com/doc/Level-and-Step-placement-guide-dfXRUlxFYuvmEQ7FTU3qc">Level &amp; Step Placement Guide</a></p></li><li><p><a href="https://dresscode.renttherunway.com/blog/ladder">Dress code engineering ladder</a></p></li><li><p><a href="https://relevant.software/blog/engineering-competency-matrix-what-it-is-and-how-to-build-one/">What A Competency Matrix is and How to Build One</a></p></li><li><p><a href="https://buffer.com/resources/engineering-career-framework/">Engineering Career Framework</a></p></li><li><p><a href="https://docs.google.com/spreadsheets/d/131XZCEb8LoXqy79WWrhCX4sBnGhCM1nAIz4feFZJsEo/edit#gid=0">CircleCI Competency Matrix</a></p></li></ul>]]></content:encoded></item></channel></rss>