<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oscar Caldera</title>
    <description>The latest articles on DEV Community by Oscar Caldera (@oscarcaldera).</description>
    <link>https://dev.to/oscarcaldera</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3846307%2Fc4e288a9-c4c5-4efe-8b11-aa5b5d8e0f9c.png</url>
      <title>DEV Community: Oscar Caldera</title>
      <link>https://dev.to/oscarcaldera</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oscarcaldera"/>
    <language>en</language>
    <item>
      <title>Your team approved it in Slack. The code shipped something else.</title>
      <dc:creator>Oscar Caldera</dc:creator>
      <pubDate>Tue, 07 Apr 2026 21:27:59 +0000</pubDate>
      <link>https://dev.to/oscarcaldera/your-team-approved-it-in-slack-the-code-shipped-something-else-2mlb</link>
      <guid>https://dev.to/oscarcaldera/your-team-approved-it-in-slack-the-code-shipped-something-else-2mlb</guid>
      <description>&lt;p&gt;It doesn't happen dramatically. It happens quietly.&lt;/p&gt;

&lt;p&gt;Two weeks before the PR, someone in #product-decisions writes: &lt;br&gt;
"Only admins can export user data. Confirmed." Three people react &lt;br&gt;
with a thumbs up. The tech lead says "got it."&lt;/p&gt;

&lt;p&gt;Then the sprint moves fast. The developer who wrote that export &lt;br&gt;
service wasn't in that Slack thread. Or they were, and forgot. &lt;br&gt;
Or they remembered but misread the scope. The PR looks fine. &lt;br&gt;
The reviewer checks logic and style. Nobody checks it against &lt;br&gt;
what was actually decided.&lt;/p&gt;

&lt;p&gt;It merges. It ships. A customer exports data they shouldn't see.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4fllp2kzl1j6zdoc7d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4fllp2kzl1j6zdoc7d0.png" alt="Decisions on Slack are stored by Mo" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem isn't the code
&lt;/h2&gt;

&lt;p&gt;Code reviewers are good at catching bad code. They're not designed &lt;br&gt;
to remember every product decision made in Slack six sprints ago.&lt;/p&gt;

&lt;p&gt;That's not a process failure. It's a memory problem. Decisions &lt;br&gt;
live in Slack. Code lives in GitHub. Nothing connects them.&lt;/p&gt;

&lt;p&gt;So the drift happens silently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decision: "Users can't delete their own account — legal requires 30-day hold"&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PR: removes the deletion delay "to simplify the flow"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decision: "Feature X is behind a flag until Q3"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PR: removes the flag check&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decision: "Payments go through Stripe only — no fallback"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PR: adds a PayPal fallback "just in case"&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of those was approved somewhere. None of them made it &lt;br&gt;
to the diff review.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;p&gt;We ran into this enough at our agency that we built Mo — a bot &lt;br&gt;
that sits between Slack and GitHub.&lt;/p&gt;

&lt;p&gt;When someone tags &lt;a class="mentioned-user" href="https://dev.to/mo"&gt;@mo&lt;/a&gt; in a channel to approve a decision, Mo &lt;br&gt;
stores it. When a PR opens, Mo checks the diff against every &lt;br&gt;
stored decision and flags conflicts before the merge.&lt;/p&gt;

&lt;p&gt;It doesn't review code quality. It doesn't care about naming &lt;br&gt;
conventions or test coverage. It only asks one question: does &lt;br&gt;
this PR contradict something the team explicitly approved?&lt;/p&gt;

&lt;p&gt;If it does, it blocks the merge and shows exactly which decision &lt;br&gt;
is being violated and where in the diff. → &lt;a href="https://hey-mo.io" rel="noopener noreferrer"&gt;hey-mo.io&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this is hard to catch otherwise
&lt;/h2&gt;

&lt;p&gt;You could try to solve this with documentation. Write every &lt;br&gt;
decision into Confluence or Notion. The problem is that nobody &lt;br&gt;
does it consistently under deadline pressure, and even when they &lt;br&gt;
do, nobody checks it during PR review.&lt;/p&gt;

&lt;p&gt;You could try to solve it with better PR templates. "Did you &lt;br&gt;
check the decision log?" Same problem — it becomes a checkbox &lt;br&gt;
nobody reads.&lt;/p&gt;

&lt;p&gt;The only fix that works is making the check automatic and &lt;br&gt;
putting it exactly where developers already are: in the PR &lt;br&gt;
itself, before merge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftn9ncctrst5uhujrbwqr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftn9ncctrst5uhujrbwqr.png" alt="Mo checking the PR on GitHub" width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this has burned your team, I'd be curious how you handled &lt;br&gt;
it — and if you want to try Mo, it's at &lt;a href="https://hey-mo.io" rel="noopener noreferrer"&gt;hey-mo.io&lt;/a&gt;.&lt;br&gt;
7-day free trial.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>documentation</category>
      <category>management</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How to turn a Gantt chart into tickets for Jira / Asana / Monday</title>
      <dc:creator>Oscar Caldera</dc:creator>
      <pubDate>Fri, 27 Mar 2026 18:33:43 +0000</pubDate>
      <link>https://dev.to/oscarcaldera/how-to-turn-a-gantt-chart-into-tickets-for-jira-asana-monday-5fci</link>
      <guid>https://dev.to/oscarcaldera/how-to-turn-a-gantt-chart-into-tickets-for-jira-asana-monday-5fci</guid>
      <description>&lt;p&gt;A Gantt chart looks great. Until you try to execute it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gap&lt;/strong&gt;&lt;br&gt;
Most teams do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a Gantt chart &lt;/li&gt;
&lt;li&gt;Share it with stakeholders&lt;/li&gt;
&lt;li&gt;Then manually create tickets in Jira/Asana&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s where things break.&lt;br&gt;
Why?&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks get simplified &lt;/li&gt;
&lt;li&gt;Dependencies get lost &lt;/li&gt;
&lt;li&gt;Timing becomes approximate &lt;/li&gt;
&lt;li&gt;Ownership gets unclear 
Now your execution differs from your plan.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The real issue&lt;/strong&gt;&lt;br&gt;
A Gantt chart is &lt;strong&gt;visual.&lt;/strong&gt;&lt;br&gt;
But execution tools need &lt;strong&gt;structured tasks.&lt;/strong&gt;&lt;br&gt;
If you don’t convert properly, you lose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sequencing &lt;/li&gt;
&lt;li&gt;dependencies &lt;/li&gt;
&lt;li&gt;timing logic &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What a proper conversion should include&lt;/strong&gt;&lt;br&gt;
Each Gantt item should become a ticket with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clear ownership &lt;/li&gt;
&lt;li&gt;start + end window &lt;/li&gt;
&lt;li&gt;dependency links &lt;/li&gt;
&lt;li&gt;step context (design / build / test / deploy) 
Not just:
“Build API”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What most teams miss&lt;/strong&gt;&lt;br&gt;
They recreate tickets manually, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;don’t preserve order &lt;/li&gt;
&lt;li&gt;don’t link dependencies &lt;/li&gt;
&lt;li&gt;don’t reflect real capacity 
So the timeline starts drifting on day 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Better approach&lt;/strong&gt;&lt;br&gt;
Your plan should be:&lt;br&gt;
&lt;strong&gt;1 model → multiple outputs&lt;/strong&gt;&lt;br&gt;
Meaning that the same structure generates: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gantt &lt;/li&gt;
&lt;li&gt;tickets &lt;/li&gt;
&lt;li&gt;timeline &lt;/li&gt;
&lt;li&gt;team schedule 
No duplication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Example of a delivery plan generating tickets and exports.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;This is from &lt;a href="https://motionode.com" rel="noopener noreferrer"&gt;Motionode&lt;/a&gt;, where the same delivery model generates timelines, tickets, and exports.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focmtinuycppoqhpsrkge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focmtinuycppoqhpsrkge.png" alt="Gantt to Tickets - Motionode" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple rule&lt;/strong&gt;&lt;br&gt;
If your tickets were not generated from the same structure as your Gantt:&lt;br&gt;
Your execution plan is already outdated.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;
Gantt → tickets is not copy/paste.&lt;br&gt;
It’s a &lt;strong&gt;model transformation problem.&lt;/strong&gt;&lt;br&gt;
Solve it once, or manually fix it forever.&lt;/p&gt;




&lt;p&gt;Related: &lt;a href="https://dev.to/oscarcaldera/how-to-compare-team-capacity-before-committing-to-a-software-deadline-1ho6"&gt;How to compare team capacity before committing to a deadline&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to compare team capacity before committing to a software deadline</title>
      <dc:creator>Oscar Caldera</dc:creator>
      <pubDate>Fri, 27 Mar 2026 18:10:49 +0000</pubDate>
      <link>https://dev.to/oscarcaldera/how-to-compare-team-capacity-before-committing-to-a-software-deadline-1ho6</link>
      <guid>https://dev.to/oscarcaldera/how-to-compare-team-capacity-before-committing-to-a-software-deadline-1ho6</guid>
      <description>&lt;p&gt;&lt;strong&gt;What most people expect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Change the team → change the timeline.&lt;/p&gt;

&lt;p&gt;More devs → faster delivery.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What actually happens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In many cases, the timeline barely changes.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;strong&gt;Same duration. Very different execution risk.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The total work stays the same&lt;/li&gt;
&lt;li&gt;The steps are still sequential (design → build → test → deploy)&lt;/li&gt;
&lt;li&gt;Someone still has to do each step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of reducing time, you just redistribute it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What really changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different team setups change how your project behaves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;idle time between steps&lt;/li&gt;
&lt;li&gt;how busy each person is&lt;/li&gt;
&lt;li&gt;how much coordination is needed&lt;/li&gt;
&lt;li&gt;where bottlenecks appear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not necessarily the final date.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What this looks like in practice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qzgvmill50z77tpnewj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qzgvmill50z77tpnewj.png" alt="Calculate team options - Motionode" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;This is from &lt;a href="https://motionode.com" rel="noopener noreferrer"&gt;Motionode&lt;/a&gt;, where you can simulate different team setups and expose execution risk, even when the timeline stays the same.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can run 3 different team setups and still get ~4 weeks.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gxk6456gjah6ounw724.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gxk6456gjah6ounw724.png" alt="Simulation results - Motionode" width="800" height="728"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one has overloaded devs&lt;/li&gt;
&lt;li&gt;one has idle time&lt;/li&gt;
&lt;li&gt;one has smoother flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why many projects don’t fail because of bad estimates. They fail because the execution model was never stress-tested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your planning process only outputs a date,&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;you’re missing the part that actually determines whether you hit it.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Related: &lt;a href="https://dev.to/oscarcaldera/how-to-turn-a-gantt-chart-into-tickets-for-jira-asana-monday-5fci"&gt;How to turn a Gantt chart into execution-ready tickets&lt;/a&gt;&lt;/p&gt;

</description>
      <category>management</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
