<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Tools · Loosely Decoupled</title>
    <link>https://looselydecoupled.com/tools/</link>
    <description>Small interactive tools for decisions that get argued about with made-up numbers. Each one shows its formula, states what it assumes, and names what it deliberately does not model.</description>
    <language>en-us</language>
    
    <copyright>© 2026 Emmanuel Tsouris</copyright>
    <lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://looselydecoupled.com/tools/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Dependency map</title>
      <link>https://looselydecoupled.com/tools/dependency-map/</link>
      <guid isPermaLink="true">https://looselydecoupled.com/tools/dependency-map/</guid>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <dc:creator>Emmanuel Tsouris</dc:creator>
      
      <description>What stops when one thing stops, and which handoffs are held together by a person? Enter your dependencies and the map is laid out from them — nothing is dragged.</description>
      <content:encoded><![CDATA[<h2 id="how-the-layout-is-derived">How the layout is derived<a class="heading-anchor" href="https://looselydecoupled.com/tools/dependency-map/#how-the-layout-is-derived"
     aria-label="Link to section: How the layout is derived" data-pagefind-ignore></a>
</h2>
<p>A node&rsquo;s column is its longest distance from a node nothing feeds. Sources sit
left, consumers right, and a cycle is reported rather than drawn — a
dependency graph with a loop in it is a finding, not a rendering problem.</p>
<h2 id="what-it-assumes">What it assumes<a class="heading-anchor" href="https://looselydecoupled.com/tools/dependency-map/#what-it-assumes"
     aria-label="Link to section: What it assumes" data-pagefind-ignore></a>
</h2>
<p>That you can name every piece. The value of the exercise is mostly in
discovering that you cannot: the map people draw from memory is reliably
missing one vendor and one spreadsheet.</p>
<p>That &ldquo;fragile&rdquo; is a judgement you are willing to write down. Marking a handoff
dashes its line and lists it in prose beneath the map, so the claim carries a
reason and not just a colour.</p>
<h2 id="what-it-does-not-model">What it does not model<a class="heading-anchor" href="https://looselydecoupled.com/tools/dependency-map/#what-it-does-not-model"
     aria-label="Link to section: What it does not model" data-pagefind-ignore></a>
</h2>
<p>Latency, volume, cost, redundancy or failure probability. It answers one
question — what is downstream of this — and a map that tried to answer the
others would answer none of them legibly.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Build vs. buy workbench</title>
      <link>https://looselydecoupled.com/tools/build-vs-buy/</link>
      <guid isPermaLink="true">https://looselydecoupled.com/tools/build-vs-buy/</guid>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <dc:creator>Emmanuel Tsouris</dc:creator>
      
      <description>Which option holds up once maintenance and switching cost are weighted the way your team feels them? A weighted matrix that shows which weight changes the answer.</description>
      <content:encoded><![CDATA[<h2 id="how-the-total-is-calculated">How the total is calculated<a class="heading-anchor" href="https://looselydecoupled.com/tools/build-vs-buy/#how-the-total-is-calculated"
     aria-label="Link to section: How the total is calculated" data-pagefind-ignore></a>
</h2>
<p>Each score is multiplied by its criterion&rsquo;s weight, and the products are
summed. A blank cell removes that criterion from the option&rsquo;s total and from
the maximum it is measured against, so an unknown does not quietly count as a
zero — an option nobody has evaluated should not lose on that basis.</p>
<p>Because options can be scored against different numbers of criteria, the
totals are reported as a percentage of each option&rsquo;s own available maximum.
No option is called the leader unless it is clear of the next one by more than
five points; below that the matrix is telling you the decision is a tie, and
printing a winner would be inventing precision the scores do not have.</p>
<h2 id="what-it-assumes">What it assumes<a class="heading-anchor" href="https://looselydecoupled.com/tools/build-vs-buy/#what-it-assumes"
     aria-label="Link to section: What it assumes" data-pagefind-ignore></a>
</h2>
<p>That the criteria are independent. They are not: time to first release and
ongoing maintenance usually trade against each other, and scoring both high
for the same option is a sign the scores are aspirational rather than
observed.</p>
<p>That a weighted total is a prompt, not a verdict. The useful output is the
moment the leader changes when you move one weight by one point — that tells
you which disagreement the decision actually rests on.</p>
<h2 id="what-it-does-not-model">What it does not model<a class="heading-anchor" href="https://looselydecoupled.com/tools/build-vs-buy/#what-it-does-not-model"
     aria-label="Link to section: What it does not model" data-pagefind-ignore></a>
</h2>
<p>Cost in money, timelines, staffing, or the risk that the vendor is acquired.
It also cannot model the thing that decides most of these arguments in
practice, which is whether the team wants to build it.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Meeting cost calculator</title>
      <link>https://looselydecoupled.com/tools/meeting-cost/</link>
      <guid isPermaLink="true">https://looselydecoupled.com/tools/meeting-cost/</guid>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <dc:creator>Emmanuel Tsouris</dc:creator>
      
      <description>What does one recurring meeting cost over a year, and what would changing its cadence save? Enter your own numbers and compare three cadence alternatives against them.</description>
      <content:encoded><![CDATA[<h2 id="how-this-is-calculated">How this is calculated<a class="heading-anchor" href="https://looselydecoupled.com/tools/meeting-cost/#how-this-is-calculated"
     aria-label="Link to section: How this is calculated" data-pagefind-ignore></a>
</h2>
<p>One multiplication, stated in full so you can check it against your own
spreadsheet rather than trusting the box above.</p>
<p class="tool-formula figures">attendees &times; (minutes &divide; 60) &times; loaded hourly cost &times; occurrences per year</p>
<p>Attendee hours are reported separately because they are the figure a manager
can act on. A cost can be argued away as sunk; four hundred hours cannot.</p>
<h2 id="what-it-assumes">What it assumes<a class="heading-anchor" href="https://looselydecoupled.com/tools/meeting-cost/#what-it-assumes"
     aria-label="Link to section: What it assumes" data-pagefind-ignore></a>
</h2>
<p>That everyone invited attends, for the whole meeting, and that their time has
one price. All three are wrong in detail and close enough in aggregate: a
half-attending director and a fully-attending engineer roughly cancel out.</p>
<p>That the default $95 loaded hourly cost is a placeholder and nothing more. It
is not a benchmark, it is not sourced from a salary survey, and the tool does
not pretend otherwise — replace it with your own organisation&rsquo;s figure before
quoting any number from this page.</p>
<h2 id="what-it-deliberately-does-not-model">What it deliberately does not model<a class="heading-anchor" href="https://looselydecoupled.com/tools/meeting-cost/#what-it-deliberately-does-not-model"
     aria-label="Link to section: What it deliberately does not model" data-pagefind-ignore></a>
</h2>
<p>Preparation and follow-up, context switching either side of the meeting, the
value of the decisions the meeting produces, and the cost of the meeting not
happening. The first two make the real cost higher; the second two are the
reason a high number is not automatically an argument for cancelling.</p>
<div class="admonition admonition--note" role="note">
  <p class="admonition__label">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="https://looselydecoupled.com/tools/meeting-cost/#i-info"/></svg>
    <span>Note</span>
  </p>
  <p>Read the number as a floor. Every omission above pushes the true figure up,
so treat the output as the cheapest this meeting could possibly be.</p>
</div>]]></content:encoded>
    </item>
    
  </channel>
</rss>
