<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>LeoSimons.com</title>
	<atom:link href="https://leosimons.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://leosimons.com</link>
	<description>Leo Simons&#039; homepage</description>
	<lastBuildDate>Sun, 26 Jul 2026 14:46:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>

<image>
	<url>https://leosimons.com/wp-content/uploads/2026/02/20251214-leo-portrait-cartoon-small.png?w=32</url>
	<title>LeoSimons.com</title>
	<link>https://leosimons.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">2100343</site><cloud domain='leosimons.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<atom:link rel="search" type="application/opensearchdescription+xml" href="https://leosimons.com/osd.xml" title="LeoSimons.com" />
	<atom:link rel='hub' href='https://leosimons.com/?pushpress=hub'/>
	<item>
		<title>Fact-based modelling and LinkML</title>
		<link>https://leosimons.com/2026/07/26/fact-based-modelling-and-linkml/</link>
					<comments>https://leosimons.com/2026/07/26/fact-based-modelling-and-linkml/#respond</comments>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Sun, 26 Jul 2026 11:49:38 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=950</guid>

					<description><![CDATA[This blog post was co-authored with AI (Anthropic Claude Fable). Domain-driven design works best when the people who know the domain can check the model. Most modelling notations get in the way of that. Fact-based modelling helps. Instead of starting from tables or classes, you describe the domain as short sentences that a domain expert &#8230; <a href="https://leosimons.com/2026/07/26/fact-based-modelling-and-linkml/" class="more-link">Continue reading<span class="screen-reader-text"> "Fact-based modelling and&#160;LinkML"</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>This blog post was co-authored with AI (Anthropic Claude Fable).</em></p>



<p class="wp-block-paragraph"><a href="https://en.wikipedia.org/wiki/Domain-driven_design">Domain-driven design</a> works best when the people who know the domain can check the model. Most modelling notations get in the way of that.</p>



<p class="wp-block-paragraph"><a href="https://medium.com/data-science/what-is-fact-based-modelling-106ba15649fa">Fact-based modelling</a> helps. Instead of starting from tables or classes, you describe the domain as short sentences that a domain expert can confirm or reject. This post walks through that way of working, then translates the result into <a href="https://linkml.io/">LinkML</a>, a schema language with good code generation.</p>



<h2 class="wp-block-heading">Think in facts</h2>



<p class="wp-block-paragraph">The best-known fact-based method is <a href="https://en.wikipedia.org/wiki/Object-role_modeling">Object-Role Modeling</a> (ORM). Its core idea: a domain is a set of facts, and every fact can be read out as a sentence.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Each Team has at least one lead, who is a Person.</p>
</blockquote>



<p class="wp-block-paragraph">A product manager can read that sentence. A DBA can read it. The person who runs the team can read it and tell you it&#8217;s wrong. &#8220;Teams go without a lead for months during reorgs&#8221; is cheap feedback at a whiteboard and expensive feedback after you ship a <code>NOT NULL</code> constraint.</p>



<p class="wp-block-paragraph">You find these facts by talking with domain experts, using concrete examples (&#8220;take the platform team. Who&#8217;s the lead there?&#8221;), plain language, and simple drawings. Examples do double duty: they help you discover a fact, and they test it. If the expert can&#8217;t fill in your example table, the fact is wrong.</p>



<p class="wp-block-paragraph">Read Halpin &amp; Morgan <a href="https://www.sciencedirect.com/book/9780443237904/information-modeling-and-relational-databases"><em>Information Modeling and Relational Databases</em></a> for details.</p>



<h2 class="wp-block-heading">Sketch first, formalize later</h2>



<p class="wp-block-paragraph">Keep formal notation off the whiteboard. Circles and lines and sticky notes are enough: a circle per kind of thing, a line per fact, the sentence written along the line, examples on stickies underneath. ORM has a precise diagram notation, and in a workshop that precision turns contributors into spectators: the expert who happily corrects a sentence will hesitate to touch a diagram symbol.</p>



<p class="wp-block-paragraph">For many domains, a whiteboard photo plus the agreed sentences is the whole model, and stopping there is fine. See <a href="https://leosimons.com/2023/11/02/caseum-my-lightweight-approach-to-software-architecture/">Caseum</a> for more about such a lightweight approach.</p>



<h2 class="wp-block-heading">From facts to schema</h2>



<p class="wp-block-paragraph">Sometimes you can&#8217;t stop there. You need a JSON Schema for an API, a database schema, docs that stay current. Maintaining those by hand, in parallel, is how the drift starts. Better to keep one source file and generate the rest.</p>



<p class="wp-block-paragraph">ORM tooling is not in the best state. <a href="https://linkml.io/">LinkML</a> is a great alternative. It is a YAML-based schema language with <a href="https://linkml.io/linkml/generators/">generators</a> for JSON Schema, SQL, ER diagrams, documentation sites, and typed Pydantic and TypeScript classes.</p>



<p class="wp-block-paragraph">A small HR domain as fact sentences:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Each Person is identified by an id, which is a URI.
Each Person has exactly one name.
Each Person (the coachee) may have one or more coaches, each of whom is a Person.
Each Person has at most one Department.
Each Team has at least one lead, who is a Person.
</pre></div>


<p class="wp-block-paragraph">The same model as LinkML (<code>hr.yaml</code>):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
id: https://example.org/hr
name: hr
prefixes:
  linkml: https://w3id.org/linkml/
  hr: https://example.org/hr/
default_prefix: hr
default_range: string
imports:
  - linkml:types

classes:
  Person:
    attributes:
      id:
        identifier: true
        range: uri
      name:
        required: true
      coach:
        range: Person
        multivalued: true
      department:
        range: Department
  Department:
    attributes:
      id:
        identifier: true
        range: uri
  Team:
    attributes:
      lead:
        required: true
        multivalued: true
        range: Person
</pre></div>


<p class="wp-block-paragraph">Each fact becomes a slot (LinkML&#8217;s word for an attribute), and the how-many wording maps directly:</p>



<figure class="wp-block-table"><table><thead><tr><th>Fact sentence form</th><th>LinkML slot</th></tr></thead><tbody><tr><td><code>is identified by</code></td><td><code>identifier: true</code></td></tr><tr><td><code>has exactly one</code></td><td><code>required: true</code></td></tr><tr><td><code>has at most one</code></td><td>(the default: optional, single-valued)</td></tr><tr><td><code>has at least one</code></td><td><code>required: true</code> + <code>multivalued: true</code></td></tr><tr><td><code>may have one or more</code></td><td><code>multivalued: true</code></td></tr><tr><td><code>who/which is a X</code></td><td><code>range: X</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Settle on a fixed set of phrases like this and turning the whiteboard into a schema stops being design work and becomes transcription, which AI can do for you.</p>



<h2 class="wp-block-heading">From schema to software</h2>



<p class="wp-block-paragraph">Use the LinkML tools to create other files from the model. For example:</p>



<h3 class="wp-block-heading">JSON Schema</h3>



<p class="wp-block-paragraph">Run <code>gen-json-schema hr.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
"Person": {
    "additionalProperties": false,
    "properties": {
        "coach": {
            "items": { "format": "uri", "type": "string" },
            "type": &#91; "array", "null" ]
        },
        "department": { "format": "uri", "type": &#91; "string", "null" ] },
        "id": { "format": "uri", "type": "string" },
        "name": { "type": "string" }
    },
    "required": &#91; "id", "name" ]
}
</pre></div>


<h3 class="wp-block-heading">Mermaid ER diagram</h3>



<p class="wp-block-paragraph">Run <code>gen-erdiagram hr.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
erDiagram
Department {
    uri id
}
Person {
    uri id
    string name
}
Team {
}

Person ||--|o Department : "department"
Person ||--}o Person : "coach"
Team ||--}| Person : "lead"
</pre></div>


<p class="wp-block-paragraph">which <a href="https://mermaid.js.org/#/">Mermaid</a> renders as:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;6a6621b17084a&quot;}" data-wp-interactive="core/image" data-wp-key="6a6621b17084a" class="aligncenter size-large is-resized wp-lightbox-container"><img width="617" height="1023" data-attachment-id="954" data-permalink="https://leosimons.com/2026/07/26/fact-based-modelling-and-linkml/2026-07-28-linkml-article-er/" data-orig-file="https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png" data-orig-size="744,1234" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="2026-07-28-linkml-article-er" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=617" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=617" alt="" class="wp-image-954" style="width:235px;height:auto" srcset="https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=617 617w, https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=90 90w, https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=181 181w, https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png 744w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">(Mermaid is supported by many Markdown tools, including on <a href="https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-diagrams">GitHub</a>)</p>



<h3 class="wp-block-heading">SQL</h3>



<p class="wp-block-paragraph">Run <code>gen-sqlddl hr.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate">
CREATE TABLE "Person" (
    id TEXT NOT NULL,
    name TEXT NOT NULL,
    department TEXT,
    PRIMARY KEY (id),
    FOREIGN KEY(department) REFERENCES "Department" (id)
);

CREATE TABLE "Person_coach" (
    "Person_id" TEXT,
    coach_id TEXT,
    PRIMARY KEY ("Person_id", coach_id),
    FOREIGN KEY("Person_id") REFERENCES "Person" (id),
    FOREIGN KEY(coach_id) REFERENCES "Person" (id)
);
</pre></div>


<h2 class="wp-block-heading">Testing the schema with examples</h2>



<p class="wp-block-paragraph">Given <code>ada.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
id: https://example.org/people/ada
name: Ada
coach:
  - https://example.org/people/grace
</pre></div>


<p class="wp-block-paragraph">and <code>bob.yaml</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
id: https://example.org/people/bob
department: engineering
</pre></div>


<p class="wp-block-paragraph">Here&#8217;s what testing looks like:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ linkml validate -s hr.yaml -C Person ada.yaml
No issues found
$ linkml validate -s hr.yaml -C Person bob.yaml
&#91;ERROR] &#91;bob.yaml/0] 'engineering' is not a 'uri' in /department
&#91;ERROR] &#91;bob.yaml/0] 'name' is a required property in /
</pre></div>


<p class="wp-block-paragraph">There is more to LinkML, but the shape is clear: one schema file, kept under code review, with tool automation so that artifacts do not drift from each other.</p>



<h2 class="wp-block-heading">Remember the facts</h2>



<p class="wp-block-paragraph">Compare the written fact</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Each Person (the coachee) may have one or more coaches, each of whom is a Person.</p>
</blockquote>



<p class="wp-block-paragraph">with the LinkML model slot:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
coach:
  range: Person
  multivalued: true
</pre></div>


<p class="wp-block-paragraph">The sentence names both roles, coach and coachee, and reads aloud in either direction. The slot names one direction and buries the rest in structure. A domain expert can verify the sentence but not the YAML.</p>



<p class="wp-block-paragraph">Keep the written facts and their examples around, right next to the schema. Your AI is excellent at English and so can help keep facts and LinkML in sync.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leosimons.com/2026/07/26/fact-based-modelling-and-linkml/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">950</post-id>
		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>

		<media:content url="https://leosimons.com/wp-content/uploads/2026/07/2026-07-28-linkml-article-er.png?w=617" medium="image" />
	</item>
		<item>
		<title>Anthropomorphizing my agent</title>
		<link>https://leosimons.com/2026/02/01/anthropomorphizing-my-agent/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Sun, 01 Feb 2026 21:19:30 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=919</guid>

					<description><![CDATA[Giving my coding agent some personality.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I think it&#8217;s useful to distinguish which git commits are (partially) AI-authored. I kind-of like how Claude Code sets Claude as co-author of git commits.</p>



<p class="wp-block-paragraph">But I think my coding agent, with all its own settings and quirks and approach, should be distinguished from everyone else&#8217;s. I use more than just Claude Code (I also use GitHub Copilot, Gemini CLI, <a href="https://shittycodingagent.ai/">pi</a>, &#8230;). I thought my coding agent better have some <em>personality</em>.</p>



<p class="wp-block-paragraph">So I&#8217;ve set up a dedicated <a href="https://github.com/lsimons-bot">@lsimons-bot</a>, <a href="https://github.com/lsimons/lsimons-dotfiles/blob/main/docs/AGENT_SETUP.md">put it in a VM sandbox</a>, and <a href="https://github.com/lsimons/lsimons-dotfiles/blob/8335ff02c7053350c9872ca28e6309b736e31868/claude/CLAUDE.md.symlink#L24">instructed it to identify me as its co-author</a>. I&#8217;ve even <a href="https://lsimonsbot.wordpress.com/">given the bot its own blog</a>. Now I get pretty commits with two authors which are me and robot-me:</p>



<figure class="wp-block-image size-large"><a href="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png"><img width="1024" height="372" data-attachment-id="927" data-permalink="https://leosimons.com/2026/02/01/anthropomorphizing-my-agent/lsimons-bot-co-author-2/" data-orig-file="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png" data-orig-size="2346,854" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="lsimons-bot-co-author" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=840" src="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=1024" alt="" class="wp-image-927" srcset="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=1024 1024w, https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=2048 2048w, https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=150 150w, https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=300 300w, https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=768 768w, https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=1440 1440w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></figure>



<p class="wp-block-paragraph">I&#8217;ve tuned the settings so that when I am doing tightly controlled AI-assisted development, the git commits have me as main author and <a href='https://lsimons.wordpress.com/mentions/lsimons/' class='__p2-hovercard mention' data-type='fragment-mention' data-username='lsimons'><span class='mentions-prefix'>@</span>lsimons</a>-bot as coauthor. When I&#8217;m doing vibe coding in the VM, it&#8217;s reversed. And it&#8217;s also nice to see the bot make pull requests which I then review and merge.</p>



<p class="wp-block-paragraph">In Claude Code it is possible to configure its <a href="https://code.claude.com/docs/en/settings#attribution-settings">attribution settings</a>, but not all the coding agents I use can do this just yet, so as of right now I&#8217;m instead wasting tokens on it.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">919</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-github.png" />
		<media:content url="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-github.png" medium="image">
			<media:title type="html">lsimons-bot-github</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>

		<media:content url="https://leosimons.com/wp-content/uploads/2026/02/lsimons-bot-co-author-1.png?w=1024" medium="image" />
	</item>
		<item>
		<title>Understanding Yegge&#8217;s Gas Town</title>
		<link>https://leosimons.com/2026/01/02/understanding-yegges-gas-town/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Fri, 02 Jan 2026 14:29:07 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=912</guid>

					<description><![CDATA[What does factory farming for source code look like?]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>This blog post was co-authored with AI (Google Gemini).</em></p>



<p class="wp-block-paragraph">Steve Yegge is back with &#8220;<a href="https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04" target="_blank" rel="noreferrer noopener">Welcome to Gas Town</a>,&#8221; a novella-sized blog post about his new multi-agent coding systems, full of <em>Mad Max</em> references. It’s an entertaining but puzzling read. He describes a chaotic world of &#8220;polecats&#8221;, &#8220;GUPP&#8221;, and &#8220;Convoys&#8221;, covering the architecture with thick narrative lore.</p>



<p class="wp-block-paragraph">To decipher what he is <em>actually</em> building, I fed the post and his <a href="https://github.com/steveyegge/gastown" target="_blank" rel="noreferrer noopener">GitHub repository</a> into Gemini. It helped me understand Steve&#8217;s vision of a Kubernetes-like control plane for AI code agents and then helped write this blog post.</p>



<h3 class="wp-block-heading">Decoding the Metaphors</h3>



<p class="wp-block-paragraph">Yegge’s system manages the chaos of running 20–30 concurrent AI agents in parallel in YOLO mode. Key parts:</p>



<ul class="wp-block-list">
<li><strong>The Controller (&#8220;The Town&#8221;):</strong> A central Go binary that orchestrates agent lifecycles across projects.</li>



<li><strong>Git-Backed State (&#8220;<a href="https://github.com/steveyegge/beads">Beads</a>&#8220;):</strong> The atomic unit of work isn&#8217;t a database row; it&#8217;s a JSON file committed directly to the project&#8217;s Git history. This makes every task, status, and message persistent and version-controlled.</li>



<li><strong>The Interface:</strong> The system uses <code>tmux</code> as a dashboard (HUD) to manage the fleet of agents.</li>
</ul>



<h3 class="wp-block-heading">The Workforce</h3>



<p class="wp-block-paragraph">The &#8220;Gas Town&#8221; roles map to standard distributed system components:</p>



<ul class="wp-block-list">
<li><strong>&#8220;Mayor&#8221; (Interface):</strong> A persistent agent acting as a Chief of Staff for the human user.</li>



<li><strong>&#8220;Polecats&#8221; (Batch Workers):</strong> Ephemeral agents spun up to execute tasks and vanish.</li>



<li><strong>&#8220;Refinery&#8221; (Merge Queue):</strong> An engineer agent that resolves merge conflicts when multiple workers submit code.</li>



<li><strong>&#8220;Witness&#8221; (Watchdog):</strong> A monitor that detects and restarts stalled agents.</li>
</ul>



<h3 class="wp-block-heading">Tackling complexity</h3>



<p class="wp-block-paragraph">More than the specific solution it&#8217;s interesting to see the underlying problems being solved for. Claude Code is polite and it stops to ask for confirmation, so, control systems are built to make it continue. Claude Code context compaction can remember the wrong things, so structured external memory is provided in specific and evolving ways. Etc.</p>



<p class="wp-block-paragraph">The <a href="https://github.com/steveyegge/gastown">git repo</a> reveals more of such complexity not fully explained in the blog, with the <a href="https://github.com/steveyegge/beads/tree/main/docs">docs</a> containing some of the more interesting insights of what happens when you do vibe coding at scale. For example, <a href="https://github.com/steveyegge/gastown/blob/main/docs/identity.md">why identity of (sub)agents matters</a>.</p>



<p class="wp-block-paragraph">The repo&#8217;s <a href="https://github.com/steveyegge/gastown/blob/main/AGENTS.md">AGENTS.md</a> is interesting too. Agents are explicitly forbidden from asking permission to push; they must run tests, commit, push, and verify success before reporting back.</p>



<p class="wp-block-paragraph">Looks like quite a serious attempt to build an industrialized coding factory, turning the developer from a coder into a manager of a synthetic manager of synthetic workers.</p>



<p class="wp-block-paragraph">Looks like most of the work to make this happen is handling accidental complexity, not essential complexity. I wonder how much of that is due to building on top of Claude Code. Perhaps a future iteration integrates its own less-polite less-error-prone coding agent, something like <a href="https://mariozechner.at/posts/2025-11-30-pi-coding-agent/">pi</a>?</p>



<p class="wp-block-paragraph"><em>(Yegge being co-author of the book <a href="https://www.amazon.com/Vibe-Coding-Building-Production-Grade-Software/dp/1966280025">Vibe Coding</a>, who recently said in a talk &#8220;<a href="https://youtu.be/7Dtu2bilcFs?t=402">if you are using an IDE [in 2026], you are a bad engineer</a>&#8220;, because you should use a coding agent)</em></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">912</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2026/01/gas-town-simplified.jpg" />
		<media:content url="https://leosimons.com/wp-content/uploads/2026/01/gas-town-simplified.jpg" medium="image">
			<media:title type="html">Gas Town explanation, simplified</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
		<item>
		<title>AI demands Literate Programming</title>
		<link>https://leosimons.com/2025/10/20/ai-demands-literate-programming/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 07:26:25 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=895</guid>

					<description><![CDATA[Clarity of expression is demanded of AI-assisted developers.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the 1980s, Donald Knuth introduced <a href="https://en.wikipedia.org/wiki/Literate_programming" target="_blank" rel="noreferrer noopener">literate programming</a>, a paradigm where code and documentation are interwoven into a single narrative. The idea was simple but radical: write programs as if you&#8217;re explaining them to another human — not just to a compiler. His <a href="https://www-cs-faculty.stanford.edu/~knuth/lp.html" target="_blank" rel="noreferrer noopener">WEB system</a> and <a href="https://tug.org/texshowcase/">TeX showcase</a> were early demonstrations.</p>



<p class="wp-block-paragraph">Fast forward to today, and we’re seeing a return to that mindset based on the practical demands of AI-assisted development.</p>



<h3 class="wp-block-heading">Spec-Driven Development: A Modern Twist</h3>



<p class="wp-block-paragraph">To keep tools like <a href="https://github.com/features/copilot">GitHub Copilot</a>, <a href="https://chatgpt.com/features/codex">ChatGPT Codex</a>, and <a href="https://www.claude.com/product/claude-code">Claude Code</a> behaving, developers are increasingly writing <strong>natural language specifications</strong> that guide code generation.</p>



<p class="wp-block-paragraph">This trend, often called <a href="https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html">spec-driven development</a>, emphasises writing structured, human-readable descriptions of what software should do — before writing any code.</p>



<p class="wp-block-paragraph">These specs aren’t just throwaway prompts. They’re version-controlled, reviewed, and treated as first-class artifacts. They are what helps keep the AI on the rails.</p>



<h3 class="wp-block-heading">The Parallel with Literate Programming</h3>



<p class="wp-block-paragraph">What’s happening here mirrors Knuth’s vision. In both cases, the developer is encouraged to <strong>think clearly and write clearly</strong>. The difference is that now, the audience isn’t just other humans — it’s also an AI model that can turn prose into functioning code.</p>



<p class="wp-block-paragraph">Modern tools like <a href="https://jupyter.org/">Jupyter</a> already blurred the line between documentation and implementation. This hybrid approach is now becoming a valuable way to avoid AI slop.</p>



<h3 class="wp-block-heading">Why It Matters</h3>



<p class="wp-block-paragraph">This isn’t just a tooling shift — it’s a cultural one. We’re moving away from “vibe-based coding” and toward a more deliberate, explainable, and collaborative process. And in doing so, we’re rediscovering the value of code as a form of communication.</p>



<p class="has-text-align-left has-medium-gray-color has-white-background-color has-text-color has-background has-link-color has-small-font-size wp-elements-098f1c055bc3b37e57b03dd0d2b3bbbb wp-block-paragraph"><em>Co-authored with AI (Anthropic Claude Sonnet 4.5).</em><br><em>Normally I don&#8217;t publish content that AI helped to write, but I wanted to see how it feels. </em></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">895</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2025/10/ai-and-literate-programming-medium.png" />
		<media:content url="https://leosimons.com/wp-content/uploads/2025/10/ai-and-literate-programming-medium.png" medium="image">
			<media:title type="html">ai-and-literate-programming-medium</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
		<item>
		<title>Caseum: my lightweight approach to software architecture</title>
		<link>https://leosimons.com/2023/11/02/caseum-my-lightweight-approach-to-software-architecture/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Thu, 02 Nov 2023 11:02:29 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Open Source]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=771</guid>

					<description><![CDATA[Whiteboards. Multiple views. Decision records. Pragmatism. Empathy.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Described my software architecture approach at <a href="https://lsimons.github.io/caseum/">https://lsimons.github.io/caseum/</a>. Just common best practices and whiteboards. Hope a simple approach in simple English can be inspiring.</p>



<p class="wp-block-paragraph">Short video introduction:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe class="youtube-player" width="840" height="473" src="https://www.youtube.com/embed/0s1qPY-W1ew?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe>
</div></figure>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">771</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2023/11/caseum-infographic-large.jpg" />
		<media:content url="https://leosimons.com/wp-content/uploads/2023/11/caseum-infographic-large.jpg" medium="image">
			<media:title type="html">caseum-infographic-large</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
		<item>
		<title>Abstract Career Framework for Engineering</title>
		<link>https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Mon, 03 Apr 2023 17:02:03 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[career ladder]]></category>
		<category><![CDATA[career progression]]></category>
		<category><![CDATA[engineering career framework]]></category>
		<category><![CDATA[engineering ladder]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=671</guid>

					<description><![CDATA[I made a career progression framework for my engineering colleagues at Schuberg Philis but it doesn't work.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I&#8217;ve published a <a href="http://sbp.progressionapp.com/teams/sbp-engineers">career framework</a> on <a href="https://progression.fyi/">Progression</a>. It is based on advice I frequently give to engineers and engineering leaders at <a href="https://schubergphilis.com/">Schuberg Philis</a> (SBP). Since I was having more such conversations than I have time for, I created this framework last year to help our coaches have more in-depth career development conversations without me.</p>



<p class="wp-block-paragraph">It doesn&#8217;t work!</p>



<h5 class="wp-block-heading">Disclaimer</h5>



<p class="wp-block-paragraph">Though I incorporated feedback from a lot of colleagues, this was never &#8220;the&#8221; SBP framework. Our company culture is as informal as it can be, with just enough structure. Making a framework such as this official is more than we need. We do not want people to think of their careers as a checklist to complete or as a ladder to climb. Instead, we suggest people mostly focus on growing their impact, picking up and mastering new competencies along the way. </p>



<h2 class="wp-block-heading">Framework</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://sbp.progressionapp.com/teams/sbp-engineers/framework" target="_blank" rel=" noreferrer noopener"><img loading="lazy" width="300" height="130" data-attachment-id="674" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-framework/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg" data-orig-size="2527,1099" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-framework" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=300" alt="" class="wp-image-674" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=300 300w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=600 600w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=150 150w" sizes="auto, (max-width: 300px) 85vw, 300px" /></a></figure>
</div>


<p class="wp-block-paragraph">The base <a href="https://sbp.progressionapp.com/teams/sbp-engineers/framework">framework</a> is rather abstract, defining 10 coarse-grained competencies that apply to all engineering roles, such as &#8220;maintaining quality&#8221; or &#8220;planning and organizing&#8221;. The competencies have up to 7 different levels. These 10 competencies are grouped into Craftsmanship, Human, and Leadership categories.</p>



<p class="wp-block-paragraph">The Progression app is organized into strict levels. To make the tool work for us, the online version of the SBP framework defines these levels too. But these are not actually used within SBP! It&#8217;s quite common to have some competencies at a very high level and others still much lower, and that&#8217;s ok with us. One common example is engineers with very highly rated craftsmanship skills but lower rated teamwork skills. The reverse also happens!</p>



<h2 class="wp-block-heading">Roles</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://sbp.progressionapp.com/teams/sbp-engineers"><img loading="lazy" width="300" height="142" data-attachment-id="676" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-roles/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg" data-orig-size="2400,1141" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-roles" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=300" alt="" class="wp-image-676" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=300 300w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=600 600w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=150 150w" sizes="auto, (max-width: 300px) 85vw, 300px" /></a></figure>
</div>


<p class="wp-block-paragraph">In this framework there are only three <a href="https://sbp.progressionapp.com/teams/sbp-engineers">roles </a>defined: engineers, tech leads, and technology officers.</p>



<p class="wp-block-paragraph">Engineers are our individual contributors (ICs), an industry term we don&#8217;t usually use. When engineers lead others, they do so primarily by example, based on the content of their work.</p>



<p class="wp-block-paragraph">Tech leads (TLs) are engineers that accept additional leadership responsibilities. Tech leads are not in charge of teams, we expect servant leadership of them.</p>



<p class="wp-block-paragraph">Technology officers (TOs) are a lot like tech leads but with somewhat different leadership responsibilities. While tech lead engineers lead one specific team, our technology officers have a somewhat broader scope. They&#8217;re a bit further removed from the day-to-day engineering work, giving them time to focus on cross-team topics and to do work for which there isn&#8217;t a dedicated engineering team available, like presales.</p>



<p class="wp-block-paragraph">TLs and TOs are leaders but not managers. At many companies with career ladders and levels, TLs and TOs might be considered staff or principal engineers, i.e. they are still on the &#8220;individual contributor&#8221; track. While some engineers progress by taking a TL or TO role, it&#8217;s important to realize there are engineers at a &#8220;staff&#8221; or &#8220;principal&#8221; level without a TL or TO role. Those engineers could match a different <a href="https://staffeng.com/guides/staff-archetypes/">staff-plus archetype</a> (like Solver or Architect), or just not match up with such a rigid framework at all. It&#8217;s also possible to switch from a TL or TO role to a regular engineering role.</p>



<p class="wp-block-paragraph">Engineers at SBP do have additional roles at times that require additional competencies. For example, engineers can become coaches. These are not part of the framework.</p>



<h2 class="wp-block-heading">Competencies</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://sbp.progressionapp.com/teams/sbp-engineers/skills"><img loading="lazy" width="300" height="221" data-attachment-id="677" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-skills/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg" data-orig-size="1698,1252" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-skills" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=300" alt="" class="wp-image-677" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=300 300w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=600 600w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=150 150w" sizes="auto, (max-width: 300px) 85vw, 300px" /></a></figure>
</div>


<p class="wp-block-paragraph">While Progression is optimized for defining pretty specific skills for pretty specific roles, this particular framework is broad and generic, and so is focused around <a href="https://sbp.progressionapp.com/teams/sbp-engineers/skills">competencies</a>.</p>



<p class="wp-block-paragraph">There are up to 7 different levels defined per competency.</p>



<p class="wp-block-paragraph">While the basic competencies are the same for TLs and TOs as for engineers, our expectations of where our leaders will focus are a little different, and so for some skills there is a leadership (L) variant defined. Since Progression doesn&#8217;t support such variant definitions, there&#8217;s some overlap/copies.</p>



<h2 class="wp-block-heading">Competency example: Client Orientation</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg"><img loading="lazy" width="296" height="299" data-attachment-id="679" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-client-orientation/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg" data-orig-size="1086,1099" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-client-orientation" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=296" alt="" class="wp-image-679" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=296 296w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=592 592w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=148 148w" sizes="auto, (max-width: 296px) 85vw, 296px" /></a></figure>
</div>


<p class="wp-block-paragraph">SBP is an outsourcing company. Our engineers work in self-steering teams dedicated to a single customer. Because all our engineers have a lot of customer interaction, the framework is relatively heavy on communication compared to many other <a href="https://progression.fyi/">progression examples</a>.</p>



<h2 class="wp-block-heading">Progression for comparing roles &amp; levels</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg"><img loading="lazy" width="300" height="211" data-attachment-id="682" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-comparison/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg" data-orig-size="1789,1261" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-comparison" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=300" alt="" class="wp-image-682" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=300 300w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=600 600w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=150 150w" sizes="auto, (max-width: 300px) 85vw, 300px" /></a></figure>
</div>


<p class="wp-block-paragraph">One cool feature in Progression is how it allows you to put different roles and different levels side by side. This can help engineers think about which direction they might develop in next, though since at SBP we don&#8217;t actually use levels it&#8217;s of limited use for us.</p>



<h2 class="wp-block-heading">Progression for check-ins</h2>


<div class="wp-block-image">
<figure class="alignleft size-medium"><a href="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg"><img loading="lazy" width="275" height="300" data-attachment-id="683" data-permalink="https://leosimons.com/2023/04/03/abstract-career-framework-for-engineering/sbp-progression-checkin/" data-orig-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg" data-orig-size="1155,1261" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="sbp-progression-checkin" data-image-description="" data-image-caption="" data-large-file="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=840" src="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=275" alt="" class="wp-image-683" srcset="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=275 275w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=550 550w, https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=137 137w" sizes="auto, (max-width: 275px) 85vw, 275px" /></a></figure>
</div>


<p class="wp-block-paragraph">A recent addition to Progression is a new check-in feature that arranges a guided conversation between engineers and their managers (or in SBP its case with no line management, coaches). The idea is to agree together on career progression.</p>



<p class="wp-block-paragraph">I like what they&#8217;ve built here. I imagine it&#8217;s a good way for HR departments to help beginning engineering managers have decent-quality factful conversations. But it&#8217;s not the right tool for Schuberg Philis.</p>



<p class="wp-block-paragraph">It&#8217;s a great example of our &#8220;too much structure&#8221; rule kicking in. We have an internal 360-degree feedback process that is less structured than this, asking open questions instead, focusing on the important feedback conversation more and happily sacrificing some structured/detailed record-keeping in the process. Maybe when SBP is 10 times bigger that has to change?</p>



<h2 class="wp-block-heading">Spreadsheet version</h2>



<p class="wp-block-paragraph">I created the Progression version of this framework based on my initial <a href="https://docs.google.com/spreadsheets/d/1Sz3tDzeKl-erdjznDJii5c34hMCFnFHorji2l8yVWqc/edit?usp=sharing">spreadsheet version of this career framework</a>. I&#8217;ve found most people feel quite overwhelmed (at best) when confronted with this spreadsheet, while HR professionals appreciate the comprehensive overview.</p>



<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vQrLGF79MfI2CexJ5fw_K05cEgwAlC-cPcYu7G9iPBSs_zrjOZsBjce5QA6sasKcH5p5M-ys5dL65Ya/pubhtml?gid=1716506889&#038;single=true&#038;widget=true&#038;headers=false" frameborder="0" width="100%" height="400" marginheight="0" marginwidth="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>



<h2 class="wp-block-heading">Success!</h2>



<p class="wp-block-paragraph">Developing this framework helped me think through career guidance in great depth and that has helped make my advice to others clearer. I sometimes refer back to it when helping to weigh or appraise feedback, during salary discussions, or when writing job specs.</p>



<p class="wp-block-paragraph">Putting the framework in Progression really helped to compare our framework to other engineering companies and to benchmark our internal levelless ranking system to common industry levels. Sometimes I can use it to explain to our younger engineers that no, they would not be ranked as principal engineers at Google, yet!</p>



<p class="wp-block-paragraph">The process of iterating on the framework together was valuable. Asking and discussing feedback helped to align our leadership&#8217;s thinking about how we appraise and value our colleagues. Beyond leadership, trying to describe very different work in common terms (dev and ops, for example) helped the people involved to understand more about each other.</p>



<p class="wp-block-paragraph">Our HR professionals happily adopted the framework, for example to develop and finetune our internal leadership training. For my HR colleagues relatively new to IT organizations it really helped them to see and understand both the breadth and the depth of our careers.</p>



<h2 class="wp-block-heading">Failure!</h2>



<p class="wp-block-paragraph">This framework hasn&#8217;t helped our engineers or their coaches! My colleagues may look at it, perhaps understand it as reasonable and sensible&#8230;and then will never use it during their career planning or career development conversations.</p>



<p class="wp-block-paragraph">People are unsure why, but they tell me the framework &#8220;doesn&#8217;t feel right&#8221;.</p>



<p class="wp-block-paragraph">I believe one problem is that the level of abstraction is so high people don&#8217;t know how to apply it for themselves in a practical way. Making more concrete roles (like &#8220;java developer&#8221;) with more concrete skills (like &#8220;java programming&#8221;) could help, but that&#8217;s a lot of work to set up and maintain.</p>



<p class="wp-block-paragraph">I believe another problem is that the setup is still too constrained: our actual appraisal system is more free-form. I imagine if we were to strictly define career levels that would then prompt more colleagues to use this framework. Especially if we linked the levels to salary ranges. And&#8230;I don&#8217;t know that would be positive. SBP tries to be a place where all our colleagues can <a href="https://schubergphilis.com/en/who-we-are/our-story">&#8220;become who they are&#8221;</a>, which for many colleagues can mean quite an &#8220;unbalanced&#8221; set of competencies.</p>



<p class="wp-block-paragraph">The framework also hasn&#8217;t helped me! Our non-technical coaches have difficulty using the more technical competencies. You need an experienced technologist&#8217;s help to evaluate the quality of your solutions designs or implementation plans, to determine how competent you got. It sucks to have a conversation about those things with a non-technical coach.</p>



<p class="wp-block-paragraph">So in the end even if my colleagues do use this framework, they will still ask for my help, and I save no time!</p>



<p class="wp-block-paragraph">Fortunately, it&#8217;s the kind of conversation I love to have.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">671</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg" />
		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg" medium="image">
			<media:title type="html">sbp-progression-framework</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-framework.jpg?w=300" medium="image" />

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-roles.jpg?w=300" medium="image" />

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-skills.jpg?w=300" medium="image" />

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-client-orientation.jpg?w=296" medium="image" />

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-comparison.jpg?w=300" medium="image" />

		<media:content url="https://leosimons.com/wp-content/uploads/2023/04/sbp-progression-checkin.jpg?w=275" medium="image" />
	</item>
		<item>
		<title>Salary setup for Dutch developers</title>
		<link>https://leosimons.com/2022/02/25/salary-setup-for-dutch-developers/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Fri, 25 Feb 2022 14:27:45 +0000</pubDate>
				<category><![CDATA[Work]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=642</guid>

					<description><![CDATA[Let&#8217;s now ignore the BigTech companies who are paying lots of money, as well as the employers trying to compete with them, and instead think a bit about the average local Dutch market. What might a reasonable salary expectation for a full-time job at an average local Dutch employer? Permanent contract vs 1-year contract Dutch &#8230; <a href="https://leosimons.com/2022/02/25/salary-setup-for-dutch-developers/" class="more-link">Continue reading<span class="screen-reader-text"> "Salary setup for Dutch&#160;developers"</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Let&#8217;s now ignore the <a href="https://leosimons.com/2022/02/24/rising-developer-salaries-in-amsterdam/">BigTech companies who are paying lots of money</a>, as well as the employers trying to compete with them, and instead think a bit about the average local Dutch market. What might a reasonable salary expectation for a full-time job at an average local Dutch employer?</p>



<h5 class="wp-block-heading" id="permanent-contract-vs-1-year-contract">Permanent contract vs 1-year contract</h5>



<p class="wp-block-paragraph">Dutch employment law can get <a href="https://www.iamexpat.nl/career/working-in-the-netherlands/work-employment-contracts">pretty complex</a>, making the non-financial terms important when evaluating salary. One key factor is whether you&#8217;re looking at a permanent contract or not.</p>



<p class="wp-block-paragraph">For more senior positions, permanent contracts are common. If you do your job well and the company is doing ok financially, your employer cannot easily fire you from a permanent contract, which makes these popular with risk-averse employees and unpopular with commitment-averse employers.</p>



<p class="wp-block-paragraph">For more junior positions, 1-year contracts are common. 1-year contracts often get automatically extended, and then can convert into permanent contracts automatically after 3 years.</p>



<p class="wp-block-paragraph">Getting a mortgage is harder without a permanent contract since banks are also risk-averse.</p>



<p class="wp-block-paragraph">The base salaries for both contract types tend to be comparable, but permanent contracts usually have better non-base salary benefits leading to a better total benefits package.</p>



<h5 class="wp-block-heading" id="common-benefits-package-components">Common benefits package components</h5>



<p class="wp-block-paragraph">A Dutch contract usually has a <strong>yearly salary</strong> listed for a full-time job. Usually full-time for developer jobs means 40 hours a week. If you work less hours you will be paid proportionally less, while if you structurally work more you typically do not get paid for that at all.</p>



<p class="wp-block-paragraph">The base yearly salary includes 8% yearly <a href="https://www.iamexpat.nl/career/employment-news/holiday-allowance-and-vacation-days-netherlands"><strong>holiday allowance</strong></a>, which is usually paid once a year in May. In May you receive 15.67% of your yearly salary, while in all other months you receive 7.67%.</p>



<p class="wp-block-paragraph"><strong>Discretionary bonuses</strong> are now reasonably common in Dutch IT companies, paid out yearly, with 5%-20% of your yearly salary reasonably common, and 10% probably the most common percentage. Usually <em>discretionary </em>means that your manager informs you once a year if you get your bonus and how much you will get, i.e. your employer can decide for any reason not to pay you the bonus.</p>



<p class="wp-block-paragraph">It is uncommon for Dutch employers to actually <em>promise </em>bonuses, or otherwise tie bonus payout to profits or performance targets in a transparent way. When that arrangement is written into your contract it is a <strong>performance bonus</strong> instead of the common discretionary bonus, which you may encounter for more commercial roles (i.e. a role as a presales engineer).</p>



<p class="wp-block-paragraph"><strong>Stock options</strong>, <strong>shares</strong>, <strong>employee ownership</strong> plans, and <strong>profit sharing</strong> agreements are relatively uncommon for Dutch IT companies. Even when they are used, the &#8220;standard&#8221; approaches that exist in the US tech industry for stock options are not standard here, which means most US-centric advice on the internet about such things does not apply. The actual benefit of such programs relative to base salary can range from pretty neglible (more common) to pretty dominant (rare).</p>



<p class="wp-block-paragraph">Cars in The Netherlands are expensive to own and drive, due to how taxes for them work as well as due to high taxes on gas. <strong>Lease cars</strong> are common, where your employer arranges a car for you (often of the type and with the options you choose) with a leasing company. Your employer pays for your car every month, including for any gas used. If you also use this car for non-work travel then you have to pay extra income tax based on the catalog value of the car. If you like driving a modern car this usually works out cheaper than other approaches. At some employers, lease cars are getting replaced with <strong>mobility budgets</strong> or <strong>public transport passes</strong>.</p>



<p class="wp-block-paragraph">A full-time contract includes a mandatory minimum of 20 vacation days. These are a legal right; you might see them as a government-mandated benefit. Many employers include <strong>extra vacation days</strong> above 20, sometimes with various differing rules for exchanging days for cash, buying extra days, and so on. Besides vacation you also have rights to parental leave, sick days, and so on.</p>



<p class="wp-block-paragraph"><strong>Paid overtime</strong> and <strong>standby shift compensation</strong> are rather uncommon for developers. If your contract does include paid overtime it is likely based on extra hours worked per week or month, which means tracking all hours. Night or weekend hours may be paid at 150% or 200%. Working a lot of overtime can mean quite significant additional income.</p>



<p class="wp-block-paragraph">Most permanent contracts will include a <strong>pension</strong>, for which there are many different and confusing different setups that are hard to compare and value. It&#8217;s common these days that your employer pays some monthly amount into a fund on your behalf that is based on a combination of your base salary plus your age, with the amount being only a few percent for people under 30 and quite a lot for those close to retirement. The fine print around Dutch pensions is often more complex than for the rest of the employment contract combined.</p>



<p class="wp-block-paragraph">Many employers also mention providing the things you need to do your job (like laptops, phones, and training budget) as benefits, or they point out lunch or snack arrangement or fun company events. While of course it&#8217;s nice if an employer provides such <strong>perks</strong>, when contrasting offers financially most of these are usually not significant. It&#8217;s also very rare for these perks to be promised contractually.</p>



<p class="wp-block-paragraph">One aspect that is not considered a perk is what <strong>working from home</strong> arrangements have been made. Besides your own preferences around this, not having a daily commute may save you money &amp; time, while not having your home office setup paid for may cost you money or health.</p>



<h5 class="wp-block-heading" id="salary-ranges">Salary ranges</h5>



<p class="wp-block-paragraph">Dutch developer salaries are perhaps <a href="https://www.payscale.com/research/NL/Job=Software_Developer/Salary">€43k average</a>, compared to <a href="https://www.cpb.nl/augustusraming-2021-2022">€38k median</a> salary across the country for all jobs. I&#8217;ve never heard of a developer making half that average, while double the average and more does happen. Most developers make close to and perhaps a bit less than the average, while a select few developers make a lot more. What&#8217;s going on?</p>



<ul class="wp-block-list"><li>Senior developers switch into different higher-paying jobs that have different titles, like architect, manager, or consultant.</li><li>Senior developers go freelance, so they write invoices instead of receive a salary.</li><li>Senior developers don&#8217;t do things to increase their salary, instead doing things they find more fun or interesting.</li><li><a href="https://danluu.com/talent/">We have no idea what individual developers are worth</a>, so there are few good arguments for employers to pay much higher than average.</li></ul>



<p class="wp-block-paragraph">Even for those salaried developers that do continue to hone their craft and gain the experience that clearly makes them more valuable, I believe the salary curve flattens out. A bit of this is simply due to how The Netherlands thinks about what&#8217;s a fair distribution of income. A bit of this is because developers don&#8217;t like salary negotiation so their employer ends up paying them what they can, instead of what they are worth.</p>



<h5 class="wp-block-heading" id="evaluating-benefits-packages">Evaluating benefits packages</h5>



<p class="wp-block-paragraph">With all that basic understanding in place, you might now enjoy playing with this <a href="https://docs.google.com/spreadsheets/d/1f09Ombqcux91S0scE8pVWa0ZFH-TxFT1JSM7__XRhEw/edit?usp=sharing">google sheet of example developer salaries</a> that I invented to make the above graph:</p>



<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vQ78FhXMEDquuNG33jUD5qdlh5fZKKgkr_m3Jb4D_x-29aLgAq5AxsbivFrUwR8mQehEvZXqXUtLw-r/pubhtml?gid=0&#038;single=true&#038;widget=true&#038;headers=false" frameborder="0" width="100%" height="420" marginheight="0" marginwidth="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>



<p class="wp-block-paragraph">The sheet might help as a baseline for evaluating different benefits packages and contrasting some different salary ladders against a simple baseline. The absolute values are probably less useful, though I did attempt to have them be reasonable based on my own experience and some general awareness of 2021 numbers at a couple different companies.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">642</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2022/02/developer-salary-by-level-1.png" />
		<media:content url="https://leosimons.com/wp-content/uploads/2022/02/developer-salary-by-level-1.png" medium="image">
			<media:title type="html">developer-salary-by-level-1</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
		<item>
		<title>Rising developer salaries in Amsterdam</title>
		<link>https://leosimons.com/2022/02/24/rising-developer-salaries-in-amsterdam/</link>
					<comments>https://leosimons.com/2022/02/24/rising-developer-salaries-in-amsterdam/#comments</comments>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Thu, 24 Feb 2022 08:12:22 +0000</pubDate>
				<category><![CDATA[Work]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=636</guid>

					<description><![CDATA[What&#8217;s a reasonable base salary for hiring really great senior software engineers in Amsterdam in 2022? As always &#8220;it depends&#8221;, but the answer is also jarringly different in 2022 than it was in 2019. Sample goal: cool company where no-one worries about money FAANG pay high salaries but not everyone wants to work for them. &#8230; <a href="https://leosimons.com/2022/02/24/rising-developer-salaries-in-amsterdam/" class="more-link">Continue reading<span class="screen-reader-text"> "Rising developer salaries in&#160;Amsterdam"</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">What&#8217;s a reasonable base salary for hiring really great senior software engineers in Amsterdam in 2022? As always &#8220;it depends&#8221;, but the answer is also jarringly different in 2022 than it was in 2019.</p>



<h5 class="wp-block-heading" id="sample-goal-cool-company-where-no-one-worries-about-money">Sample goal: cool company where no-one worries about money</h5>



<p class="wp-block-paragraph"><a href="https://www.levels.fyi/">FAANG pay high salaries</a> but not everyone wants to work for them. You may choose to work for a smaller company, or a cooler one, or one with better values. Perhaps then we can pay a bit less?</p>



<p class="wp-block-paragraph">Let&#8217;s look for a really cool small company with solid values, and see what they pay. <a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">Bryan Cantrill&#8217;s Oxide Computer pays everyone who works at their company a $180k base salary</a> (€160k). That is enough:</p>



<ol class="wp-block-list">
<li>to live comfortably with 3 kids in the Bay Area;</li>



<li>to be in the top 5% of income in the US;</li>



<li>to not worry about money, even when putting extra organic raspberries in your shopping basket.</li>
</ol>



<p class="wp-block-paragraph">They also provide good benefits like healthcare and stock options. For them, €160k is enough to take money of the table as a employee demotivator, enough to assemble a great team.</p>



<p class="wp-block-paragraph">The people that work at Oxide Computer could earn more at other employers. That&#8217;s ok: beyond some amount, more money simply matters less than other things, like pursuing autonomy, mastery, and purpose. What they offer candidates is something like <em>join a great team, try to make something cool <a href="https://oxide.computer/principles">following decent principles</a>, live comfortably, and have a small chance to become independently wealthy</em>.</p>



<p class="wp-block-paragraph">While it&#8217;s not a goal for them forever, Oxide so far has (quite) senior engineers only, of which Bryan writes &#8220;engineers at the earliest stages of their career are unlikely to be a fit for us right now&#8221;.</p>



<p class="wp-block-paragraph">Let&#8217;s imagine we start a similarly cool company, with similar hiring goals, but in Amsterdam, The Netherlands. Let&#8217;s imagine we want to hire (someone like) Bryan as our first awesome senior engineer. He&#8217;ll get options or shares of course, and a nice pension, and so on, but what base salary should we pay him so money is not a worry?</p>



<h5 class="wp-block-heading" id="76-000">€76.000?</h5>



<p class="wp-block-paragraph">The <a href="https://www.cpb.nl/augustusraming-2021-2022">estimated modal income in The Netherlands for 2022</a> is €38k gross. €38k is the income where 50% of employees make less and 50% make more than that. An example of a job where you can expect to make about €38k is as a nurse with a college degree.</p>



<p class="wp-block-paragraph">€76k is double that modal income. Ignoring market conditions, I consider double-modal quite a decent benchmark salary for individual contributor senior software engineers with a lot of experience.</p>



<ul class="wp-block-list">
<li>Until our recent housing crisis, a double-modal income was enough to buy a house, support a family, and otherwise live quite a comfortable life in The Netherlands;</li>



<li>€76k is more than the average senior software engineer makes in The Netherlands, which is probably about €60k;</li>



<li>Above-average does seem reasonable to me, after all this is Bryan Cantrill we&#8217;re trying to hire!</li>



<li>It <em>feels</em> right to me.</li>
</ul>



<p class="wp-block-paragraph">Unfortunately, with the rising house prices, €76k salary is currently not enough for Bryan to buy a comfortable Amsterdam family home, and it&#8217;s definitely not enough for unlimited organic fruit. We should deal with our housing crisis and make healthy food cheaper, but in the meantime&#8230;</p>



<h5 class="wp-block-heading" id="100-000">€100.000??</h5>



<ol class="wp-block-list">
<li>To live in a modern 4 bedroom house in the greater Amsterdam area, Bryan&#8217;s mortgage will be about €550k, for which he will need a salary of about €100k;</li>



<li>He&#8217;ll pay about 40% income tax, so will have net income of about €60k, which puts him in <a href="https://www.cbs.nl/nl-nl/visualisaties/inkomensverdeling">the top 5% of income in The Netherlands</a>;</li>



<li>After base costs, perhaps €30k remains as disposable income, which should be plenty for all the raspberries he&#8217;d like, plus a couple of family ski trips a year, plus buying carbon offsets for that trip.</li>
</ol>



<p class="wp-block-paragraph">€100k ought to be enough of a base salary based on the goals we picked. It&#8217;s is a lot more than most software engineers make in The Netherlands, but $180k is of course also more than most software engineers make in the USA. We want excellent people so we will have to pay an excellent salary <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h5 class="wp-block-heading" id="140-000">€140.000???</h5>



<p class="wp-block-paragraph">Most expats prefer living in Amsterdam itself instead of merely close to it. It&#8217;s nice when the staff at the local organic grocery shop speaks fluent English as they point out the organic raspberries isle. To live in Amsterdam itself, Bryan&#8217;s cost of living goes up a lot, especially for housing.</p>



<ol class="wp-block-list">
<li>He will need perhaps an €800k mortgage, for which he needs a salary of about €140k;</li>



<li>His taxes will then be a bit higher too, for a net income of about €80k, which now puts him in the top 2% of income in The Netherlands;</li>



<li>Perhaps €35k of that is now disposable income, still plenty for those more expensive Amsterdam raspberries.</li>
</ol>



<p class="wp-block-paragraph">Beyond just money, the living standards for the top 5%/2% of earners in The Netherlands are arguably quite amazing compared to the Bay Area. After all The Netherlands is one of the best places to live in the world! Rather than try to flesh out that argument here I&#8217;ll point out the excellent YouTube channel <a href="https://www.youtube.com/c/NotJustBikes/videos?view=0&amp;sort=p&amp;flow=grid">NotJustBikes</a>.</p>



<p class="wp-block-paragraph">So is this €140k enough to get Bryan to join us? Of course €140k isn&#8217;t €160k…but since The Netherlands is so awesome, it does seems somewhat reasonable to me to have to take a bit of a paycut to live here, just like it also seems reasonable to take a bit of a paycut to work for an amazing company such as Oxide Computer. That 12% paycut might be ok to Bryan, and is a bit less than the 15% cost of living difference between the Bay Area and Amsterdam, so day to day it may not feel like a big paycut to him.</p>



<h5 class="wp-block-heading" id="160-000">€160.000????</h5>



<p class="wp-block-paragraph">It&#8217;s 2022 and many US tech companies are all-in on full-remote work, often no longer adjusting for cost of living when setting global salaries. More and more of these companies will pay those Bay Area salaries over here, so to be globally competitive in the job market €160k now really is <a href="https://techpays.com/countries/netherlands/amsterdam/tier-3">the rate to match</a> and that&#8217;s what our imaginary Amsterdam startup should probably do.</p>



<p class="wp-block-paragraph">Wow. While €100k is already considered a high salary by most Dutch standards for just about any regular job, €160k plus benefits is more than most Dutch software engineers imagined they could make at any point in their careers. Over here that €160k makes you a part of the 1% even before considering the rest of your benefits package. Many software engineers are loyal employees who don&#8217;t like to change jobs, but finding out a life-changing amount of money is perhaps on offer (while building cool things with Bryan Cantrill, no less!) many of us are tempted!</p>



<p class="wp-block-paragraph">On the other side of the negotiating table, as a hiring manager who pays their engineers €76k or perhaps €100k and thinks that it is quite a generous and reasonable amount, it can be jarring when we hear that those same engineers now earn 60-100% more somewhere else for the same (or more fun!) work. Should we try and somehow match the US salaries, or, should we accept we&#8217;re not a globally competitive employer and risk losing some of our best people? Ugh! That also doesn&#8217;t <em>feel</em> right.</p>



<h5 class="wp-block-heading" id="how-high-will-salaries-go">How high will salaries go?</h5>



<p class="wp-block-paragraph">Over the last few quarters a lot of Dutch employers are <a href="https://blog.pragmaticengineer.com/off-cycle-compensation-adjustments-for-software-engineers-in-2021/">bumping engineering salaries by 10-20% or more</a>, <a href="https://www.asdcode.de/2022/02/it-salary-survey-december-2021.html">German IT salaries are going up fast</a> too, and probably this really is true across Europe. Employers are trying to remain competitive in the job market&#8230;but is a 10% bump enough when 60% or 100% more salary is on offer elsewhere?</p>



<p class="wp-block-paragraph">Since the scarcity of senior software engineers won&#8217;t be fixed change quickly, and the BigTech companies can afford to pay a lot, it seems like the top global salaries are poised to still go up further in the short term, in turn creating further strain in our local job market, and keeping the money topic on the table for most IT employers and employees everywhere.</p>



<h5 class="wp-block-heading" id="will-salaries-come-back-down">Will salaries come back down?</h5>



<p class="wp-block-paragraph">Perhaps. The global economy seems to be overheating. It could be we are in another bubble, which could burst, which could turn the scarcity of engineers into surplus of engineers really quickly as investment drops. Since no-one really understands how the global economy works, it&#8217;s hard to be sure.</p>



<p class="wp-block-paragraph">(Disclaimers: I work in outsourcing, not at a startup. I work and live in the Amsterdam area but not in Amsterdam itself. This is not how compensation is set up where I work. I make a lot less money than Bryan Cantrill, who was also not consulted about this blog post (I owe you some raspberries, Bryan).)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leosimons.com/2022/02/24/rising-developer-salaries-in-amsterdam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">636</post-id>
		<media:thumbnail url="https://leosimons.com/wp-content/uploads/2022/02/rising-developer-salaries-medium.png" />
		<media:content url="https://leosimons.com/wp-content/uploads/2022/02/rising-developer-salaries-medium.png" medium="image">
			<media:title type="html">rising-developer-salaries-medium</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
		<item>
		<title>Think and say &#8220;I don&#8217;t know&#8221;</title>
		<link>https://leosimons.com/2021/12/17/think-and-say-i-dont-know/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Fri, 17 Dec 2021 07:50:05 +0000</pubDate>
				<category><![CDATA[Life]]></category>
		<guid isPermaLink="false">http://leosimons.com/?p=627</guid>

					<description><![CDATA[Think "I don't know" more often and then say it. It helps you and others fight bias. Maybe, I don't know.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">We like to be certain of our beliefs, theories, opinions and emotions. We like things simple, consistent, and fast. We follow strong leaders and make their ideas our own. We believe our own memories and knowledge. These <em>biases</em> cause us and others many issues:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://upload.wikimedia.org/wikipedia/commons/6/65/Cognitive_bias_codex_en.svg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Cognitive_bias_codex_en.svg/512px-Cognitive_bias_codex_en.svg.png" alt="The cognitive bias codex showing many common biases" /></a><figcaption><a href="https://commons.wikimedia.org/wiki/File:Cognitive_bias_codex_en.svg">Interactive cognitive bias codex by John Manoogian III, Buster Benson, and TilmannR, CC BY-SA 4.0, Wikimedia Commons</a></figcaption></figure></div>



<p class="wp-block-paragraph">To fight your own bias think: <em>&#8220;I don&#8217;t know&#8221;</em>. Question your own thoughts, knowledge and beliefs, often, more than is comfortable. This will improve your thinking and reduce your bias. The more you question yourself the easier it gets.</p>



<p class="wp-block-paragraph">To help others fight their bias, lead by example. Say <em>&#8220;I don&#8217;t know&#8221;</em> out loud. By saying it you make it easier for them to think and say it too.</p>



<p class="wp-block-paragraph">To think and work together, listen to and try to understand others with a mindset of not knowing. If our own position is unsure we are more open to ideas of others. As a leader in a group conversation you can say: <em>&#8220;I don&#8217;t know, what do others think?&#8221;</em></p>



<p class="wp-block-paragraph">I don&#8217;t know any of this for sure! I think the above is good advice because scientific and philosophical content points in this direction and (I think&#8230;) I have some experience with it myself. But don&#8217;t take my word for it!</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">627</post-id>
		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>

		<media:content url="https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Cognitive_bias_codex_en.svg/512px-Cognitive_bias_codex_en.svg.png" medium="image">
			<media:title type="html">The cognitive bias codex showing many common biases</media:title>
		</media:content>
	</item>
		<item>
		<title>The philosophy of inconsequentialism</title>
		<link>https://leosimons.com/2021/11/22/the-philosophy-of-inconsequentialism/</link>
		
		<dc:creator><![CDATA[Leo Simons]]></dc:creator>
		<pubDate>Mon, 22 Nov 2021 16:43:03 +0000</pubDate>
				<category><![CDATA[Life]]></category>
		<guid isPermaLink="false">http://lsimons.wordpress.com/?p=620</guid>

					<description><![CDATA[These are some of my initial reflections about a newly minted Dutch philosophy. Frank Meester is a Dutch philosopher who has written a new book Waarom we de wereld niet rond krijgen: pleidooi voor inconsequentie(&#8220;Why we can&#8217;t make the world whole: plea for inconsequence&#8221; &#8211; amazon &#124; bol &#124; libris) I found the book&#8217;s form &#8230; <a href="https://leosimons.com/2021/11/22/the-philosophy-of-inconsequentialism/" class="more-link">Continue reading<span class="screen-reader-text"> "The philosophy of inconsequentialism"</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">These are some of my initial reflections about a newly minted Dutch philosophy.</p>



<p class="wp-block-paragraph"><a href="https://www.burofludo.nl/">Frank Meester</a> is a Dutch philosopher who has written a new book</p>



<p class="wp-block-paragraph"><a href="https://www.burofludo.nl/product/waarom-we-de-wereld-niet-rond-krijgen-pleidooi-voor-inconsequentie/">Waarom we de wereld niet rond krijgen: pleidooi voor inconsequentie</a><br>(&#8220;Why we can&#8217;t make the world whole: plea for inconsequence&#8221; &#8211; <a href="https://www.amazon.nl/Waarom-wereld-niet-kunnen-krijgen-ebook/dp/B08Z7CLQ5J/">amazon </a>| <a href="https://www.bol.com/nl/nl/p/waarom-we-de-wereld-niet-rond-kunnen-krijgen/9300000030692208/">bol </a>| <a href="https://libris.nl/boek?authortitle=frank-meester/waarom-we-de-wereld-niet-rond-kunnen-krijgen--9789025909147">libris</a>)</p>



<p class="wp-block-paragraph">I found the book&#8217;s form almost as interesting as its main ideas. On the one hand it&#8217;s a &#8220;properly&#8221; structured philosophical work with a clear argument that&#8217;s built up and examined from several perspectives, and supported with many references to prior work (including Kant, Wittgenstein, Sartre, Peirce). On the other hand it&#8217;s an accessible story that&#8217;s full of casual and witty sentences, anecdotes, and modern cultural references, never taking itself too seriously for too long, and taking care to provide simple explanations for all philosophical concepts referenced.</p>



<p class="wp-block-paragraph">I think this dual form works well to get across the main idea. Meester&#8217;s main point in the book is to introduce his own new philosophy dubbed inconsequentialism, which is summarized in his main statements:</p>



<ol class="wp-block-list"><li>It isn&#8217;t possible to tell a consistent or consequent story about life.</li><li>Because total consequence is not possible, we do not have to find it annoying when we don&#8217;t quite succeed at it.</li><li>In practices almost everything is a little bit possible.</li><li>A little bit is already quite something.</li></ol>



<p class="wp-block-paragraph">At first these seemed almost trivial statements to me that could hardly be the basis for a full book, but Meester diggs into them and their impact in quite some detail. In the first part of the book Meester reviews logic and reality for their inherent (in)consistency, building his philosophy on top of work by primarily Wittgenstein and Kant, assisted with reference to modern physics and quantum physics. In part two he moves on to consequences of his inconsequentialism, looking at pragmatism, the hermeneutic circle, ethics, and determinism. In part three he contrasts his inconsequentialism with existentialism, humanism, absurdism, and performativity.</p>



<p class="wp-block-paragraph">The weakest part of the book for me is where Meester dives into physics and specifically quantum physics, subject matter he admits he is not too deeply familiar with. For some reason it is pretty popular these days to take the small scale awkwardness of quantum physics to make large scale arguments about the nature of nature, and Meester does the same. But the instances where that scale-up makes sense in nature are a rare exception to the rule that in the large you can usually get by with Newtonian physics, a rule that ought to mostly carry over to philosophical constructs. Fortunately most of Meester&#8217;s argument still holds up even when rejecting his view on modern physics.</p>



<p class="wp-block-paragraph">I guess Meester&#8217;s incosequentialism might be very <em>Dutch</em>. In many ways it&#8217;s a modest and moderate philosophy, down-to-earth and practical, forgiving and reasonably applicable to daily life. As far as philosophies go, this one lacks grandeur, does not strive for greatness, doesn&#8217;t strongly critique or fully reject the ideas that came before. Instead Meester is poised to get along about equally well with influential Greeks, German, French and American philosophers.</p>



<p class="wp-block-paragraph">I guess if Meester&#8217;s very Dutch, I might also be very Dutch, because I find this book to be closer to my own personal philosophy than most other philosophical work I&#8217;ve read recently. By rejecting absolute/simple answers to typical philosophical puzzles as well as the absoluteness/simpleness of those puzzles themselves, there&#8217;s room for nuance. For example:</p>



<ul class="wp-block-list"><li>It&#8217;s good to try to live the good life, even if it is hard to have an exact definition of what the good life is or to be perfect at living it.</li><li>It&#8217;s good to have lofty dreams and ideals, while it&#8217;s also ok to have practical pragmatic compromise when it is not possible to reach the ideal.</li><li>Compromising on ideals doesn&#8217;t make the ideals bad or useless.</li></ul>



<p class="wp-block-paragraph">I find such thoughts hopeful and comforting. If you can read Dutch I can recommend this as an accessible and enjoyable book, even if normally you don&#8217;t read philosophy. (As far as I can tell the book has no English translation yet but I&#8217;ll update this post if that changes.)</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">620</post-id>
		<media:content url="https://0.gravatar.com/avatar/f143f73fe0eba6aa3d82ef89a93e746a76637af3040c276a2421762a1f106676?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lsimons</media:title>
		</media:content>
	</item>
	</channel>
</rss>
