<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Pablo's logbook]]></title><description><![CDATA[Thoughts, adventures and code experiences.]]></description><link>https://blog.codemanship.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1645778583573/dovJ7V-u9.png</url><title>Pablo&apos;s logbook</title><link>https://blog.codemanship.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 11:40:10 GMT</lastBuildDate><atom:link href="https://blog.codemanship.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The wrong unit]]></title><description><![CDATA[Remember when I told you all I'd swim in one lane? Well... I'm swimming in two to six lanes now. And I can report that my deploy paralysis is gone, and that my mental fatigue doesn't kick in meaningfu]]></description><link>https://blog.codemanship.dev/smaller-steps-six-ai-coding-agents</link><guid isPermaLink="true">https://blog.codemanship.dev/smaller-steps-six-ai-coding-agents</guid><category><![CDATA[AI]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[software development]]></category><category><![CDATA[Developer Tools]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 19 Aug 2026 16:11:12 GMT</pubDate><content:encoded><![CDATA[<p>Remember when I <a href="https://blog.codemanship.dev/rant-code">told you all I'd swim in one lane</a>? Well... I'm swimming in two to six lanes now. And I can report that my deploy paralysis is gone, and that my mental fatigue doesn't kick in meaningfully until the end of the day.</p>
<p>Which means either I've learned nothing at all, or something changed in between.</p>
<p>For those who missed it (or didn't want to follow a link on the first sentence of an article): I'd had five projects going at once, my nervous system was fried, I was saying yes to everything without even looking, and it took me about a month to dig myself out of the PRs that came back. I concluded that we have to do less. Well, now I can juggle two to six tasks at once.</p>
<p>The models might have gotten marginally better, but that's not what changed. I was right that I had to do less, but I had the wrong unit. The problem was how much I was asking the model to do in each stride. And by lowering that amount I can keep more things in parallel actually moving.</p>
<p>Before any of the specifics, the thing all of it is built on.</p>
<h2>So what is a stride?</h2>
<p>A stride is the smallest thing I can ask for that gets me in the right direction from green (passing tests) to green. I do have a final destination in mind, and I share that with the model, but a stride is really the smallest directionally correct step I can take. In practice that's usually one behaviour, and the test that drove it.</p>
<p>Of course, I'm building on the shoulders of giants here, and <a href="https://www.geepawhill.org/">GeePaw Hill's</a> <a href="https://www.geepawhill.org/series/many-more-much-smaller-steps/">Many More Much Smaller Steps</a> is what inspired this. Stop here and go read that, I'll wait, and it's worth it! The final trigger was a conversation we had on <a href="https://open.spotify.com/episode/4GLP0naEVVLFZ6SzkISA17?si=ui_6_arTRs-hoIIv6qmK8A">A Junior, A Senior and I</a> with Tim and Paul.</p>
<p>I'd rather bound a stride by time, the number I care about is the minutes between meaningful interactions. But the model can't feel time. If I ask it for "about ten minutes of work", it hands me a feature. It can count lines though, and 40 is a size it can both hold and check itself against.</p>
<p>Here's the shape of one. Say I want a report to leave a blank rather than a zero when there's nothing to measure yet. The test comes first:</p>
<pre><code class="language-ruby">test "reports no median for a step where nothing was paid" do
  report = EffectivenessReport.new(rows: [step_with_no_payments])

  assert_nil report.rows.first[:median_days_to_payment]
end
</code></pre>
<p>And then the change that makes it pass:</p>
<pre><code class="language-ruby">- median_days_to_payment: row["median_days_to_payment"].to_i
+ median_days_to_payment: row["median_days_to_payment"]&amp;.to_i
</code></pre>
<p>You'll notice that this stride is quite small. Not all of them are like that, but I want to stress that a stride is not necessarily a feature, it can be as small as a three line change. Most are around 40 lines, but I don't have many 200+ line diffs anymore. One stride is one commit.</p>
<p>Once the stride is done, it's up to me to decide where we're going next (although the word generator sure likes to make "suggestions").</p>
<h2>But how do you run six at once?</h2>
<p>One stride at a time is easy when you're in one lane. The reason I can be in six is that opening a lane costs me nothing.</p>
<p><code>claude-dev task &lt;task-name&gt;</code> opens a tab, creates the worktrees if they don't exist, and lays out four panes: a claude session on the left, resumed if one already exists, and shells on the two worktrees and their shared parent on the right. It's tmux inside Ghostty, and you can probably reproduce it with other tools. That's the whole thing — I'm not really in need of a helicopter view.</p>
<p>I'll usually have two to six of those running. One of them is my actual priority. The others are things that need less attention from me: migrating legacy code, migrating specs. Sometimes something small someone asked for, a graph, some quality of life thing. When a new thing pops up, I reach for <code>claude-dev task &lt;new-thing&gt;</code> and pick the first stride.</p>
<p>Once a stride is done I get a notification, and I open the tab to be greeted by the diff. On the whole I'm interacting meaningfully with each task every 5 to 10 minutes, and each interaction lasts anywhere from 30 seconds to 5 minutes.</p>
<p>I'm steering the system, and yes, that's context switching all day long. The difference is what a context costs now: 40 lines and the test that drove them, instead of a whole branch I have to rebuild in my head.</p>
<h2>The part I won't hand off</h2>
<p>This is the part I don't want to hand off. The model is bad at it.</p>
<p>When a stride lands, two things arrive with it: the diff, and a suggestion for what to do next.</p>
<p>The review pane gives me the files that changed, a map of what else in the codebase references them, and then the diff itself. That's enough to see whether it's doing what I asked, and to the standard I expect. Since it's small, I can go through it quite easily and fast, and it doesn't take much out of me. From there I either approve, or I leave a note:</p>
<pre><code class="language-diff">   def overdue?
-    due_on &lt; Date.current
+    due_on &lt; Date.current &amp;&amp; !paid?
   end
 
-  def formatted_total
-    "%.2f" % total
-  end
+  def formatted_total = format("%.2f", total)
</code></pre>
<p>Scope creep like this is the most common thing I have to push back on. The note I'd leave, in the review pane:</p>
<blockquote>
<p>the formatting change is unrelated, revert it and keep the stride to the one behaviour</p>
</blockquote>
<p>Once I close the review pane, either I tell it I left a note, or I look at suggested next strides. About two times out of three I pick one of the suggestions, but not always the "recommended". Strides are small, so if they're directionally correct that's usually good enough. If I'm not convinced I tell it to do a different stride.</p>
<h2>Throwing the conversation away</h2>
<p>While I could deploy most strides as I go (they go <em>or should go</em> from green to green), ten minutes of CI per PR is enough to make me batch. So in order to deploy I bundle two to five strides together and create a PR at that point to trigger the CI and merge if green is confirmed.</p>
<p>One problem I had with this approach is that my context got bigger and bigger, and corrupted with unimportant artifacts (pushes, side conversations, etc). One thing that unblocked this is the introduction of cycles. A cycle is just that bundle: two to five strides, one PR, one merge.</p>
<p>Once a cycle is done, I have a <code>/cycle</code> command that will:</p>
<ul>
<li><p>run <code>/handoff</code>: gotchas and lessons go to memory files, progress goes to the plan, anything a reviewer needs goes into the PR description. Then it writes a handoff. Where this task is going, how I'll know it's done, what's green and what's pushed, and one next stride.</p>
</li>
<li><p>close the claude session</p>
</li>
<li><p>and run <code>claude-dev cycle</code> which starts a new claude conversation that reads the handoff, gives me a one line status and the next stride it proposes, and waits.</p>
</li>
</ul>
<p>That buys me tokens, and it flushes two sets of temporary memory: the session's, and mine.</p>
<h2>Some numbers, because you'll ask</h2>
<p>The numbers I care about are the small ones: the median commit adds 59 lines, tests included. While I ask for 40, the model does overshoot a little. Nine out of ten are under 211. These are diffs I can parse easily, and correct on the fly.</p>
<p>Volume and PR count are probably the least interesting ways to measure "faster"... So here they are anyway.</p>
<p>Since the 1st of June, across both repos, I've made just under a thousand commits, over the 41 days I actually worked (the rest was holiday). In the same period 354 of my pull requests were merged, and at Recovr merging means shipping. So call it 24 commits and 8 deploys on a working day.</p>
<p>The number I'd most like to give you is the one I don't have: bugs in production. My honest read is that they're stable, maybe lower. That's a gut feeling and you should hold it against me.</p>
<p>With 8 merges a day, it's rare that I have a branch open for more than a couple of hours. That's the closest I've ever been to trunk based development, with all its benefits (low conflicts, code exercised sooner, etc.).</p>
<p>Which invites the obvious question: who reviews eight PRs a day? After the fact, mostly nobody. We use <a href="https://martinfowler.com/articles/ship-show-ask.html">Ship/Show/Ask</a>, and this way of working has taken full advantage of it. I review every line of code as I go (remember strides are small now) and in a trusting team formal PR reviews end up being quality theatre anyway. Ask is still there for changes that deserve another set of eyes.</p>
<p>And if you read all of this as "way more work", I've written this badly. I'm shipping sooner, not really faster.</p>
<h2>If you want to try this</h2>
<p>I'm not going to tell you to copy my setup. The tmux part is incidental and you'll want your own anyway. But if I had to rebuild this on a new machine tomorrow, there are five things I'd want back, roughly in this order.</p>
<ul>
<li><p><strong>Small steps, as an actual rule.</strong> For me that's a skill file the model loads at the start of every session: what a stride is, how big it's allowed to be, and that it stops after each one. Everything else here is plumbing. This is the part that does the work.</p>
</li>
<li><p><strong>One command to start or resume a piece of work.</strong> Mine creates the worktrees, opens the panes, and either starts a session or picks up the one that was already there. Not having to assemble that by hand is most of the difference between running one task and running six.</p>
</li>
<li><p><strong>A handoff, and a way to cut the session.</strong> Where this is going, what's green, what's pushed, and the one next step. Then throw the conversation away and start the next one from that note.</p>
</li>
<li><p><strong>The diff, in front of you, automatically.</strong> Not "go and look if you remember to". It shows up when the step is done, with the files that changed, what else references them, and the code.</p>
</li>
<li><p><strong>A way to clean up.</strong> When a task is done, something that removes the worktrees and closes the window, and refuses if anything in there is uncommitted.</p>
</li>
</ul>
<p>What all of it really buys me is permission to forget. Whatever mattered is written down by the time the session ends, so I don't have to carry it into the next one.</p>
<p>Last time I said the answer was fewer lanes. It wasn't, it was shorter strokes.</p>
]]></content:encoded></item><item><title><![CDATA[Rant Code]]></title><description><![CDATA[As any tech lead/CTO worth their salt, I have not opened my IDE to write code for a few months now. And as an aspiring blogger I have thoughts about it.
I have thoughts about LLM coding, and they migh]]></description><link>https://blog.codemanship.dev/rant-code</link><guid isPermaLink="true">https://blog.codemanship.dev/rant-code</guid><category><![CDATA[vibe coding]]></category><category><![CDATA[llm]]></category><category><![CDATA[code]]></category><category><![CDATA[rant]]></category><category><![CDATA[engineering]]></category><category><![CDATA[AI coding]]></category><category><![CDATA[AI Coding Assistant]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 17 Apr 2026 10:14:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61aa1ef08d2c527c4b5ee122/c9cd1ced-5fb3-4144-b7b9-9e1ccbd4a813.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As any tech lead/CTO worth their salt, I have not opened my IDE to write code for a few months now. And as an aspiring blogger I have thoughts about it.</p>
<p>I have thoughts about LLM coding, and they might be slightly different than other people, so buckle your seat belts dear readers and let's wade through some slop together.</p>
<h2>LLMs as a general tool</h2>
<p>LLMs are a chatbot, they do chatbot things, and when using them you must remember that they strip away most of the intention of whatever you wrote.</p>
<p>Even though most people try to convince me that the written discourse on the internet in general (and LinkedIn in particular) was already truly uniform, I am quite certain that:</p>
<ul>
<li><p>It was not.</p>
</li>
<li><p>You did not use to get dumber reading it.</p>
</li>
</ul>
<p>And writing text is supposed to be the thing they excel at!</p>
<p>Seeing the subpar text they produce should make anyone wary of using them for any serious purpose.</p>
<p>A few newsletters I read quite avidly in the past have become intolerable as an LLM takes a sentence that might be interesting and turns it into five paragraphs.</p>
<p>While it might not be yet capable of turning a blog post into a book (we were quite good at that before), it certainly can turn a sentence into a (bad) blog post.</p>
<p>And all that with all the convenience that fast food has. It's fast, it's 'repeatable' and in a world where volume already spoke louder than quality, it is drowning any original thought that might have emerged before.</p>
<p>But it is impressive, and it plays very well to our laziness. I have a podcast, and I don't like marketing, of course I have been tempted more than once to tell the LLM to write some copy for me.</p>
<h2>Abstracting cost from output</h2>
<p>One thing I must give kudos for is that the abstraction between the cost and the output is marvelously achieved.</p>
<p>In it's more utilitarian view, we don't know (and don't think about) how many tokens are in our subscription, not how much money a token costs, nor what a token is, not how much energy a given token might consume. We don't even know how many tokens any given request will consume.</p>
<p>The above makes it so we don't know if there is a viable business on top of LLMs as a general tool. It might be worth producing an ungodly amount of slop at 200 a month, but there is a number where that is not true. And we don't know what the final price will be.</p>
<p>We don't know either what the energy consumption of all of this "work" is other than "high". I believe in part it is due to it being a complicated subject, and in part that fear is a good marketing tool, for example saying we might have blackouts due to LLMs or that we will have to open a nuclear power plant to power a data center sells.</p>
<p>But there is a more insidious cost being abstracted away, and that is attention, and while attention might be all you need, attention is being destroyed.</p>
<p>First and foremost is the fact that as soon as it becomes apparent that something was spewed out by the machine, my eyes (and I suspect yours) immediately gloss over the rest of the content.</p>
<p>Not less important, by clicking the metaphorical "make longer" button, your idea gets diluted into "it's not this, it's that" and other weird sentence constructions.</p>
<p>Finally, you are probably not paying attention to your "writing" anymore, after all the computers never lie, or never used to lie, and you told it to turn your idea into long form writing "using your voice". How can you be sure your voice is not eerily close to everyone else's voice?</p>
<h2>They can't write, can they do something else?</h2>
<p>Although the hype machine wants to convince us and sell us today on what LLMs might be able to do in the future, I do believe there are some things it does reasonably well today, at today's subsidized price.</p>
<p>One of the things it does reasonably well is the opposite of 'make this longer'. It is capable of ingesting a fairly large amount of information, in a reasonable time and give you a watered down but mostly sufficient summary. As long as precision is not something you need from it.</p>
<p>You do need to be aware that it had been trained mostly on internet text, so it "wants to give you" actionable advice, and strategy. And it is easy to be fooled into thinking it can think and actually provide advice and analysis.</p>
<p>It also can code, mostly...</p>
<h2>But I can code faster now!</h2>
<p>Congratulations, after 750 words you finally are at the part that reveals my hypocrisy and that probably interests you more.</p>
<p>I have not opened my IDE to type code in a while. And I think I am mostly faster, but there is a lot to unpack here.</p>
<h3>I can give a prompt to the LLM and it builds an app for me</h3>
<p>No you can't. If you are not a software engineer, and don't understand the code it is producing you might be able to fight it until it builds something really simple thst mostly works. But you are most probably building a website, that website is pretty simple and you were overestimating the complexity of what you wanted to build.</p>
<p>That is not to say that it is not useful, and it might allow you to create some bespoke webapps for really niche problems, but you can't vibe code your way to solving a problem at scale. Since I can't prove a negative, let's say that with the miriad of people vibe coding the next unicorn, one would expect at least one or two to get some traction.</p>
<h3>But my whole organization can now create a PR from a slack message, we are all 10x engineers!</h3>
<p>No you are not. But thanks for telling me, I'll make sure to avoid your software for a while.</p>
<p>In the worst of cases, you are creating an intolerable amount of bugs and pushing unreviewed and unintentional code out into the wild.</p>
<p>In the best of cases, the people that know best how to structure and tend to your code are now stuck babysitting a codebase getting filled with half baked ideas.</p>
<p>Code is quite meaningless, but I will presume you have some sort of software you are trying to sell. The functionalities you do not build into it are as important as the functionalities you do build into it. Every piece of functionality you write is a desire path that you are paving other, and if you don't put intention and attention into it, you will end up paving the whole field, getting your users lost in what they try to accomplish and trying to plug holes in a surface area that is untenable.</p>
<h3>But it gave me code and now I can scrape recipes of the internet and repurpose them for SEO farming</h3>
<p>Yes, I am quite sure it did. But if you have followed along... At what cost? And for what?</p>
<h2>But I am a software engineer, and I don't use my IDE anymore! And I am faster?</h2>
<p>I am in the same case than you, and I do think you can be significantly faster when assisted by an LLM for coding, but I have feelings again. The rant continues!</p>
<h3>Faster?</h3>
<p>Faster is really hard to pin down, I know it might seem disingenuous but what do you mean by faster?</p>
<ol>
<li><p>Do you produce more code by volume?</p>
</li>
<li><p>Do you have a shorter cycle time?</p>
</li>
<li><p>Are you creating more PRs?</p>
</li>
<li><p>Do you deploy more frequently?</p>
</li>
<li><p>Are you adding more functionality more frequently?</p>
</li>
<li><p>Are you adding functionality that you could not before?</p>
</li>
<li><p>Are you seeing a smaller volume of bugs in production?</p>
</li>
</ol>
<p>All of these are ways to measure "faster" and I would contend that some of them are more interesting than others. Especially Volume and PRs seem to be quite worthless to me.</p>
<p>If I submit myself to that questionnaire today, I would answer:</p>
<ol>
<li><p>Do you produce more code by volume?</p>
<ol>
<li>Yes</li>
</ol>
</li>
<li><p>Do you have a shorter cycle time?</p>
<ol>
<li>Yes</li>
</ol>
</li>
<li><p>Are you creating more PRs?</p>
<ol>
<li>I was, I stopped</li>
</ol>
</li>
<li><p>Do you deploy more frequently?</p>
<ol>
<li>Yes</li>
</ol>
</li>
<li><p>Are you adding more functionality more frequently?</p>
<ol>
<li>Somewhat</li>
</ol>
</li>
<li><p>Are you adding functionality that you could not before?</p>
<ol>
<li>Yes, at least considering things that where not realistic before</li>
</ol>
</li>
<li><p>Are you seeing a smaller volume of bugs in production?</p>
<ol>
<li>Mostly yes</li>
</ol>
</li>
</ol>
<p>So I do think I am faster now, but I would not say I am twice as fast as before. There are also some systemic issues that must be tackled in order to be faster.</p>
<p>Asynchronous Code Review, for the despair of many, are a default in our industry, and while we can create a higher volume of code and PRs, we are transferring a bottleneck downstream. And it is a bottleneck that creates a lot of problems, from context switching, to conflicts creeping in the different branches.</p>
<h3>You will do too much</h3>
<p>If you decided to start doing your engineering from a CLI instead of an IDE, I believe you will have gone through this phase.</p>
<blockquote>
<p>Hey! I want to add the possibility to link slack and my app to notify people of changes</p>
<blockquote>
<p>Chatbot creates a worktree and churns along...</p>
</blockquote>
<p>Hey! I also want to be able to login by taking a picture of my face</p>
<blockquote>
<p>Chatbot creates another worktree (some times in the correct place) and churns along...</p>
</blockquote>
<p>Hey! Actually I also want to add fingerprints so people can login when they pick up their phone</p>
<blockquote>
<p>Chatbot happily tells you yes, creates a worktree and churns along...</p>
</blockquote>
</blockquote>
<p>Of course all of this goes in parallel and your nervous system is fried and overworked so you are saying yes to everything without even looking. But you do remember to tell it to review itself from time to time</p>
<p>A few hours or days after you have several PRs, probably massive, they read like rants written in code and you need to review them all.</p>
<p>It took me a month to recover from that and actually manage to merge the PRs (at least those I did not discard). I hope this does not sound familiar, but I am quite certain it will.</p>
<h3>Reining it in</h3>
<p>So, we have to do less, it is not tenable to have 5 projects in parallel. It is a lesson apparently I (and I suspect you) needed to learn again. I am still faster, granted, but now I only swim in one lane instead of trying to encompass the whole pool at once.</p>
<p>I also have realized that we need to contain the Rants it produces in code. We need to constrain it so that it does not spew forth a whole app every time you tipe something in your IDE.</p>
<p><a href="https://github.com/citypaul/.dotfiles/blob/main/README.md">Paul's dotfiles</a> are a great starting point when you want to rein it in, they do shorten cycle time* (*If you are doing TBD), I am still faster, and I pay more attention.</p>
<p>I do feel like I have to babysit the LLM in very predictable ways.</p>
<h3>Feedback loops or lack thereoff</h3>
<p>One of the reasons I believe LLMs are performing adequately for software engineering is that (most) of the industry has accepted the need for short-ish feedback loops, from Tests (ideally first) to static checkers, going through CI.</p>
<p>And that harnesses and helps the LLM iterate. But some of them are 'hard feedback' and some of them are judgement calls.</p>
<p>LLMs are really good at following hard feedback, they will churn along (most times) until the test goes green, or the static checks pass.</p>
<p>They are really bad at making what I am calling judgement calls though.</p>
<p>A symptom of that is their constant refusal of doing the Refactor part or Red - Green - Refactor. And I believe it is because they don't have a hard gate. Refactoring or not is a judgement call, and so is loading skills dynamically.</p>
<p>As such, you will have to constantly babysit the LLM to do those tasks, and absolutely cannot trust that it will do them. No matter how many times you have written that it should!</p>
<p>In the same vein, you cannot believe it when it says it has reviewed it's output, it does not have the capacity to think critically, and reviews are judgement calls.</p>
<p>Finally, the LLM can give you a mostly correct assessment of a situation, but it will again, and again make a 'recommendation'. And that biases your thinking. LLMs are not fit to make recomendations and when having them sumarize the situation of a part of a codebase or a work in progress, you must remember to be at the drivers wheel.</p>
<p>For very long we have been trained to 'click' yes when prompted, your default position when using an LLM assistant should be 'no' and think through why it should be yes. This is made harder by the fact that it is not trivial to distinguish when the LLM is in need of a decision (e.g. should this function be split in two) or is just not able to perform a decisionless task without explicit agreement from you (e.g. running the tests)</p>
<p>If we disregard (and it is a big disregard) the economics of LLMs, for them to work as well as they should we need to create as many hard gates around them as we can, they are relentless at making something go from red to green, and I do not believe we can base ourselves solely on the tests for that part.</p>
<p>But in the meantime,..</p>
<h3>Old is new again</h3>
<p>There are practices that help in creating smaller chunks of work and in keeping feedback loops short, hard and manageable.</p>
<p>It seems a lot of people are rediscovering them and renaming them (with the age old fight of Agile vs Waterfall getting a new battlefield). But we have known them for quite a while.</p>
<ul>
<li><p>Strive to have tests for the LLM to but its head against (and review those thoroughly if the LLM writes them).</p>
</li>
<li><p>Test behavior rather than implementation.</p>
</li>
<li><p>Have every 'unit' of code do one job and one job only.</p>
</li>
<li><p>Reduce conascence throughout your app</p>
</li>
<li><p>Do not rely on asynchronous code reviews</p>
</li>
<li><p>Work in small chunks that go from green to green and can be deployed independently</p>
</li>
</ul>
<p>Most of these principles and practices have been extensively written about. Notably I would recommend you read at the very least</p>
<ul>
<li><p>TDD by example (Kent Beck)</p>
</li>
<li><p><a href="https://agilealliance.org/resources/experience-reports/mob-programming-agile2014/">The original article on Software teaming</a> by Woody Zuil</p>
</li>
<li><p>eXtreme Programming (Kent Beck)</p>
</li>
<li><p>Refactoring (Kent Beck and Martin Fowler)</p>
</li>
<li><p><a href="https://connascence.io/">Conascence</a></p>
</li>
</ul>
<p>And watch:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=EZ05e7EMOLM">TDD where it all went wrong</a> by Ian Cooper.</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Flow State]]></title><description><![CDATA[It’s nine AM, my work begins,
A clear direction, where to go,
I concentrate, I take it all in,
And so I start, without a stop.
-
It's ten AM, no time to breathe,
A single focus, reach my goal,
And so I write, it is a breeze,
My laptop, me, we are one...]]></description><link>https://blog.codemanship.dev/flow-state</link><guid isPermaLink="true">https://blog.codemanship.dev/flow-state</guid><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 26 Nov 2025 12:45:37 GMT</pubDate><content:encoded><![CDATA[<p>It’s nine AM, my work begins,</p>
<p>A clear direction, where to go,</p>
<p>I concentrate, I take it all in,</p>
<p>And so I start, without a stop.</p>
<p>-</p>
<p>It's ten AM, no time to breathe,</p>
<p>A single focus, reach my goal,</p>
<p>And so I write, it is a breeze,</p>
<p>My laptop, me, we are one.</p>
<p>-</p>
<p>In my head variables fly,</p>
<p>Functions appear out of thin air,</p>
<p>All the fluff is just gone by,</p>
<p>All my issues disappear,</p>
<p>Just look ahead, I am almost there.</p>
<p>What is that? A fly?</p>
<p>-</p>
<p>Disaster struck, where is my flow?</p>
<p>What was I doing, where am I?</p>
<p>All the variables, are they gone?</p>
<p>What was I doing, where am I?</p>
<p>-</p>
<p>The fly flew on, where is my flow?</p>
<p>What was I doing, where am I?</p>
<p>I have a test, somewhere I think?</p>
<p>What was I doing, where am I?</p>
<p>-</p>
<p>The clean begins,</p>
<p>All those small things,</p>
<p>That felt redundant,</p>
<p>Tests, refactor, clean.</p>
<p>-</p>
<p>They keep me grounded,</p>
<p>Like an anchor,</p>
<p>They get me back in.</p>
]]></content:encoded></item><item><title><![CDATA[My code is a liar]]></title><description><![CDATA[My code is a liar!
And yet, it's never wrong,
It does give quick feedback,
And most of it for naught.
-
My code is impatient!
And yet, often impuntual,
For decisions long forgotten,
It gives me painful stabs.
-
My code is a bad teacher!
And yet, it t...]]></description><link>https://blog.codemanship.dev/my-code-is-a-liar</link><guid isPermaLink="true">https://blog.codemanship.dev/my-code-is-a-liar</guid><category><![CDATA[coding]]></category><category><![CDATA[Poetry]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Thu, 20 Nov 2025 07:22:25 GMT</pubDate><content:encoded><![CDATA[<p>My code is a liar!</p>
<p>And yet, it's never wrong,</p>
<p>It does give quick feedback,</p>
<p>And most of it for naught.</p>
<p>-</p>
<p>My code is impatient!</p>
<p>And yet, often impuntual,</p>
<p>For decisions long forgotten,</p>
<p>It gives me painful stabs.</p>
<p>-</p>
<p>My code is a bad teacher!</p>
<p>And yet, it teaches well,</p>
<p>On one single subject,</p>
<p>But, for that one, it excels.</p>
<p>-</p>
<p>And yet, I've been promised,</p>
<p>There is a golden path,</p>
<p>It sure would be great,</p>
<p>If all of them were right!</p>
]]></content:encoded></item><item><title><![CDATA[Separating the important from the urgent]]></title><description><![CDATA[At any given point there is only one most important thing you should be doing.
Sadly, that seldom coincides with the most urgent.
A solution to that is to carve a space dedicated to the important rather than the urgent.
At Recovr we realized a few mo...]]></description><link>https://blog.codemanship.dev/separating-the-important-from-the-urgent</link><guid isPermaLink="true">https://blog.codemanship.dev/separating-the-important-from-the-urgent</guid><category><![CDATA[agile]]></category><category><![CDATA[development]]></category><category><![CDATA[team]]></category><category><![CDATA[workflow]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Mon, 08 Sep 2025 11:56:23 GMT</pubDate><content:encoded><![CDATA[<p>At any given point there is only one most important thing you should be doing.</p>
<p>Sadly, that seldom coincides with the most urgent.</p>
<p>A solution to that is to carve a space dedicated to the important rather than the urgent.</p>
<p>At Recovr we realized a few months ago that we were consumed by the urgent.</p>
<p>Our solution has been to optimize for the flow of our main priority. We decide on a main priority when the previous one is done, and there is one person responsible for its continuous flow.</p>
<p>This has allowed us three things:</p>
<p>1- the most important feature is always visible and prioritized.</p>
<p>2- the most important feature is in constant movement.</p>
<p>3- we have (surprisingly?) more space for the urgent.</p>
<p>These don't just happen by magic, but rather a combination of factors:</p>
<ul>
<li><p>The visibility of the advance of the main priority ‘buys’ a lot of goodwill from the rest of the teams.</p>
</li>
<li><p>Since the people that are not on the main priority can be interrupted, it's easier to tackle ad hoc emergencies</p>
</li>
<li><p>The people working on the main priority fluctuate, this allows us to expand or contract capacity for ‘non main priority’ work.</p>
</li>
</ul>
<p>Our rules for the main priority are quite simple:</p>
<ul>
<li><p>A main priority must have a DoR (Définition if Ready) with at least a MoSCoW priorisation.</p>
</li>
<li><p>There is one person responsible for the main priority, and they can ‘recruit’ anyone from the team they need to make the priority move forward.</p>
</li>
<li><p>The main priority takes precedence above other things, it cannot remain sitting in a queue.</p>
</li>
<li><p>The person responsible decides how the work is shared/performed and communicates with the rest of the company.</p>
</li>
</ul>
<p>We have noticed that the other teams are quite happy with this arrangement as it increases both flexibility to tackle urgent things and visibility on our next most important feature.</p>
<p>If you are drowning in urgent things, and have trouble advancing important work, I recommend you to try and set up a main priority.</p>
]]></content:encoded></item><item><title><![CDATA[Agile in the age of Scrum]]></title><description><![CDATA[[Edit, 1st of September 2025: Philippe I'll pointed out to me that the artifacts I attribute to scrum have been addressed or removed in the latest scrum versions.]
When you tell someone that you work in an agile team, or that you want to be more agil...]]></description><link>https://blog.codemanship.dev/agile-in-the-age-of-scrum</link><guid isPermaLink="true">https://blog.codemanship.dev/agile-in-the-age-of-scrum</guid><category><![CDATA[agile]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 27 Aug 2025 12:10:50 GMT</pubDate><content:encoded><![CDATA[<p>[Edit, 1st of September 2025: <a target="_blank" href="https://www.linkedin.com/in/philippevaneerdenbrugghe?utm_source=share&amp;utm_campaign=share_via&amp;utm_content=profile&amp;utm_medium=android_app">Philippe</a> I'll pointed out to me that the artifacts I attribute to scrum have been addressed or removed in the latest scrum versions.]</p>
<p>When you tell someone that you work in an agile team, or that you want to be more agile, chances are that they hear:</p>
<blockquote>
<p>We do Scrum-like things</p>
</blockquote>
<p>That is good and bad.</p>
<p>On one hand, most companies will have some inflexible rituals, applied without thought. I am looking at you stand up!</p>
<p>On the other, at least they changed some things. (hopefully in a deliberate manner).</p>
<p>While your team’s way of working and personalities will probably not be uncommon, their combination and circumstances are probably unique.</p>
<p>As such, following a prescribed practice, static in time will not optimize for most important things.</p>
<h2 id="heading-what-is-important-in-software-teams">What is important in software teams:</h2>
<p>This is an opinion, but I hope it is a shared one.</p>
<p>Priorities that should be shared among all or most software teams are, in order:</p>
<ul>
<li><p>Producing software that solves our user's needs. (And makes enough money)</p>
</li>
<li><p>Producing software that has few, if not none, defects.</p>
</li>
<li><p>Producing software fast.</p>
</li>
<li><p>Being able to adapt the software to changing needs.</p>
</li>
<li><p>Being able to sustain it indefinitely.</p>
</li>
</ul>
<p>There are other sub priorities, but I think they are encompassed by the above ones.</p>
<p>And your team might have other specific priorities as well.</p>
<h2 id="heading-how-to-address-these-priorities">How to address these priorities:</h2>
<p>I understand it would be quite ironic if I were to prescribe a list of practices here that you <em>must</em> do after having complained at people following prescribed practices.</p>
<p>But people have been thinking about these problems for a while, good places to start would be to look towards Lean, eXtreme Programming, DevOps and the DORA report</p>
<p>What I would say is that to address these priorities you must be willing to adapt, to change how you work regularly, in small increments and with buy in from the team.</p>
<p>Something that worked <em>for us</em> is to have frequent retrospectives, that might work for you. But in any case, you must be able to change when something is not working.</p>
<h2 id="heading-doesnt-scrum-address-that">Doesn’t Scrum address that?</h2>
<p>[The practices I describe below have been addressed in the latest versions of Scrum. I will leave the original version below annotated with square brackets, as a self reminder that jargon matters and I should research things better. I invite you to see the scrum guide 2020 here: https://scrumguides.org/scrum-guide.html before continuing.]</p>
<p>I am not a Scrum expert. But everywhere I worked at, Scrum artifacts have existed. They might be a good starting point, but I don’t see them as an end goal.</p>
<p>The most common ones I have seen are:</p>
<ul>
<li><p>Some type of estimation/betting table [The Sprint Planning]</p>
</li>
<li><p>A team cycle of two weeks (I refuse to use sprint) [a maximum of one month, but static in size]</p>
</li>
<li><p>Daily Stand Ups, what you did, what you will do, what is blocking. [No mention of that format in the guide]</p>
</li>
<li><p>Some type of cycle closing/starting [sprint closing and sprint retrospective]</p>
</li>
</ul>
<p>These solve specific issues, and might be worth keeping, or changing, or removing depending on your circumstances:</p>
<h3 id="heading-estimationsbetting-table">Estimations/betting table</h3>
<p>These usually are there to avoid scope creep, we agree on what we are going to do for the next two weeks, that way we can say no to those other things that want doing.</p>
<p>They are a good starting point, it at least gets you to establish some priorities.</p>
<p>In my <em>limited</em> experience they tend to show their limits quite fast. Bugs want to be debugged, our estimations/guesses are incorrect, etc.</p>
<h3 id="heading-two-week-cycles-with-a-closestart">Two week cycles with a close/start</h3>
<p>The idea here is that you at least will have things to show after two weeks. To be fair, it’s at least better than longer periods. But I do tend to see a mad dash at the end to fit to the schedule. And things don’t always fit a two week schedule.</p>
<p>At least it gets people talking twice a week, as they are usually accompanied of some sort of retrospective.</p>
<h3 id="heading-daily-stand-ups">Daily Stand Ups</h3>
<p>I mean, sure, they might make you talk to your team?</p>
<p>It’s better than nothing, I guess?</p>
<p>They tend to go to a state where they feel repetitive because they are a chore and most people wont read from other people.</p>
<p>[As described by the scrum guide, they feel somewhat more useful]</p>
<h3 id="heading-so-no-scrum">So, no Scrum?</h3>
<p>I don’t have too much of a beef with Scrum per se. I think it is a fine starting point. For some teams it might get them closer to where they need to be.</p>
<p>But, it is often implemented rigidly, when you want to teach someone you teach practices, as it’s harder to teach principles. So, people learn the practices, and they stay, they loose meaning, they start impeding further progress.</p>
<p>Start with Scrum if you want, just don’t stay there. (Or start with XP, or with watever, as long as you keep adapting)</p>
<h2 id="heading-so-how-can-i-do-agile-then">So, how can I do Agile then?</h2>
<p>[While I ‘pick on’ Scrum here, my critique can be applied to any framework you treat as if it was ‘the final form'. Most frameworks exist to address issues that are more or less common, but the work your team does and the way they work is unique. Treat them as a starting point and adapt to your circumstances]</p>
<p>You can’t <em>do</em> agile. But you can <em>be</em> agile.</p>
<p>Agile is a lot of things, it's vague for a reason. But it's about having the right priorities and changing the way you work to address them.</p>
<p>Pick a starting point, see if it gets you closer to the goals stated above and change and tweak as needed to adapt to today's circumstances.</p>
]]></content:encoded></item><item><title><![CDATA[I found and AI plugin that works]]></title><description><![CDATA[DISCLAIMER: Thins post is not sponsored, just sharing my experience.
I found an AI/LLM plugin that finally works for me. For you? Your Mileage Might Vary.
The tool is Augment.
I've been trying out Code Assistants, and getting extremely frustrated by ...]]></description><link>https://blog.codemanship.dev/i-found-and-ai-plugin-that-works</link><guid isPermaLink="true">https://blog.codemanship.dev/i-found-and-ai-plugin-that-works</guid><category><![CDATA[AI]]></category><category><![CDATA[copilot]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Mon, 19 May 2025 17:59:38 GMT</pubDate><content:encoded><![CDATA[<p>DISCLAIMER: Thins post is not sponsored, just sharing my experience.</p>
<p>I found an AI/LLM plugin that finally works <em>for me</em>. For you? Your Mileage Might Vary.</p>
<p>The tool is <a target="_blank" href="https://www.augmentcode.com/">Augment</a>.</p>
<p>I've been trying out Code Assistants, and getting extremely frustrated by them. They basically worked as a <em>better</em> autocomplete, but all chat functions got real frustrating, real quick.</p>
<p>The promise I was sold was that it could help me co-create code. And <em>for me</em> that was not a better autocomplete that breaks your code if you give it some free reign.</p>
<p>And <em>for me</em> up to this point, that was the experience. Clunky, breaking, extremely over eager and fundamentally dumb.</p>
<p>The hard part is not writing the code. And if “the help” is breaking things and adding work for me… Pablo not happy.</p>
<p>But, is Augment fundamentally different? For me, yes, in one central way:</p>
<p>It can run the tests! Iteratively!</p>
<p>The amount of ways in which it can break things is not only severely reduced. More importantly, the amount of times I have to tell it ‘you are wrong, you useless thing’ is severely reduced.</p>
<p>Now, I am sure the folks building it have made things so that <em>in general</em> it's better.</p>
<p>But the true game changer is being able to run tests.</p>
<p>It unlocks <em>for me</em> a speed in doing things that I didn't have before, I am still in the driver's wheel. And when I actually let go too much… I instantly regret it. But, I have, finally, a somewhat competent assistant that can do the tasks that ‘annoy’ me most: writing trivial code.</p>
<p>Granted, you need a really tight leash, it will try to do too much, a coworker was surprised that I had to tell it to only change X file every time, until I forgot and he changed 5 files at once.</p>
<p>But, it works good enough that <em>for now</em> it is a good experience.</p>
<p>A last forewarning I will leave you with. What our elders described as great ways of working: XP, always green specs, test first, small increments, etc. Are doubly true with this assistant. The steps might be a bit bigger, in part because the machine is overeager, in part because it allows for bigger ‘jumps’. But the principles still apply.</p>
]]></content:encoded></item><item><title><![CDATA[Potential is not fixed]]></title><description><![CDATA[Maybe it sounds a little harsh, but a programmer who's been working professionally for five years has likely already revealed their potential. What you're going to get is roughly what you see. That doesn't mean that people can't get better after that...]]></description><link>https://blog.codemanship.dev/potential-is-not-fixed</link><guid isPermaLink="true">https://blog.codemanship.dev/potential-is-not-fixed</guid><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 11 Apr 2025 13:22:15 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>Maybe it sounds a little harsh, but a programmer who's been working professionally for five years has likely already revealed their potential. What you're going to get is roughly what you see. That doesn't mean that people can't get better after that, but it means that the trajectory by which they improve has already been plotted.</p>
</blockquote>
<p>The above quote and its <a target="_blank" href="https://world.hey.com/dhh/why-we-won-t-hire-a-junior-with-five-years-of-experience-0a548994">corresponding article</a> from DHH, has instilled in me quite a reaction.</p>
<p>I'll start with the most obvious:</p>
<h1 id="heading-knowledge-work-is-not-a-sport">knowledge work is not a sport</h1>
<p>It is especially not a US sport.</p>
<p>I make the above distinction since:</p>
<ol>
<li><p>US sport associations have some convoluted ways you might get to play in one of their teams</p>
</li>
<li><p>He uses US sport examples in the article.</p>
</li>
</ol>
<h2 id="heading-i-want-to-get-in-the-nba">I want to get in the NBA</h2>
<p>I will use the NBA as an example, since it is the US sport association I know best, but they all have a similar ‘story’.</p>
<p>If you want to have a career in the NBA, there is quite a straight path you must take*:</p>
<ul>
<li><p>Be good in school, best of the best.</p>
</li>
<li><p>Get selected for college, be good, best of the best.</p>
</li>
<li><p>At some point during college declare yourself eligible for the draft (teams will pick as in the schoolyard, in turns**)</p>
</li>
<li><p>Get chosen by a team, the ‘better’ you are the ‘worst’ the team that picks you is.</p>
</li>
<li><p>Play about 15 years</p>
</li>
<li><p>Retire.</p>
</li>
</ul>
<p>*: you could also play ‘overseas’, Europe or Asia prior to being drafted.</p>
<p>**: teams are assigned an order of picks and will each pick a couple young players.</p>
<h2 id="heading-why-the-teams-select-players-young">Why the teams select players young.</h2>
<p>There are a few incentives on ‘fighting’ for young players in structures such as the NBA.</p>
<p>First and foremost, that is when you are sure you can get access to talent you would not have access otherwise (and keep in mind that the young players have no say in the team they’ll play for)</p>
<p>You get talent at a huge discount. Contrary to what is stated in the article, you don't pay a premium for ‘potential’, you get a potential discount for skills.</p>
<p>A players physical attributes will decline with age, with peaks being reached around 28-29 years of age. That is about 6-7 years after most enter the league.</p>
<h1 id="heading-the-differences">The differences</h1>
<p>I would expect that if you are working in a knowledge field, you can see the differences with a sport league, but please allow me to state the obvious:</p>
<h2 id="heading-your-career-will-be-longer">Your career will be longer</h2>
<p>You will not have ‘only’ a ~15 year career, more typically, your career will last for 40 years, if you ‘loose’ 5 years, you have not ‘lost’ comparatively as big a proportion.</p>
<h2 id="heading-you-skills-dont-decline-as-sharply">You skills don’t decline as sharply</h2>
<p>You don’t depend on your physical attributes for knowledge work, and while cognitive ability might decline <em>some</em> with age. The decline is not as sharp as with physical attributes</p>
<h2 id="heading-you-have-more-time-for-circumstances-to-change">You have more time for circumstances to change</h2>
<p>While now might not be a good time for you to ‘grow’ or ‘learn’. Life does change, and circumstances do as well.</p>
<h1 id="heading-so-how-potential">So, how potential?</h1>
<p>Potential (understood as ‘growing speed’) is derived from curiosity and opportunity. So, if you want people to grow with you, try to hire curious people and give them opportunity to learn. At the end of the day, you will be paying people for their skills today, and contrary to what happens in sport, they are not tied to you so if your compensation stops being fair for their skill… Well, either you’ll renegotiate or they will leave.</p>
]]></content:encoded></item><item><title><![CDATA[The planning trap]]></title><description><![CDATA[Detailed plans, precise specifications, exact destinations are a trap.
They feel good, they are fun to imagine, they make us feel very smart.
They give us a sense of beginning and a sense of ending.
They make us think that we are future proof and tha...]]></description><link>https://blog.codemanship.dev/the-planning-trap</link><guid isPermaLink="true">https://blog.codemanship.dev/the-planning-trap</guid><category><![CDATA[agile]]></category><category><![CDATA[planning]]></category><category><![CDATA[development]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 28 Feb 2025 11:44:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/Z2yXfJEu5rI/upload/6437ef666fcb7b805cce380f89321bf3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Detailed plans, precise specifications, exact destinations are a trap.</p>
<p>They feel good, they are fun to imagine, they make us feel very smart.</p>
<p>They give us a sense of beginning and a sense of ending.</p>
<p>They make us think that we are future proof and that, since we found the good solution we won't need to change anything.</p>
<p>But:</p>
<p>They delay the moment where we add value to our software.</p>
<p>They force us into a path where we have zero to no value until the whole plan is executed.</p>
<p>The highest value is added at the end of the line, if not, we could forego most of the plan.</p>
<p>The solution, and our code will tend to be more brittle.</p>
<p>We will still have to change it once people start using it.</p>
<p>So:</p>
<p>Don't pick an exact destination and break it down into small chunks.</p>
<p>Pick a problem, ask yourself how you could solve it in a day.</p>
<p>There might be another problem later, do the same.</p>
<p>Add value fast.</p>
]]></content:encoded></item><item><title><![CDATA[Software Teaming]]></title><description><![CDATA[What is it?
Software teaming commonly refers to the practice of having a full multifunctional team work on one feature at a time on the same machine. It is also known as Ensemble Programming or Mob Programming.
Why do it? - Motivation from a team lea...]]></description><link>https://blog.codemanship.dev/software-teaming</link><guid isPermaLink="true">https://blog.codemanship.dev/software-teaming</guid><category><![CDATA[software teaming]]></category><category><![CDATA[mob-programming]]></category><category><![CDATA[teamwork]]></category><category><![CDATA[software development]]></category><category><![CDATA[agile]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 21 Feb 2025 15:34:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/t4qI2IDcL5s/upload/ad3e285f50904dd5f6385859e7e8ac7e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-it"><strong>What is it?</strong></h2>
<p><a target="_blank" href="https://softwareteaming.com/">Software teaming</a> commonly refers to the practice of having a full multifunctional team work on one feature at a time on the same machine. It is also known as Ensemble Programming or Mob Programming.</p>
<h2 id="heading-why-do-it-motivation-from-a-team-lead-perspective">Why do it? - Motivation from a team lead perspective</h2>
<p>In order to understand why I pushed my team to experiment and try Software Teaming, I think it would be useful to understand the challenges we are facing when working asynchronously from my perspective.</p>
<p>Our team is composed of 5 people separated in 2 Front End Engineers and 3 Back End Engineers. A typical feature will include a Front End Ticket and a Back End Ticket.</p>
<p>This leads to a state where:</p>
<ul>
<li><p>Rework can and does happen frequently.</p>
</li>
<li><p>There is a layer of coordination that needs to be added between the Front End and Back End Engineers.</p>
</li>
<li><p>Switching costs are high.</p>
</li>
<li><p>The waiting time for each feature is high.</p>
</li>
</ul>
<p>Having the team perform as a team instead of a collection of individuals solves most of this issues, but also presents with an opportunity for other benefits, namely:</p>
<ul>
<li><p>A reduction of the <a target="_blank" href="https://en.m.wikipedia.org/wiki/Bus_factor">bus factor</a>.</p>
</li>
<li><p>A potential to have everyone expand their knowledge of the whole stack.</p>
</li>
<li><p>A higher overall level of <a target="_blank" href="https://blog.codemanship.dev/so-we-tried-ensemble-programming">care</a> on our code.</p>
</li>
<li><p>A more rounded perspective of our solutions.</p>
</li>
</ul>
<h2 id="heading-challenges-you-might-face-if-you-decide-to-try">Challenges you might face if you decide to try</h2>
<p>While I paint what I hope is a pretty appealing picture above, if you want to try Software Teaming withing your organization, you should be aware of the challenges you might face.</p>
<p>First and foremost, it is a hard sell. You will be optimizing for throughput rather than output, and it goes against the traditional way of measuring performance.</p>
<p>It goes against an ingrained perception of the developer as the ‘sole genius' of a development. Individual progress might feel slower, as no member is fully responsable of the code, but the team is.</p>
<p>It can be more tiring to work as part of a group, as you don't fully control the rythm, and the level of social interaction is higher.</p>
<p>Finally, there might be a feeling of loss of control and loss of agency. As, while working in a group you will, most times, influence rather than decide. For the same reason, you'll have to be mindful of everyone being able to influence the group.</p>
<h2 id="heading-in-practice">In Practice</h2>
<p>The theory is all well and good, but what did it mean in practice?</p>
<h3 id="heading-our-setup">Our setup</h3>
<p>We, the five engineers worked as a tem for three days a week for three weeks. We did so in person, as we tried to do one day in remote but our remote setup made it harder.</p>
<p>We had one screen, one keyboard and one computer for the team on the ‘teaming’ days, and we roughly did turns of 20 minutes each as typists.</p>
<p>The ‘mandatory’ teaming hours were from 10 to 12 and from 14 to 16, but in practice we did whole days of mobbing.</p>
<h3 id="heading-pain-points">Pain points</h3>
<p>Our setup was not ideal, as we used a team members computer and screen, as such they were locked in the mob wether they ‘felt like it' or not.</p>
<p>The skill separation between Front End Engineers and Back End Engineers made some parts a bit painful when a lot of the focus was only on the backend or only on the frontend.</p>
<p>There was a sentiment of isolation from the rest of the company, and ‘secondary’ things were harder to keep track of.</p>
<p>There was a sentiment of ‘not being the most conductive setup to learning'.</p>
<h3 id="heading-gains">Gains</h3>
<p>The feature was in constant progress, even when not the whole team was there, wether due to emergencies or illness.</p>
<p>There was no waiting time, the code review was done on the spot, and we deployed (but did not release) at least daily.</p>
<p>We were able to change the shape of our API and make judgement calls on the spot, which allowed us to keep progressing the feature.</p>
<p>There was a noticeable improvement in the skills of the participants, the first days we would have to dictate the Backend to FE engineers and viceversa, later days we could express ideas as the team and have the typist mostly execute them.</p>
<p>We were stuck at several points, and having a wider range of skills allowed us to tackle the issues in a more effective way. Although, I must note, that a shared frustration at being stuck is not easier to bear than an isolated frustration at being stuck.</p>
<p>We all know the tradeoffs and choices that were made, as well as how and why our code works the way it works.</p>
<h3 id="heading-tweaks-i-would-make">Tweaks I would make</h3>
<p>I think that while the team being multifunctional has its interest, this exercise necessitates that people have a fair knowledge of the whole stack. While I think that time can solve the issue, it is none the less a hurdle you will have in segregated FE and BE teams.</p>
<p>The setup, can make or break you, if you decide to give it a go, you should pretty soon have a dedicated computer, keyboard and screen (a big one) to allow members to leave the group when they need to do individual work.</p>
<h2 id="heading-will-we-do-it-again">Will we do it again?</h2>
<p>Tl:dr: maybe.</p>
<p>After three weeks of working <em>mostly</em> as a mob, we have decided that the challenges were a bit too big for the team.</p>
<p>We did take some lessons from this new try and might try again in the future.</p>
<p>As an individual, in a vacuum, I am now convinced that this is the most effective way of producing software. But it necessitates a high buy in and conviction from management and the software team.</p>
]]></content:encoded></item><item><title><![CDATA[Floor and Ceiling raisers]]></title><description><![CDATA[Floor and ceiling raisers have been on my mind lately regarding software development.
Yes, another sport analogy… but one I believe is fitting.
What does it even mean?
I heard of this concept as related to basketball initially.
A floor raiser is a pl...]]></description><link>https://blog.codemanship.dev/floor-and-ceiling-raisers</link><guid isPermaLink="true">https://blog.codemanship.dev/floor-and-ceiling-raisers</guid><category><![CDATA[tech ]]></category><category><![CDATA[agile]]></category><category><![CDATA[team]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 04 Oct 2024 09:03:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728032531023/1173f7e0-5c6a-46f0-a940-b7271ea33db5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Floor and ceiling raisers have been on my mind lately regarding software development.</p>
<p>Yes, another sport analogy… but one I believe is fitting.</p>
<h1 id="heading-what-does-it-even-mean">What does it even mean?</h1>
<p>I heard of this concept as related to basketball initially.</p>
<p>A floor raiser is a player (or concept) that raises the lower level you operate at.</p>
<p>On the contrary, a ceiling raisers will raise the highest level you can operate at.</p>
<p>In a software development team, I think of these concepts as:</p>
<p>Floor raising =&gt; We are better within our ‘possibility space'</p>
<p>Ceiling raising =&gt; We expand the horizon of our ‘possibility space’</p>
<h1 id="heading-how-does-it-relate-to-software">How does it relate to software?</h1>
<p>While the decisions are, at it's simplest, much more intuitive in basketball, I believe a good software team is first and foremost a team.</p>
<p>And as such, other than the obvious ‘you are as strong as your weakest link'. There are practices you can adopt to raise your team’s floor (and a couple of hints on raising its ceiling).</p>
<p>And I will focus more on the floor, because contrary to basketball, ‘peaks’ matter less than ‘valleys’ in software development.</p>
<p>In the long term, the productivity of a software team will be determined by its valleys.</p>
<h1 id="heading-raising-the-floor">Raising the floor</h1>
<p>So, what can you do to raise the floor? And how can we measure the floor of a software team?</p>
<h2 id="heading-the-floor">The floor</h2>
<p>The baseline measure I will consider for a piece of software is:</p>
<ul>
<li><p>Ease of change,</p>
</li>
<li><p>amount of defects,</p>
</li>
<li><p>the software works as expected</p>
</li>
</ul>
<p>In the scope of a team:</p>
<ul>
<li><p>Deploys per period,</p>
</li>
<li><p>defects per deploy</p>
</li>
<li><p>time to fix defects</p>
</li>
</ul>
<p>Apart from the practices described below, hiring a senior or raising the seniority of your team will raise the floor of your team.</p>
<h2 id="heading-practices">Practices</h2>
<h3 id="heading-test-driven-development">Test Driven Development</h3>
<p>This is I believe one of the biggest floor raisers, and one of the easy pickings.</p>
<p>Code designed with Test Driven Development, is easier to change, produces less defects and can be deployed continuously.</p>
<h3 id="heading-short-lived-branches">Short lived branches</h3>
<p>By reducing the overhead of reviews, and the size of code reviews, you again, by design raise the floor of the team. Trunk Based Development, while needing of quite a few preexisting conditions, is even more effective at that.</p>
<h3 id="heading-ensemblepair-programming">Ensemble/Pair Programming</h3>
<p>By reducing the feedback loop: the review happens ‘as you code'. And, helping maintain a higher base level of care. Coding in group helps elevate the floor of a team.</p>
<h3 id="heading-thin-vertical-slicing">Thin vertical slicing</h3>
<p>By creating thin vertical slices for your projects/features, you lower the risk of any one slice, you facilitate the review process and shorten the feedback loop.</p>
<h3 id="heading-retrospectives">Retrospectives</h3>
<p>By having frequent retrospectives (the 6 thinking hats framework worked quite well on our team) you open the door of adapting your way of work. This will allow you to progressively raise the floor of your team.</p>
<h1 id="heading-raising-the-ceiling">Raising the ceiling</h1>
<h2 id="heading-the-ceiling">The ceiling</h2>
<p>The ceiling is derived from the capabilities your team has. What domains they can work on and for what types of technological problems they can intervene effectively.</p>
<h2 id="heading-how-to-raise-it">How to raise it</h2>
<p>If the technological or domain proficiency of certain members of your team grow, the ceiling will move up.</p>
<p>There are two obvious ways to achieve that:</p>
<ul>
<li><p>Hiring a specialist,</p>
</li>
<li><p>forming members of your team in new technologies or specialist subjects.</p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusion</h1>
<p>At its limit, the productivity of a software development team is determined by its ‘floor’ so when thinking which practices to introduce to your team, think which would be the most effective floor raiser.</p>
<p>The floor is also, the limit where you can have more impact in the long run. Although you can have bursts of impact on the ceiling.</p>
]]></content:encoded></item><item><title><![CDATA[Retrospectives]]></title><description><![CDATA[If I had to choose one thing and one thing only that I would enshrine as THE thing to make a software development team more effective, it would be frequent retrospectives.
We have been doing a retrospective every two weeks at Recovr, and this is what...]]></description><link>https://blog.codemanship.dev/retrospectives</link><guid isPermaLink="true">https://blog.codemanship.dev/retrospectives</guid><category><![CDATA[agile]]></category><category><![CDATA[Retrospective]]></category><category><![CDATA[#Continuous improvement]]></category><category><![CDATA[teamwork]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 29 May 2024 13:30:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/lPgmMWtX14Q/upload/2c4b72d174e5f26175cd501f0a4ccd70.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If I had to choose one thing and one thing only that I would enshrine as THE thing to make a software development team more effective, it would be frequent retrospectives.</p>
<p>We have been doing a retrospective every two weeks at Recovr, and this is what is working great for us:</p>
<h1 id="heading-structured-and-timed">Structured and Timed</h1>
<p>We are using a variant of the 6 thinking hats.</p>
<p>We spend 2 minutes on facts and figures, 4 minutes on positive thinking, 4 minutes on critical thinking and 4 minutes on solution thinking. We then leave ourselves some time to decide on at most 1 adjustment to make until the next retrospective.</p>
<p>We have a time keeper and a person writing everyone's points on a whiteboard.</p>
<p>This is how a typical retro might look in the end:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1716979746903/bccdb79f-8500-4cfa-81f5-e85f5c422b7e.png" alt class="image--center mx-auto" /></p>
<p>Thanks to that structure, our retrospectives are usually between 30 and 45 minutes long.</p>
<h1 id="heading-one-adjustment-in-isolation">One adjustment in isolation</h1>
<p>The idea is not to change the whole way we work at every retrospective, but rather to make at most one adjustment per retrospective.</p>
<p>For example we realized we had too many items ongoing, so we added a rule that anyone could only have a maximum of three items in review or in progress.</p>
<p>We also decided to try our hand at Ensemble Programming after a retrospective.</p>
<h1 id="heading-no-listing-of-what-was-done">No listing of what was done</h1>
<p>We do not go through each item of the period, what was done and not done. We found that it rarely leads to insights, and the few insights are not really actionable.</p>
<p>As such we speak about the period as a whole.</p>
<h1 id="heading-dont-debate-what-goes-to-the-board"><strong>Don't debate what goes to the board</strong></h1>
<p>If a person of the team feels something is worth saying, it goes to the board without discussion, there can be an explanation, but doubt is not cast on it.</p>
<p>The place to debate the different things is when we look for the adjustment that should be made for the next period.</p>
<p>This allows us to not get bogged down in the particulars and react to the more general patterns emerging.</p>
<h1 id="heading-high-buy-in">High buy in</h1>
<p>The structure, and the fact that in the end an adjustment is decided as a group, provoques a high buy in from the whole team in the adjustment to be made for the next period.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Try your hand at doing frequent retrospectives today, keep them structured, keep them short and have he discipline to only make one adjustment.</p>
<p>Bit by bit it will improve how you work, and will find what works for your team at each moment in time.</p>
]]></content:encoded></item><item><title><![CDATA[So we tried Ensemble Programming]]></title><description><![CDATA[It has been a couple of months since we started inserting small controlled experiments into our workflow at Recovr. It all started with the introduction of retrospectives, following a similar method to the Six Thinking Hats, although we only kept fou...]]></description><link>https://blog.codemanship.dev/so-we-tried-ensemble-programming</link><guid isPermaLink="true">https://blog.codemanship.dev/so-we-tried-ensemble-programming</guid><category><![CDATA[group-programming]]></category><category><![CDATA[mob-programming]]></category><category><![CDATA[extreme programming]]></category><category><![CDATA[agile]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Mon, 27 May 2024 08:35:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/gA396xahf-Q/upload/97712b807cc6bd4b6fa134a266e8e9bf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It has been a couple of months since we started inserting small controlled experiments into our workflow at <a target="_blank" href="https://recovr.eu">Recovr</a>. It all started with the introduction of retrospectives, following a similar method to the Six Thinking Hats, although we only kept four (Facts and Figures, Critical thinking, Positive Thinking, and Solutions).</p>
<p>Our latest experiment has been 3 days of Ensemble Programming. And I loved it, so let me tell you what ensemble programming was for us, what worked well and where we could still tweak it.</p>
<h1 id="heading-ensemble-for-us">Ensemble for us</h1>
<p>From what I gathered talking to people around me, Ensemble programming means different things to different people. So here are the rules we had for our first ensemble day and how the rules ended up for the last day (three days later).</p>
<h2 id="heading-first-day">First Day</h2>
<p>On the first day, we heavily influenced ourselves by the book <a target="_blank" href="https://pragprog.com/titles/mpmob/code-with-the-wisdom-of-the-crowd/">Code With the Wisdom of the Crowd</a>.</p>
<p><strong>Roles</strong>: We decided that there would be two roles: the Typist and the Rest of the ensemble. The Typist's responsibility is to transcribe the ensemble's intentions.</p>
<p><strong>Timings</strong>: We started with every typist being at the keyboard for 15 minutes</p>
<p><strong>Retrospectives</strong>: We decided to have regular retrospectives throughout the three days; these informed the changes we reached for the other days</p>
<h2 id="heading-second-day">Second day</h2>
<p>After a retrospective on day two, we discovered what seemed most problematic on day one: We got off topic and lost half a day chasing our tails.</p>
<p>As a consequence, we decided to add another 'rule' which was:</p>
<p><strong>Structure</strong>: We can only advance following a to-do. If we run out of to-do items or we need to deviate, a new to-do must be created</p>
<p>This allowed us to advance with more purpose on our second day.</p>
<h2 id="heading-third-and-final-day">Third and final day</h2>
<p>On our last retrospective, we realized that the timings for the typist were too short, and the switching machines cost too high in proportion.</p>
<p>To fix that, we decided to increase the timings for the typist from 15 to 25 minutes. Here is how the rules looked in the end:</p>
<p><strong>Roles:</strong> Typist and Rest of the ensemble. The <em>Typist's</em> responsibility is to transcribe the intentions of the ensemble.</p>
<p><strong>Timings</strong>: 25 minutes on the keyboard for each of us. If we must discuss something for a long time, the timer is paused.</p>
<p><strong>Retrospectives</strong>: regular retrospectives</p>
<p><strong>Structure</strong>: A to-do must always be up-to-date and active to advance.</p>
<h1 id="heading-what-worked-for-us-in-my-opinion">What worked for us (in my opinion)</h1>
<h2 id="heading-retrospectives">Retrospectives</h2>
<p>Within the three days we had three retrospectives, one at the first half day, and in the morning of each of the other two.</p>
<p>This was the most impactful thing we did, it allowed us to have each day improve on what we had built the previous day.</p>
<h2 id="heading-breaks">Breaks</h2>
<p>We forced ourselves to take breaks quite regularly, especially after we finished the first day knackered. This allowed us to be fresher and more efficient during the working parts.</p>
<h2 id="heading-level-of-care">Level of care</h2>
<p>I found that the level of care and attention to detail was higher as a group than as 5 distinct individuals.</p>
<p>I attribute this to the fact that as a group, someone's care was always high, even when it decayed on someone else.</p>
<p>I believe the end result of what we were coding was something we can be prouder that if it was coded individually.</p>
<h2 id="heading-learning">Learning</h2>
<p>We are organized as a team with a distinct front and back end. In order for this to work, we decided to have the front and back work together.</p>
<p>This meant that we not only were learning how to work as a group, we were all also all learning a new language.</p>
<p>Everyone had quite an open mind to it, and recalling our first rotations and our last ones, the instructions went from dictating the specific syntax to more general we should do X.</p>
<h2 id="heading-flow-and-coordination">Flow and coordination</h2>
<p>One area where we definitely gained a lot of time and quality, was in the coordination among the front and back (and more generally the team).</p>
<p>If we wanted a shape to our API, it was decided on the spot by everyone, so we did not have to revisit things due to misunderstandings.</p>
<p>The same can be said about the architecture of our code.</p>
<h2 id="heading-code-and-architecture-quality">Code and architecture quality</h2>
<p>Since we were deciding things by committee, there were less sunk cost galàxies that come into play when a review is done after the fact.</p>
<h1 id="heading-what-could-still-be-improved-in-my-opinion">What could still be improved (in my opinion)</h1>
<h2 id="heading-switching-costs">Switching costs</h2>
<p>Most of us preferred to work on our machines, and while it has advantages, mainly everyone working in a familiar environment, it does mean that there is an inherent cost of switching the machines and pushing/pulling the code.</p>
<p>We did find ways to make that s bit faster with each switch, but progress could still be made in that front.</p>
<h2 id="heading-cost-of-the-experiment">Cost of the experiment</h2>
<p>While I am convinced now that doing ensemble work regularly would be a net positive, this first experiment did have costs.</p>
<p>The big elephant in the room is that we spent 15 programmer-days for this experiment. At the end of the three days we did a budgeted work of ~8 programmer days. I believe the advantages in reduced coordination costs are well worth it. And with more ensemble experience, I believe the two numbers will get closer to each other.(Edit: after the fact I realized that it is quite common for us to miss our mark when estimating and being of by 50% so the amount of work produced was roughly on par)</p>
<p>The two other minor costs we incurred were:</p>
<p>On one hand, we ended the days quite tired (although less with each passing day).</p>
<p>On the other, since we were working in an unfamiliar way we were not as efficient as we could have been.</p>
<p>I am quite sure that the cost will lessen as we keep doing ensemble programming.</p>
<h2 id="heading-getting-stuck">Getting stuck</h2>
<p>I had the impression that we got stuck on minutiae a couple of times, especially when two of us felt quite strongly about one thing or the other.</p>
<p>I suppose there are a few ways to fix that, first that comes to mind is after X time, pick one direction and test it.</p>
<p>I look forward to see how this evolved in the future.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>I believe the experiment was a net positive, not only is the code quality higher, I think that the 'time' we lost due to inexperience will be offset by the reduced coordination and review costs.</p>
<p>The team seemed quite enthusiastic about the experiment and we are working on integrating ensemble programming into the way we work.</p>
<p>If you, dear reader, have never tried it, I can only recommend you do, remember to adjust along the way and to keep an open mind.</p>
]]></content:encoded></item><item><title><![CDATA[Test factories should not have randomness, but... Why?]]></title><description><![CDATA[I had a discussion with a colleague the other day about randommess in FactoryBot objects.
They were in favor of having randomness in their objects, their main argument being:

If we have random values, eventually we are bound to find the edge cases.
...]]></description><link>https://blog.codemanship.dev/test-factories-should-not-have-randomness-but-why</link><guid isPermaLink="true">https://blog.codemanship.dev/test-factories-should-not-have-randomness-but-why</guid><category><![CDATA[Testing]]></category><category><![CDATA[Programming Tips]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[Fixtures]]></category><category><![CDATA[test driven development]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 06 Mar 2024 10:48:30 GMT</pubDate><content:encoded><![CDATA[<p>I had a discussion with a colleague the other day about randommess in FactoryBot objects.</p>
<p>They were in favor of having randomness in their objects, their main argument being:</p>
<blockquote>
<p>If we have random values, eventually we are bound to find the edge cases.</p>
</blockquote>
<p>I was against, my main argument being a flavor of:</p>
<blockquote>
<p>Tests should be deterministic</p>
</blockquote>
<p>My inability to better explain why has prompted this post to produce a though out explanation as to why.</p>
<h1 id="heading-trust">Trust</h1>
<p>Randomness in setting the context of tests makes our tests untrustworthy, and:</p>
<p>Tests we cannot trust are a waste of time, brainpower and computation (in order of decreasing importance).</p>
<p>We waste time having to run them multiple times.</p>
<p>We waste time having to manually verify facts the tests should tell us.</p>
<p>We waste brainpower trying to figure out if a failing test is a genuine regression or if it is just flakyness introduced by the randomness.</p>
<p>We waste computation, although with a lesser importance in my eyes, we do waste computation if we introduce flakyness.</p>
<h1 id="heading-hidden-information">Hidden information</h1>
<p>If we rely on randomness to catch our edge cases, we rob them of the visibility and place they deserve. The next person to come through our tests won't know what edge cases we have faced, and won't know if they are tested.</p>
<p>Unless we log the objects in our tests, chances are the failure message will be really critic</p>
<p>If we are reaching for an object from a factory, we now have to know or lookup what values might vary.</p>
<h1 id="heading-tests-should-be-deterministic">Tests should be deterministic</h1>
<p>In closing, I guess my 'one Line argument' remains the same:</p>
<blockquote>
<p><em>Tests should be deterministic</em></p>
</blockquote>
<p>But I sincerely hope someone will be convinced by the expanded arguments above.</p>
]]></content:encoded></item><item><title><![CDATA[Dependencies in Knowledge and Practices]]></title><description><![CDATA[Knowledge and practices have dependencies.
Knowing this and thinking about them will allow to grow your knowledge and practices in a more comfortable manner
In this article I would like to examine and exemplify them separately in order to better unde...]]></description><link>https://blog.codemanship.dev/dependencies-in-knowledge-and-practices</link><guid isPermaLink="true">https://blog.codemanship.dev/dependencies-in-knowledge-and-practices</guid><category><![CDATA[code]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 31 Jan 2024 10:27:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/XXScl3vjFpw/upload/bb799a00a47bb6ae597d51dff02c4885.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Knowledge and practices have dependencies.</p>
<p>Knowing this and thinking about them will allow to grow your knowledge and practices in a more comfortable manner</p>
<p>In this article I would like to examine and exemplify them separately in order to better understand their consequences.</p>
<h1 id="heading-the-dependencies-of-knowledge">The dependencies of Knowledge</h1>
<p>Learning has dependencies, there is no point in trying to teach advanced algorithms to someone who has not a clue about recursion or that does not understand control flow.</p>
<p>And if you try to do so, you will quickly discover that you will have to take the time to teach those concepts.</p>
<p>This applies to most knowledge we need as engineers, and learning or teaching them in the "correct" order matters.</p>
<p>Another example that comes to mind is languages and frameworks. You can learn JavaScript by learning React, but your knowledge of both React and JavaScript will suffer from it. (Substitute JavaScript and React with CSS and Tailwind, Ruby and Rails, etc).</p>
<p>This affects both individuals and teams:</p>
<ul>
<li><p>Individuals because they should be conscious of it when learning, to see that if something is "too difficult" it might be because they are trying to learn it out of order.</p>
</li>
<li><p>Teams because if you want to upskill a team, you need everyone to get on the same 'stem' of the tree of knowledge or be prepared to tailor the growth of each individual.</p>
</li>
</ul>
<h1 id="heading-the-dependencies-of-practices">The dependencies of Practices</h1>
<p>As with knowledge, Practices have dependencies. The clearer example of that is CI(Continuous Integration)/TBD(Trunk Based Development). In order to apply it, you must, as a minimum:</p>
<ul>
<li><p>Have good test practices</p>
</li>
<li><p>Pair/mob regularly</p>
</li>
<li><p>Be comfortable with separating integration from release</p>
</li>
</ul>
<p>A similar story goes for test practices, let's take TDD(Test Driven Development) for example. In order to acquire that practice, you must already:</p>
<ul>
<li>Be comfortable with the practice of testing.</li>
</ul>
<p>These dependencies are somewhat overlooked by proponents of the 'more advanced' practices and that can be problematic.</p>
<p>This has the same consequences both for individuals and teams:</p>
<p>Individuals and teams should understand the dependencies in the practices they wish to embrace in order to adopt their prerequisites.</p>
<h2 id="heading-a-small-out-of-bounds-note-on-practices">A small out of bounds note on practices</h2>
<p>The dependencies in practices also reveal themselves in the fact that some practices are anathema to others. I won't delve deep into this subject, but let me exemplify it by saying that you will struggle making git flow and TBD work at the same time.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<ul>
<li><p>Know the dependencies that exist in what you want to learn or do.</p>
</li>
<li><p>Go about reaching the destination in order of dependencies.</p>
</li>
<li><p>Validate that as a team or individual you have satisfied the dependencies before moving to higher subjects</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Some subjects are inherently better to learn]]></title><description><![CDATA[Some subjects are inherently better to learn
Me - to a group of friends

Allow me to explain what might seem like a hot take:
2 things make a subject 'inherently' better, one is deeply personal, the other is a matter of applicability :
Deeply persona...]]></description><link>https://blog.codemanship.dev/some-subjects-are-inherently-better-to-learn</link><guid isPermaLink="true">https://blog.codemanship.dev/some-subjects-are-inherently-better-to-learn</guid><category><![CDATA[learning]]></category><category><![CDATA[programming]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Fri, 27 Oct 2023 16:15:01 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>Some subjects are inherently better to learn</p>
<p>Me - to a group of friends</p>
</blockquote>
<p>Allow me to explain what might seem like a hot take:</p>
<p>2 things make a subject 'inherently' better, one is deeply personal, the other is a matter of applicability :</p>
<h1 id="heading-deeply-personal">Deeply personal</h1>
<p>If the subject matter holds no interest to you, be it for personal or professional reasons, that subject matter is inherently worse (for you)</p>
<h1 id="heading-a-matter-of-applicability">A matter of applicability</h1>
<p>I like to see subjects (I mostly read, but I believe it applies to subjects, not books) as having a "wideness" of applicability.</p>
<h2 id="heading-very-narrow">Very narrow</h2>
<p>Very narrow subjects (think "Eloquent JavaScript" or "Practical Go Lessons") have a very narrow applicability, close to 100% of what you'll learn will apply only in situations where you use that language.</p>
<p>It's ok to investigate a bit to hone your skills, but won't be very transferable. They deal in very "short term" tactics.</p>
<h1 id="heading-averagely-narrow">Averagely narrow</h1>
<p>If we expand the scope a bit and go for wider books, we have subjects that deal with a "universal topic", think subjects you could learn in a language you don't master, things like: TDD, Encapsulation, Refactoring, Patterns, Algorithms</p>
<p>These subjects still deal mostly with "tactics", but their scope is a bit expanded, the tactics are more long term, some get close to being strategic. You start to be able to use these lessons in almost any language.</p>
<h1 id="heading-wide">Wide</h1>
<p>Then you have more "holistic" subjects, in books I think of: "Pragmatic Programmer", "The software craftsman", "Modern Software Engineering", any book about Architecture, DDD</p>
<p>These will give you very transferable knowledge.</p>
<h1 id="heading-situational">Situational</h1>
<p>To finish the list, you have more situational books (think eXtreme Programming) where the knowledge is highly transferable technologically, but very team-context dependent.</p>
<h2 id="heading-what-type-of-topic-should-i-go-for">What type of topic should I go for?</h2>
<p>I believe the inherent worth of each of them might change over time and situation, but I believe that the marginal-gain curve flattens out faster the "narrower" the subject is. The 100th hour learning Ruby has less beneficial impact than the 100th hour learning testing strategies for example</p>
]]></content:encoded></item><item><title><![CDATA[The dangers of refactoring to an idea]]></title><description><![CDATA[Recently I started a new position. After a couple of (I hope) successful additions to de codebase, I was entrusted with a bug fix that sparked in me an idea for a potential refactor.
I discussed my idea with some of my new colleagues and got some buy...]]></description><link>https://blog.codemanship.dev/the-dangers-of-refactoring-to-an-idea</link><guid isPermaLink="true">https://blog.codemanship.dev/the-dangers-of-refactoring-to-an-idea</guid><category><![CDATA[coding]]></category><category><![CDATA[refactoring]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Tue, 17 Oct 2023 15:09:55 GMT</pubDate><content:encoded><![CDATA[<p>Recently I started a new position. After a couple of (I hope) successful additions to de codebase, I was entrusted with a bug fix that sparked in me an idea for a potential refactor.</p>
<p>I discussed my idea with some of my new colleagues and got some buy-in and time to execute the refactor.</p>
<p>I took about a week tinkering and delivered my PR, all the tests passed, and all seems okay.</p>
<p>And still, I have a nagging feeling of dissatisfaction with the work I produced. It works, I believe, fine enough and the solution is, if I might self-congratulate, elegant enough.</p>
<p>So, why do I have this feeling of dissatisfaction?</p>
<p>Please embark with me, dear reader, on a small introspective journey while I try to make sense of these feelings. With some luck, we will all learn something from the exercise (at the very least I hope I will).</p>
<h1 id="heading-the-unease-begins">The unease begins.</h1>
<p>When reflecting on what created my nascent unease with my work, I believe I can pinpoint it to two things. One of them concrete, one of them more intangible.</p>
<p>On the concrete side of things, is the file changes count and the lines +-. I changed about 45 files and added ~2000 to remove ~200 lines.</p>
<p>This is A LOT, and made me pause when I realized it.</p>
<p>It also, I believe, contributes to the intangible part, explaining and self-reviewing my changes in writing felt very hard, not so much on a conceptual level, as on the sheer amount of changes.</p>
<h1 id="heading-red-flags">Red flags(?)</h1>
<p>Okay, so those things made me feel awkward, but are they red flags?</p>
<p>On a vacuum, yes, certainly.</p>
<p>But are the changes I made justified or am I justifying them to myself due to the sunk cost fallacy?</p>
<h1 id="heading-goals-accomplished">Goals accomplished (?)</h1>
<p>I think, to make sense of all of this I need to separate the actual PR (and what I think the goals of a PR should be) from the refactor (and what I think the goals of a refactor should be)</p>
<h2 id="heading-goals-of-a-pr">Goals of a PR</h2>
<p>In my opinion, a PR should accomplish the following goals:</p>
<ul>
<li><p>Be cohesive (success)</p>
</li>
<li><p>Be easy to review (failure)</p>
</li>
<li><p>Have a small diff (failure)</p>
</li>
</ul>
<p>1 out of 3, and in my opinion not the most important success, so here I clearly failed (I'll reflect below on what I could have done differently)</p>
<h2 id="heading-goals-of-a-refactor">Goals of a refactor:</h2>
<ul>
<li><p>Make future changes easier (success)</p>
</li>
<li><p>Make the code easier to parse (success)</p>
</li>
</ul>
<p>In this, I feel like I succeeded, I believe the code is easier to parse and easier to change later.</p>
<h1 id="heading-where-did-i-go-wrong">Where did I go wrong?</h1>
<p>I started the refactoring by presenting an idea to the team, which is not a bad thing in and of itself, but I believe I fleshed out the idea too much.</p>
<p>It also prompted me to start the refactoring by my 'wanted' result rather than step by step.</p>
<p>This had two consequences:</p>
<ul>
<li><p>My thinking was less flexible</p>
</li>
<li><p>I branched out the oath by inserting my 'final' class and broke the tests for a week.</p>
</li>
</ul>
<h1 id="heading-what-i-should-have-done-differently">What I should have done differently</h1>
<p>Giving a high-level idea of the changes is fine, but I fleshed it out too much.</p>
<p>More importantly, I should have done the refactoring step by step and starting from the existing code, making sure the relevant specs pass all the way.</p>
<p>This would have provided me with natural stopping points where I could have submitted several PRs instead of the monstrosity I submitted.</p>
]]></content:encoded></item><item><title><![CDATA[Value Objects in Rails]]></title><description><![CDATA[You can get a lot of value in rails by using value objects to compose your ActiveRecord models and using concepts from value objects to limit said models.
I will strive to explain here:

What is a value object

How to make a pure value object and use...]]></description><link>https://blog.codemanship.dev/value-objects-in-rails</link><guid isPermaLink="true">https://blog.codemanship.dev/value-objects-in-rails</guid><category><![CDATA[Rails]]></category><category><![CDATA[code]]></category><category><![CDATA[development]]></category><category><![CDATA[DDD]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 11 Oct 2023 19:04:57 GMT</pubDate><content:encoded><![CDATA[<p>You can get <em>a lot</em> of value in rails by using value objects to compose your ActiveRecord models and using concepts from value objects to limit said models.</p>
<p>I will strive to explain here:</p>
<ul>
<li><p>What is a value object</p>
</li>
<li><p>How to make a pure value object and use it in rails</p>
</li>
<li><p>How to transform ActiveRecord objects into almost value objects</p>
</li>
<li><p>Why and when could you use value objects</p>
</li>
</ul>
<h1 id="heading-what-is-a-value-object">What is a value object</h1>
<p>I deliberately choose not to look up a definition (in part so you, dear reader, can tell me how wrong I am) and provide the definition I have in my head.</p>
<p>A value object is an object that does not need nor have an identity, that can be substituted by another instance of the same object with the same attributes and that is immutable (as changing it would make it by definition another object)</p>
<p>So if we imagine a <code>Money</code> class, that implements a <code>#value</code> and a <code>#currency</code> attributes. Any <code>&lt;Money value=5 currency=€&gt;</code> Can be substituted by another instance of <code>Money</code> that has the same value and currency (after all, when you get a 5€ not, you do not care about the serial number).</p>
<p>This can be opposed to an <code>Account</code> object, that has <code>#balance</code> and <code>#currency</code> methods, in this case, substituting an account for another might mean allowing someone to withdraw money that isn't theirs.</p>
<h1 id="heading-how-to-make-pure-value-objects-and-use-them-in-rails">How to make 'pure' value objects and use them in Rails</h1>
<p>At its simplest, a value object is just a class with an overridden <code>==</code> method (well and <code>===</code>). You could just do:</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Money</span></span>
    <span class="hljs-keyword">attr_reader</span> <span class="hljs-symbol">:amount</span>, currency

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initialize</span><span class="hljs-params">(<span class="hljs-symbol">amount:</span>, <span class="hljs-symbol">currency:</span>)</span></span>
        @amount = amount
        @currency = currency
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">==</span><span class="hljs-params">(other)</span></span>
        amount == other.amount &amp;&amp;
            currency == other.currency
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>This is a value object in and off itself, but how do you plug it into your ActiveRecord object?</p>
<p>Taking advantage of the <code>composed_of</code> <a target="_blank" href="https://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html">macro</a>:</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Accoun</span> &lt; ActiveRecord </span>
    [...]    
    composed_of <span class="hljs-symbol">:money</span>, <span class="hljs-symbol">mapping:</span> { <span class="hljs-symbol">balance:</span> <span class="hljs-symbol">:amount</span>, <span class="hljs-symbol">currency:</span> <span class="hljs-symbol">:currency</span> }
<span class="hljs-keyword">end</span>
</code></pre>
<h1 id="heading-how-to-transform-activerecord-objects-into-almost-value-objects">How to transform ActiveRecord objects into almost value objects</h1>
<p>Sometimes, we need our ActiveRecord objects to behave with certain characteristics of value objects, in this case, I will show you how to make an active record (almost) immutable:</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CarModel</span></span>
    [...]    

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_only?</span>    </span>
    !persisted?   
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>You could go further and also overwrite the <code>==</code> method if you wanted.</p>
<h1 id="heading-why-and-when-could-you-use-value-objects">Why and when could you use value objects</h1>
<p>All of this is well and good, but I gather part of the reason you are here, cherished reader, is to know when and why you would use value objects.</p>
<h2 id="heading-when">When</h2>
<p>As stated previously, one of the key reasons to use value objects is when you only care about the characteristics.</p>
<p>You might also find yourself, attentive reader, with 'prefixed attributes'. A classic example of this might be <code>address</code></p>
<p>For example, a <code>Person</code> had several related attributes like: <code>address_street</code>, <code>address_number</code>, etc</p>
<p>You can group all of these in an address object and enrich them with methods such as <code>#full_address</code>and store all of those in a <code>jsonb</code> <code>address</code> column.</p>
<p>Finally, it helps you break god objects into more cohesive and reusable units</p>
<h2 id="heading-why">Why</h2>
<p>It is safer as having these objects being immutable means they won't change in the course of your code, which is one less variable to take into account.</p>
<p>You can unit test these objects with more ease than a typical ActiveRecord object.</p>
<p>Finally, it allows you to give them larger behavior than you could if you represented the values 'only' with a primitive.</p>
]]></content:encoded></item><item><title><![CDATA[BDD in action (a quick opinion)]]></title><description><![CDATA[The book is quite ok (although a bit tedious in it's examples). I do recommend reading it!
My sense of BDD after this book:
You get 'mostly' feature coverage, but as a byproduct, although it is a byproduct not of organizing the system but of explorin...]]></description><link>https://blog.codemanship.dev/bdd-in-action-a-quick-opinion</link><guid isPermaLink="true">https://blog.codemanship.dev/bdd-in-action-a-quick-opinion</guid><category><![CDATA[bdd]]></category><category><![CDATA[coding]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Sun, 10 Sep 2023 09:56:30 GMT</pubDate><content:encoded><![CDATA[<p>The <a target="_blank" href="https://www.manning.com/books/bdd-in-action">book</a> is quite ok (although a bit tedious in it's examples). I do recommend reading it!</p>
<p>My sense of BDD after this book:</p>
<p>You get 'mostly' feature coverage, but as a byproduct, although it is a byproduct not of organizing the system but of exploring and defining the high-level functionality of your application.</p>
<p>It has several strategies to explain how to not get bogged down in infinitely running tests as well as how it evolved from TDD.</p>
<p>All in all, it seems BDD requires a bigger organisational 'buy-in' than TDD (and has also bigger promises). In the sense that I can TDD without anyone's but in, and maybe convince 'by example', but in the end it does not really matter that all the team TDD's. Whereas for BDD to be useful as described in the book, the whole 'team' (in it's widest sense, including even users) needs to buy in.</p>
<p>It's promises are quite interesting though, and present a cycle of red-green-refactor made up of a lot of red green refactors.</p>
<p>I think when I 'naively' tried it in the past, my main mistake was assuming that the cucumber scenarios should not be done by the tech team (in close collaboration with the stakeholders)</p>
<p>The promises of being able to better discover features and edge cases via examples while making collaboration with 'business' easier is quite appealing</p>
<p>After reading the book, if I am ever in position to try BDD again I would like to give it another go</p>
]]></content:encoded></item><item><title><![CDATA[I did not write any tests]]></title><description><![CDATA[I made a website for a friend a couple months ago, it was a quick and dirty job, and to be honest not much more was/is needed.
This being a quick and dirty job, I did not write any tests (because I am my own worst enemy). After all, there are literal...]]></description><link>https://blog.codemanship.dev/i-did-not-write-any-tests</link><guid isPermaLink="true">https://blog.codemanship.dev/i-did-not-write-any-tests</guid><category><![CDATA[Testing]]></category><category><![CDATA[code]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Wed, 30 Aug 2023 13:59:56 GMT</pubDate><content:encoded><![CDATA[<p>I made a website for a friend a couple months ago, it was a quick and dirty job, and to be honest not much more was/is needed.</p>
<p>This being a quick and dirty job, I did not write any tests (because I am my own worst enemy). After all, there are literally four screens and three use cases to test. Realistically I could test the three use cases in under two minutes.</p>
<p>My friend asked me for a small change, this being basically a greenfield project, it took literally 20 minutes to implement.</p>
<p>So, all good, I test the screen that I think is affected, go to the home screen just in case, all is good.</p>
<p>Great! I made a friend happy for basically no effort, world is wonderful!</p>
<p>Deploy....</p>
<p>2 minutes later I get a message "hey Pablo, do you know the search is broken?"</p>
<p>"Ah right! This partial is used here!"</p>
<p>If only I coule have done something to prevent forgetting to test something...</p>
<p>You know, something that is actually low effort and would not only save me 2 mins each change, but most importantly would no have allowed me to deploy something broken in an obvious way!</p>
<p>Dear reader, if you know something that would have helped here, please let me know!</p>
]]></content:encoded></item></channel></rss>