<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  
  <title>Cameron Gorrie</title>
  <subtitle>Writing on software, music, and whatever else.</subtitle>
  <link href="https://sastraxi.com/blog/feed.xml" rel="self" />
  <link href="https://sastraxi.com/" />
  <updated>2026-10-09T00:00:00Z</updated>
  <id>https://sastraxi.com/</id>
  <author>
    <name>Cameron Gorrie</name>
  </author>
  <entry>
    <title>The right number of constraints</title>
    <link href="https://sastraxi.com/blog/the-right-number-of-constraints/" />
    <updated>2026-10-09T00:00:00Z</updated>
    <id>https://sastraxi.com/blog/the-right-number-of-constraints/</id>
    <content type="html">&lt;p&gt;An important skill in software development is determining whether you have the right number of constraints. &lt;a href=&quot;https://sookocheff.com/post/architecture/innovation-with-constraints/&quot;&gt;This is&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://spin.atomicobject.com/constraints-good-custom-software/&quot;&gt;not a&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://dev.to/mjodeh/the-hidden-cost-of-starting-development-too-early-1hgj&quot;&gt;new idea&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Every way of running a project — e.g. waterfall, agile — has moments where we transition from planning to action. Waterfall, at least the idealized version, has exactly one decision point: have we figured &lt;em&gt;everything&lt;/em&gt; out? The &amp;quot;agile&amp;quot; pratcies I&#39;ve seen are much more haphazard with these moments, determined by the engineering lead who is planning alongside a designer and a product manager while also executing.&lt;/p&gt;
&lt;p&gt;A seasoned engineer asks &amp;quot;what&#39;s defined enough to implement?&amp;quot; constantly. This runs in reverse too: when do we need to stop and go back to planning, because we no longer have confidence we can execute?&lt;/p&gt;
&lt;p&gt;I&#39;ve been toying with the idea that this confidence is a proxy for the project&#39;s constraints. Too few, and you&#39;re lost: too much is possible, so nothing is obvious, and I think this is where most projects spend most of their time. With too many constraints, you&#39;ve hit a wall: the library doesn&#39;t quite support your use case, or the blast radius grows until you&#39;re putting your hands up and pulling the &amp;quot;scope is blowing up&amp;quot; cord.&lt;/p&gt;
&lt;p&gt;Somewhere in the middle there&#39;s a space of low turbulence where execution feels close to effortless.&lt;/p&gt;
&lt;h2&gt;Under-thinking, over-thinking&lt;/h2&gt;
&lt;p&gt;One of the best developers I&#39;ve worked with put it this way: &amp;quot;I&#39;m just trying to prune my decision tree to get to the right one.&amp;quot; He knows it&#39;s bullshit to try to brute-force the answer.&lt;/p&gt;
&lt;p&gt;I think every programmer has experienced this: impatient, they just start programming, only to realize later that they underthought the architecture. Granted, I think the opposite is usually more true — that we &lt;em&gt;overthink&lt;/em&gt; our architectures — but that&#39;s just the pendulum swing of correction, right? A developer new to a project or a technology begins by not understanding it, then passes through the cloud of &amp;quot;everything&#39;s so complicated! The solution must be as well!&amp;quot;&lt;/p&gt;
&lt;p&gt;Ultimately, what we&#39;re all trying to do is create the simplest possible solution that&#39;s maintainable. That solution is a lot easier to arrive at when you&#39;ve spent the right amount of time narrowing down the solution space.&lt;/p&gt;
&lt;h2&gt;Constraints prune the decision tree&lt;/h2&gt;
&lt;p&gt;Every constraint cuts branches off the tree (closes off parts of the solution space). A security audit &amp;quot;speed bump&amp;quot;, missing infrastructure, a teammate still wrapping up another project. What can you do &lt;em&gt;now&lt;/em&gt; with what you&#39;ve got? Which branches do you suspect will ultimately be fruitless? How likely is each path to lead you to an eventual &amp;quot;leaf&amp;quot; that fits your specifications?&lt;/p&gt;
&lt;p&gt;Some of those are objective truths about the solution space. Others represent someone&#39;s will: a deadline chosen politically, an invented user story, or a &amp;quot;we don&#39;t do it that way here.&amp;quot; They prune just as hard, but they can be challenged. When you hit a wall, find out which kind it is before you accept it.&lt;/p&gt;
&lt;p&gt;When you&#39;re under-constrained, you don&#39;t need &lt;em&gt;more&lt;/em&gt; information so much as &lt;em&gt;fewer options&lt;/em&gt;. Shape Up&#39;s &lt;a href=&quot;https://basecamp.com/shapeup/1.2-chapter-03#setting-the-appetite&quot;&gt;appetite&lt;/a&gt; gives you that, as does the number of hours in a day. Maybe there&#39;s prior art to look at, or development principles to adhere to.&lt;/p&gt;
&lt;h2&gt;Constraints are a gift&lt;/h2&gt;
&lt;p&gt;Take a third-party provider. Choosing one up front prunes a huge part of the tree, and that&#39;s exactly why companies go all-in on a cloud platform: there&#39;s a golden path, and most of the decisions are already made. But the same choice can turn into a wall the moment the provider doesn&#39;t quite support what you need. Same constraint, different moment. This is what a proof of concept is for: a bit of knowledge up front tells you whether you&#39;re pruning toward a leaf or toward a dead end.&lt;/p&gt;
&lt;p&gt;If it&#39;s a dead end, congratulations: you just pruned a branch.&lt;/p&gt;
&lt;aside&gt;
&lt;h2&gt;Parametric memory as a space&lt;/h2&gt;
&lt;p&gt;Prompting an LLM feels similar to me: a conversation navigates the model&#39;s learned knowledge space, pruning branches every time you send a message.&lt;/p&gt;
&lt;p&gt;The model is trying to rationalize the world based on what we tell it, so if we argue with it for three or four messages before deciding &amp;quot;that code was fine after all&amp;quot;, that detour is still part of its world (imagine a textbook that argued with itself for three pages, then said &amp;quot;never mind!&amp;quot;). Models may attempt to &amp;quot;connect dots&amp;quot; that should not be connected.&lt;/p&gt;
&lt;p&gt;The fix for LLMs is to rewind the conversation: go back to before the bad constraint went in, and navigate again from there. In the real world, undoing decisions is much more costly and full of friction.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2&gt;The slipstream&lt;/h2&gt;
&lt;p&gt;Some time after a project kicks off, there&#39;s a moment where you think, &amp;quot;I see it now.&amp;quot; You&#39;ve found the constraints you need: clarity on the user journeys you need to support, a forgotten spike document from years before, the limits of the technologies you&#39;ve chosen, the relevant sharp edges of your existing codebase, and a stable business context. That&#39;s the right number of constraints, and the right time to start developing.&lt;/p&gt;
&lt;p&gt;Make a practice of checking in during execution. If you&#39;re lost, go find more constraints. If you&#39;ve hit a wall, find out whose it is.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Kevin Sookocheff, &lt;a href=&quot;https://sookocheff.com/post/architecture/innovation-with-constraints/&quot;&gt;Innovation with Constraints&lt;/a&gt;, 2019. &lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Dan Kelch, &lt;a href=&quot;https://spin.atomicobject.com/constraints-good-custom-software/&quot;&gt;Constraints Are Necessary When Building Custom Software&lt;/a&gt;, Atomic Object, 2021. &lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Mohammad Jodeh, &lt;a href=&quot;https://dev.to/mjodeh/the-hidden-cost-of-starting-development-too-early-1hgj&quot;&gt;The Hidden Cost of Starting Development Too Early&lt;/a&gt;, DEV Community. &lt;a href=&quot;https://sastraxi.com/blog/the-right-number-of-constraints/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
</feed>