<?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>Sat, 16 May 2026 16:57:20 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[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><item><title><![CDATA[The problems that are no one's problem]]></title><description><![CDATA["Can you change the text on the signup button?" Asked Travis, from marketing.
"Not really, I am in the middle of a project. I can take a look next week when I am done" responded Anna.
"Come on Anna, please it's just changing text, how long do you thi...]]></description><link>https://blog.codemanship.dev/the-problems-that-are-no-ones-problem</link><guid isPermaLink="true">https://blog.codemanship.dev/the-problems-that-are-no-ones-problem</guid><category><![CDATA[team]]></category><category><![CDATA[code]]></category><category><![CDATA[organization]]></category><category><![CDATA[agile]]></category><dc:creator><![CDATA[Pablo Curell Mompo]]></dc:creator><pubDate>Sat, 26 Aug 2023 20:12:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/den6EylZH9w/upload/75a940d7b9b1a2a2ecebc284194637cc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"Can you change the text on the signup button?" Asked Travis, from marketing.</p>
<p>"Not really, I am in the middle of a project. I can take a look next week when I am done" responded Anna.</p>
<p>"Come on Anna, please it's just changing text, how long do you think it'll take?"</p>
<p>"Ok, Travis you are right, it's 5 minutes I'll let you know when it's live"</p>
<p>If you have ever been a developer at a small or medium company, you have been in Anna's shoes. What is more, you can probably spot at least a couple of issues with this interaction.</p>
<p>Just in case, let me list a couple here:</p>
<ul>
<li><p>Anna has been interrupted by something without context and in a setting where she is not inclined to ask any</p>
</li>
<li><p>If Travis asks this, what is stopping Eva or Bob from asking for similar things</p>
</li>
<li><p>Once Anna has opened that door, it's complicated to say no to the next ones</p>
</li>
<li><p>A lot of small quick fixes might get done, but the (hopefully) important longer projects get delayed ad nauseam</p>
</li>
</ul>
<p>I believe in this article I can introduce to you a way to solve this, with the bonus of aiding to assign responsibility to those 'shadow' tasks that need doing but are no one's task.</p>
<h1 id="heading-the-idea">The idea</h1>
<p>Deliberately assign some team time (grouped or individually) where high-priority, small tasks are handled.</p>
<p>Some examples (but to each their own) of tasks that might qualify:</p>
<ul>
<li><p>Low impact bugs</p>
</li>
<li><p>Wording changes</p>
</li>
<li><p>Feature tweaks</p>
</li>
</ul>
<h1 id="heading-the-history">The history</h1>
<p>Sadly I must admit that the origin of this iteration of our (non)-revolutionary idea is lost to the fog of time. But I do know that when I got introduced to it, it had been copied from someone else. In the following sections, I will walk you through how I was introduced to the idea as well as how it morphed over several iterations.</p>
<h1 id="heading-once-a-week-we-all-dance-for-the-king">Once a week we all dance for the king</h1>
<p>I was introduced to this idea when working in Paris at Study Advisor.</p>
<p>Every Monday, the tech team would spend the day as the 'fous du roy' (King's jesters) and would handle the little tasks and bugs of the week. Well, to be honest... The tasks kept accumulating, but at least the most urgent ones were being handled.</p>
<p>Sadly, this presented some problems:</p>
<ul>
<li><p>Small fixes could turn out to need more than one day to fix.</p>
</li>
<li><p>Every week the tech team would spend at least one day 'not advancing' on their projects (that is 20% of the time)</p>
</li>
<li><p>It was taking a toll on the tech team members to 'drop' everything once a week and work on something else.</p>
</li>
<li><p>Other teams within the company might still wait a week or more to have their needs met.</p>
</li>
</ul>
<p>The next iteration of this idea fixed the identified problems</p>
<h2 id="heading-this-court-needs-a-rotating-jester">This court needs a rotating jester</h2>
<p>The solution we found to those problems was to have a rotating jester, so one member of the tech team would be the jester for the week (yes, the whole week). A board would centralize the requests from the other teams and the bugs with a perceived 'importance' for the team and the jester would be responsible for prioritizing and fixing or implementing the small things.</p>
<p>The idea behind this was that at the limit, the tasks would not represent a week's work, so the jester would be able to advance on their assigned feature as well during the week.</p>
<p>Higher impact bugs got added to the purview of the jester, as they would be the ones shouldering the weight of the interruptions on behalf of the team.</p>
<p>While this iteration solved the previously mentioned problems, it uncovered a rather big one, what happens when there are too many high-impact bugs or the jester is not the best person to handle an issue.</p>
<h2 id="heading-a-jester-is-not-enough-lets-call-spock">A jester is not enough, let's call Spoc(k)</h2>
<p>The next iteration of this idea was slow to come, I had left the team at Study Advisor, and at the company I joined (Yago) there seemed to be less of a need for such a figure.</p>
<p>Little did we know that one day one of us would take a vacation and it would coincide with a rather nasty (but seemingly) low-impact bug.</p>
<p>At that time we discovered that our teammate was not only handling his fair share of work, but on top of it, he was handling all the little bugs and modifications.</p>
<p>In our discussion as a team, I brought forth my experiences as a king's jester and we proceeded to implement the next iteration of the idea, but this time we would be Knight's, more exactly Single Point Of Contact Knights (because backronyms rock 🖖).</p>
<p>The Spock would have the same responsibilities as the jester previously had, but we added the fact that their responsibility was 'making sure things got done' rather than necessarily doing it themselves.</p>
<p>The Spock would primarily work as a single point of contact for bugs and requests, and although primarily they would be the ones solving the issues, they could call on other team members if they needed help or if someone else was better suited for the task.</p>
<p>And here concludes (for now) our story of kings, jesters, and Spock 🖖</p>
<h1 id="heading-summary-of-benefits">Summary of benefits</h1>
<ul>
<li><p>Low visibility or ad-hoc tasks are no longer anyone's problem</p>
</li>
<li><p>'Business' is more satisfied with the tech team as the team is less of a blocker for 'easy' changes</p>
</li>
<li><p>The bigger the team, the less proportional time is devoted to low-impact tasks</p>
</li>
<li><p>Making it rotational (I recommend weekly) makes it take less of a mental toll on the team</p>
</li>
</ul>
<h1 id="heading-potential-fallbacks">Potential fallbacks</h1>
<ul>
<li><p>If every small task is 'of the utmost importance' prioritization might be a problem</p>
</li>
<li><p>If a hand-off is not put in place between Spocks, some small tasks might be done twice or lost in the transition.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>