<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://seankilleen.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://seankilleen.com/" rel="alternate" type="text/html" /><updated>2026-03-14T06:15:37+00:00</updated><id>https://seankilleen.com/feed.xml</id><title type="html">SeanKilleen.com</title><subtitle>Ramblings on bytes and life.</subtitle><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><entry><title type="html">Thoughts on Picking Up Trash</title><link href="https://seankilleen.com/2025/05/thoughts-on-picking-up-trash/" rel="alternate" type="text/html" title="Thoughts on Picking Up Trash" /><published>2025-05-02T01:41:00+00:00</published><updated>2025-05-02T01:41:00+00:00</updated><id>https://seankilleen.com/2025/05/thoughts-on-picking-up-trash</id><content type="html" xml:base="https://seankilleen.com/2025/05/thoughts-on-picking-up-trash/"><![CDATA[<p>We got a two pack of <a href="https://www.amazon.com/dp/B0CSDHMN1Y">those grabbers that pick things up</a> (not an affiliate link; just for reference). Recently I’ve been inspired to go on walks at night with one of the grabbers and a trash bag.</p>

<p>This is a collection of unordered thoughts I’ve had while picking up some trash.</p>

<hr />

<ul>
  <li>This was easier to get into than I thought. It feels good, and makes the moderate exercise feel purposeful, which makes it more appealing than it would be on its own.</li>
  <li>I didn’t realize how much more mindful and in the moment I’d be when doing this. I’m not thinking about work or current events; I’m just walking and looking for the next piece of trash to pick up. I’m noticing nature. I’m noticing parts of my neighborhood.</li>
  <li>The human mind is phenomenal at spotting patterns. I’ve come to appreciate just how quickly our brains are able to highlight things like trash against the surroundings.</li>
  <li>It’s absolutely a privilege that I have to be able to walk around, often around dark, often with headphones in.</li>
  <li>While I might pick up a bag of trash on a given trip, I’m also struck by, and appreciative of, how nice our neighborhood is, and how generally effective our tax dollars are. I know that’s a privilege, too.</li>
  <li>Doing anything that benefits our community has the potential to add up. With everything in the world, it’s so easy to feel defeated. It’s good to have a reminder that you can do something from right where you are to make something a little better, with no interference.</li>
  <li>Virtuous cycles are so important to my wellbeing. When I pick up trash, I’m more eager to walk. When I walk more, I drink more water. When I walk and drink more water, I drink less things I shouldn’t (beer, coffee, etc.) when those things collectively improve, I sleep better, so I have more energy to walk. I can sense negative cycles more easily than positive ones; it’s nice to notice the positive ones sometimes.</li>
  <li>There will always be someone who wants to sneer at you. I was sweating on a hot night walking with a full bag of trash when a woman signaled to me. I took my headphones off, only for her to say “Is that the first time you’re doing that in your life?” I get it; some people (OK, lots of us) are having a hard time, and some need to feel like they’ve got a leg up by putting someone else down. To some people, I fit the profile of the folks who are currently in charge of the government<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>. It’s a good reminder to believe in what you do and to try to be there for your community in ways big and small, regardless of what people say or how they react. We’re all in this together. I hope that woman had a better night after that.
    <ul>
      <li>PS I’ve found the best cure for comments like this is to play dumb and say “Sorry, I don’t understand?” Because in order to explain the joke, someone has to essentially explain that they were being mean to you for no reason despite you doing a good thing and not bothering anyone. It seems to cause some introspection.</li>
    </ul>
  </li>
  <li>Related to the point above: there are certainly less white dudes like me out there doing any kind of public service than there should be. A good reminder to show up more, and publicly.</li>
  <li>It bothered me at first to feel like I missed any trash as I went by (oh hey there, perfectionism!) But doing it multiple times has helped me see the long game and allowed me to not get so hung up on every piece. The trash bag gets filled up with trash that’s just as real as the piece I missed.</li>
  <li>I’m so digital in my work and life that I often forget to do tangible things with real-world outcomes. A full bag at the end of a walk feels good.</li>
  <li>It feels silly to write about this. But when I thought about why that is, I realized it’s because it feels like something that someone would put in a bullshit LinkedIn post to try to up their follower count or something. Capitalism has screwed up so much about being a person. But this is my space, and my feelings are real, so I get to write about it. And it’s nice to remember that my audience is allowed to also be just me.<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></li>
</ul>

<p>I’m not sure if I’ll inspire anyone else to do this, but I’ve become convinced that I and the world are both a little better off for doing it. And I know it’s possible to be inspired, because one day last year I saw a guy walking down the street a few times with a grabber and I thought “hey, that’s a great idea.” And I hope that guy looks around on his walks now sometimes and thinks “hmm, there’s less trash than there used to be.”</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>Yeah, NOPE. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>While at the same time realizing I’m absolutely going to post this on Bluesky, and probably LinkedIn. Whatever. I contain multitudes. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="personal" /><category term="mindfulness" /><category term="service" /><summary type="html"><![CDATA[We got a two pack of those grabbers that pick things up (not an affiliate link; just for reference). Recently I’ve been inspired to go on walks at night with one of the grabbers and a trash bag.]]></summary></entry><entry><title type="html">[Field Notes] Troubleshooting .NET OpenTelemetry SDK: Why Can’t I see My App’s Metrics?</title><link href="https://seankilleen.com/2025/02/field-notes-troubleshooting-net-opentelemetry-sdk-why-cant-i-see-my-apps-metrics/" rel="alternate" type="text/html" title="[Field Notes] Troubleshooting .NET OpenTelemetry SDK: Why Can’t I see My App’s Metrics?" /><published>2025-02-03T14:00:00+00:00</published><updated>2025-02-03T14:00:00+00:00</updated><id>https://seankilleen.com/2025/02/field-notes-troubleshooting-net-opentelemetry-sdk-why-cant-i-see-my-apps-metrics</id><content type="html" xml:base="https://seankilleen.com/2025/02/field-notes-troubleshooting-net-opentelemetry-sdk-why-cant-i-see-my-apps-metrics/"><![CDATA[<h2 id="challenge">Challenge</h2>

<p>I have a .NET app that runs in a Linux container. I was instrumenting this app with OpenTelemetry to push metrics to an OpenTelemetry Collector container (“otel-collector”). Locally, I have a docker-compose setup that spins up the otel-collector, Prometheus, and Grafana.</p>

<p>I had everything set up as I remembered it working (and where I had past working examples). But for some reason, nothing seemed to be hitting the otel-collector. I enabled the console exporter for OpenTelemetry metrics, and saw metrics being generated by the app.</p>

<p>I couldn’t figure out how to understand what was happening between the time the .NET OTel SDK generated the metric and when it should arrive to the otel-collector. I enabled verbose logging in my otel-collector config:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">exporters</span><span class="pi">:</span>
  <span class="na">debug</span><span class="pi">:</span>
    <span class="na">verbosity</span><span class="pi">:</span> <span class="s">detailed</span>
</code></pre></div></div>

<p>But I still saw nothing.</p>

<h2 id="opentelemetry-net-sdk-self-diagnosis-to-the-rescue">OpenTelemetry .NET SDK Self-Diagnosis to the Rescue</h2>

<p>Fortunately, I found <a href="https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#troubleshooting">this troubleshooting document</a> that describes how to get some OTel SDK self-diagnostics in place.</p>

<ul>
  <li>Open a terminal session in the container – this should open in the app’s working directory (<code class="language-plaintext highlighter-rouge">/app</code> in my case)</li>
  <li><code class="language-plaintext highlighter-rouge">echo '{"LogDirectory":".","FileSize":32768,"LogLevel":"Verbose"}' &gt;&gt; OTEL_DIAGNOSTICS.json</code> creates a JSON file that tells the SDK to output diagnostics</li>
</ul>

<p>At this point, I saw a file called <code class="language-plaintext highlighter-rouge">dotnet.572.log</code> appear. I had diagnostics!</p>

<h2 id="the-real-problem-a-breaking-change-id-missed">The Real Problem: A Breaking Change I’d Missed</h2>

<p>Now that I had a diagnostic log, I could easily see the issue:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">2025-01-10T03:50:19.5070301Z:Exporter failed send data to collector to {0} endpoint. Data will not be sent. Exception: {1}{http://host.docker.internal:4317/}{Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake. (InvalidResponse) HttpIOException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake. (InvalidResponse) HttpIOException: The response ended prematurely while waiting for the next frame from the server. (ResponseEnded)", DebugException="System.Net.Http.HttpRequestException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake. (InvalidResponse)")
</span></code></pre></div></div>

<p>Well, that’s not great! However, a quick search led me to a GitHub issue that could help: <a href="https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33896">https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33896</a></p>

<p>In that issue, it was noted that as of v0.104.0 of the OTel Collector, I’d have to bind to all network interfaces in order to enable my past behavior. There was <a href="https://opentelemetry.io/blog/2024/hardening-the-collector-one/">a blog post</a> and everything. I totally missed it!</p>

<h2 id="the-solution">The Solution</h2>

<p>The proposed solution was fine with me – this particular implementation is something I only care about in a local dev environment.</p>

<p>In my <code class="language-plaintext highlighter-rouge">otel-collector.yaml</code> settings file, I changed my receivers from the default:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">receivers</span><span class="pi">:</span>
  <span class="na">otlp</span><span class="pi">:</span>
    <span class="na">protocols</span><span class="pi">:</span>
      <span class="na">grpc</span><span class="pi">:</span>
      <span class="na">http</span><span class="pi">:</span>
</code></pre></div></div>

<p>to:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">receivers</span><span class="pi">:</span>
  <span class="na">otlp</span><span class="pi">:</span>
    <span class="na">protocols</span><span class="pi">:</span>
      <span class="na">grpc</span><span class="pi">:</span>
        <span class="na">endpoint</span><span class="pi">:</span> <span class="s">0.0.0.0:4317</span>
      <span class="na">http</span><span class="pi">:</span>
        <span class="na">endpoint</span><span class="pi">:</span> <span class="s">0.0.0.0:4318</span>
</code></pre></div></div>

<p>This bound to all network addresses. Lo and behold, with a restart of the otel-collector, I saw the verbose logs in .NET now indicate that metrics were being published, and I saw the verbose otel-collector logs showing that metrics were now being received. I was also able to see the metrics in Prometheus.</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="dotnet" /><category term=".net" /><category term="opentelemetry" /><category term="otel" /><category term="otel-collector" /><category term="docker" /><category term="field-notes" /><summary type="html"><![CDATA[Challenge]]></summary></entry><entry><title type="html">Farewell, SpecFlow. Gáspár Nagy Saves the Day with Reqnroll!</title><link href="https://seankilleen.com/2025/01/farewell-specflow-gaspar-nagy-saves-the-day-with-reqnroll/" rel="alternate" type="text/html" title="Farewell, SpecFlow. Gáspár Nagy Saves the Day with Reqnroll!" /><published>2025-01-27T14:00:00+00:00</published><updated>2025-01-27T14:00:00+00:00</updated><id>https://seankilleen.com/2025/01/farewell-specflow-gaspar-nagy-saves-the-day-with-reqnroll</id><content type="html" xml:base="https://seankilleen.com/2025/01/farewell-specflow-gaspar-nagy-saves-the-day-with-reqnroll/"><![CDATA[<p>This is a quick appreciation post.</p>

<p>I became enamored with the idea of <a href="https://cucumber.io/docs/gherkin/reference">gherkin-based</a> testing and writing human-readable examples that translated to code a long time ago. I think it was the excellent book on <a href="https://www.manning.com/books/specification-by-example">Specification by Example</a> that first got me really thinking about it.</p>

<p>One of the bigger successes in my career came from using this technique. We were running a retirement benefit system with a ton of complex calculations where the stakes were high. We had to make some major changes, and even though there were automated tests, those weren’t understandable (understandably!) to the business professionals who were responsible for the outcome. They wanted 9 months to test the changes, to ensure there would be no issues. Instead, we were able to work toward a ubiquitous language for describing the actions that this calculation logic took. Once those were in place, we published the specs that we had created, and invited the business folks to come up with as many exhaustive examples as they could. We were able to easily incorporate new examples. In the end, we made changes with a high degree of shared confidence and saved the entirety of that designated testing time. I was hooked.</p>

<p>The de facto tool for accomplishing this in .NET for a long time was <a href="https://specflow.org/">SpecFlow</a>. It was easy to use, had great tooling, great docs, and a really helpful team.</p>

<h2 id="specflow-a-tragic-oss-tale">SpecFlow: A Tragic OSS tale</h2>

<p>(<em>Ed. Note:</em> to be clear, this is from an outside observer’s perspective.)</p>

<p>SpecFlow was a labor of love for a few key contributors and a vibrant community surrounding them. They had a phenomenal OSS product, and commercial offerings and tooling built around that OSS.</p>

<p>Then, they were acquired by Tricentis, a company that provides test automation products. At the time, I very much considered this A Good Thing™️. The authors deserved any kind of payday, and Tricentis promised to keep things open-source and moving along.</p>

<p>Tricentis then basically, over a long time, slapped the community in the face. Contributions and forward motion stopped and it was impossible to get a read on the state of the project. Then, not only did Tricentis announce a very small window of time to shut down the project, but it deleted the SpecFlow repository from GitHub. It could have chosen to open up all the tooling and archive it, but instead it did the selfish business thing that helped nobody. (Do you hear that sound? It’s me crossing Tricentis off from the vendors I’ll ever consider working with).</p>

<p>So, in a tale as old as time, an OSS project that seemed to have a great path to commercialization was instead rotted by corporate interests.</p>

<h2 id="enter-gáspár-nagy-and-reqnroll">Enter Gáspár Nagy and Reqnroll</h2>

<p><a href="https://gasparnagy.com/">Gáspár Nagy</a> was one of the prior creators of SpecFlow. He saw the stagnation in the repository and the writing on the wall a year in advance. Rather than writing it off or waiting, he got to work on behalf of the community. He created <a href="https://reqnroll.net/">Reqnroll</a> to fill the gap, and it does so very well.</p>

<p>It is <em>amazing</em> how easy it was for me to switch my current org’s codebase from SpecFlow to Reqnroll – a lot of care was taken for users to achieve that. The whole thing took me around 20 minutes.</p>

<h2 id="with-great-oss-comes-great-responsibility">With Great OSS Comes Great Responsibility</h2>

<p>I didn’t notice what was happening with SpecFlow because I was in “consumer mode” with it. I’d become complacent and took the tool for granted. I had stopped checking in on the GitHub repo. I wasn’t following the creators online as closely as I should have. So I didn’t see what was happening and couldn’t contribute. This was less than ideal from both and community perspective and even a supply chain perspective for my organization.</p>

<p>I’m trying to fix that this go-round. I’m following the creators, I’m subscribed to the repo, I’m meandering my way through a PR, and I’m trying to pay attention to where help is needed. I’m also looking to create some donation infrastructure in my current organization.</p>

<h2 id="in-closing-gratitude">In Closing: Gratitude</h2>

<p>I am grateful to SpecFlow for the time was here and what it enabled me and others to accomplish for so long.</p>

<p>I am beyond grateful to Gáspár for saving this important tooling for the community and building a bridge while many of us hadn’t even realized the last one was burning.</p>

<p>And I am grateful for the reminder, once again, that if we want OSS community, we have to build it and sustain it.</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="OSS" /><category term="SpecFlow" /><category term=".net" /><category term="dotnet" /><category term="testing" /><category term="community" /><summary type="html"><![CDATA[This is a quick appreciation post.]]></summary></entry><entry><title type="html">My New Reading Workflow</title><link href="https://seankilleen.com/2025/01/my-new-reading-workflow/" rel="alternate" type="text/html" title="My New Reading Workflow" /><published>2025-01-20T14:00:00+00:00</published><updated>2025-01-20T14:00:00+00:00</updated><id>https://seankilleen.com/2025/01/my-new-reading-workflow</id><content type="html" xml:base="https://seankilleen.com/2025/01/my-new-reading-workflow/"><![CDATA[<p>I absolutely love reading. Lately, a few things have been happening:</p>

<ul>
  <li>I’ve been pretty busy, which has stopped me from feeling like I could really dig into something long-form</li>
  <li>I’ve been looking at a screen too much, so my eyes have been tired at times when I might otherwise read something on my phone</li>
  <li>My phone has offered too many distractions and I felt like I wasn’t fully engaging with what I was reading.</li>
  <li>My unread articles in Pocket had been piling up to the point where it started to feel silly to save them.</li>
</ul>

<p>Recently, I discovered an app, <a href="https://p2k.co">https://p2k.co</a>, and revamped my workflow in a way that is absolutely delightful to me. I’ve read hundreds of articles, I feel better before bed, my eyes have gotten a break, and I’ve felt better about engaging with things.</p>

<p>So, here’s what I do now!</p>

<h2 id="my-current-short-form-reading-process">My Current Short-form Reading Process</h2>

<ul>
  <li>All my incoming RSS Feeds and newsletters come into <a href="https://feedly.com">Feedly</a>, which I happily pay for.</li>
  <li>Feedly integrates with <a href="https://getpocket.com">Pocket</a>. When I see an article I want to save, I click a button on the article to save it to Pocket. I tag it with “kindle” if I know I’ll want to read it on my Kindle.</li>
  <li>I scan/skim through articles in Pocket. Where it seems I want to read it in a more relaxed / focused space and it’s possible to do so, I tag the article with “kindle”.</li>
  <li>I have a process set up in P2K (which stands for Pocket to Kindle). Every day, it bundles up 10 random Pocket saves that are tagged “kindle”, creates a book, and sends it to my Kindle. It then archives those items in Pocket. (All of this is configurable to user preferences.)</li>
  <li>As the opportunity presents itself, I read the articles on my Kindle. I take notes and highlights, just as I would in a normal Kindle book.</li>
  <li>I review the notes occasionally and create tasks if I want to.</li>
</ul>

<p>This process has brought me so much joy in the few weeks I’ve been using it. I’m reading more, looking at my phone less, and feeling better about reading things I save. It energized me to go through literal years of saved articles in Pocket. I have several 10-article books’ worth of content to get through at a given time. Forcing myself to read the articles in order like a book has been a great way to get my brain to slow down and stop trying to skim everything. And the random nature of the process means that I get a variety of content from a long time range, which I appreciate.</p>

<p>If you like reading as much as I do, I hope this might delight you as well. How do you set up your reading flow? Let me know in the comments!</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="personal" /><category term="productivity" /><category term="reading" /><summary type="html"><![CDATA[More delight in a personal process.]]></summary></entry><entry><title type="html">My OSS “Social Contract”</title><link href="https://seankilleen.com/2025/01/my-oss-social-contract/" rel="alternate" type="text/html" title="My OSS “Social Contract”" /><published>2025-01-16T14:00:00+00:00</published><updated>2025-01-16T14:00:00+00:00</updated><id>https://seankilleen.com/2025/01/my-oss-social-contract</id><content type="html" xml:base="https://seankilleen.com/2025/01/my-oss-social-contract/"><![CDATA[<p>I’ve spoken about this in fragments online and <a href="https://seankilleen.com/2023/08/on-moq-and-our-part-in-the-oss-sustainability-social-contract/">eluded to it in other blog posts</a>, so I figured I’d spell it out here.</p>

<h2 id="resources-within-the-oss-ecosystem">Resources Within the OSS Ecosystem</h2>

<p>As a possible participant in the OSS ecosystem, I feel we have three possible resources:</p>

<ul>
  <li>Money</li>
  <li>Time</li>
  <li>Gratitude/Grace</li>
</ul>

<p>To be a participant in an OSS project, you must be contributing one of those three items. You might contribute money in the form of donations/sponsorship/licenses (if requested). You might contribute time in the form of pull requests, documentation, thoughtful discussion, or picking up administrative work like triaging issues (if requested). Or, you can be grateful for all the impact you’ve received from something despite it not being appropriately supported, and understanding if the direction of that changes. And you can extend grace to OSS authors when they do something you disagree with.</p>

<p>So often, people and organizations are unwilling to contribute time/money, and somehow still exempt themselves from the last bullet point.</p>

<h2 id="why-do-people-forget-about-such-an-important-resource">Why Do People Forget About Such an Important Resource?</h2>

<p>There could be a lot of reasons that people forget about gratitude. Perhaps they’ve built a reputation for themselves within their org as a person who gets things done well (in part because of a tool) or who knows tools to help the organization, and they don’t want that reputation to be called into question. Perhaps they have used something for so long that they come to see it (incorrectly) as their own. Perhaps they simply don’t like the feeling of change and don’t know where to place that emotion. Perhaps they do not like to see their own lack of contribution to the project reflected back to them in the situation they now face.</p>

<p>But so often, as we’ve seen, it is the sense that an OSS author’s purpose is to create a free lunch for everyone else, making sure that nobody else has to think about it too hard, while simultaneously receiving very little help/support. Sometimes, they try to hide these feelings behind the idea of a “supply chain” and the threat it would pose if the tool went away, which misses the entire point.</p>

<h2 id="if-youre-not-in-a-community-your-opinion-on-its-direction-is-irrelevant">If You’re Not in a Community, Your Opinion on its Direction is Irrelevant.</h2>

<p>But here’s the thing – if you’re not contributing your time or your money to an OSS project, your say in that project is exactly zero. And if you’re not responding to a major change with gratitude as you move away from the tool, or grace as you work through the issue, you’re not a member of that OSS project community, and aren’t acting as an OSS community member at all. You’re acting like a leech, which makes you part of the problem – and anyone invested in a solution would be best served by ignoring you entirely.</p>

<p>In terms of the supply chain, I think <a href="https://www.softwaremaxims.com/blog/not-a-supplier">Thomas Depierre sums it up well in his blog post “I am not a supplier”</a>:</p>

<blockquote>
  <p>Now, I am more than happy to become a supplier. You want me to work a certain way, I am more than happy to do it. But to do that, I am going to have to become a supplier. Which means you are going to have to start to pay me. A fair price, that we can negotiate. Under a different license.</p>

  <p>Until then, I am not your supplier. So all your Software Supply Chain ideas? You are not buying from a supplier, you are a raccoon digging through dumpsters for free code.</p>
</blockquote>

<h2 id="how-this-plays-out-for-me">How This Plays Out for Me</h2>

<ul>
  <li>I try to contribute where I can, to projects and people I care about or appreciate and want to support. It will never be as much as I want; I, too, have to balance my priorities in life across my personal/family life, work, and extracurricular activities.</li>
  <li>When Moq changed its approach to seeking donations using SponsorLink, I <a href="https://seankilleen.com/2023/08/on-moq-and-our-part-in-the-oss-sustainability-social-contract/">respected what they were trying to accomplish</a>. Our team at work evaluated the change, and felt fine with sticking with the project unless something made it untenable. To that point, I hadn’t contributed to the project. After that, I made a donation.</li>
  <li>When <a href="https://github.com/fluentassertions/fluentassertions/pull/2943">Fluent Assertions changed to a dual license that required a license purchase for commercial use</a>, our team evaluated it as a product. We came to the conclusion that the value we were getting didn’t justify the proposed licensing cost, so we are choosing to remove it. But we’re not mad at having to make the choice, because we didn’t contribute anything to that point, and it’s only fair for the author to consider what they need.</li>
</ul>

<p>My perspective on the OSS social contract allowed me to do a few things in those situations:</p>

<ul>
  <li>Pay more attention to my OSS dependencies</li>
  <li>Look to support OSS in more ways, proactively, before these things come up</li>
  <li>Channel my disappointment / inconvenience in a productive way</li>
  <li>Remain thankful for – and thus aware of – all the value and impact I’ve been lucky to receive, for free, because someone else cared enough to nurture that into being.</li>
</ul>

<h2 id="why-did-i-write-this">Why Did I Write This?</h2>

<p>I don’t know, honestly. So many of us have seen these situations play out time and time again. I guess if I can change even one person’s perspective on this and bend the arc away from consumption and toward contribution, I’ll consider it worthwhile.</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="dotnet" /><category term="oss" /><category term="culture" /><summary type="html"><![CDATA[I’ve spoken about this in fragments online and eluded to it in other blog posts, so I figured I’d spell it out here.]]></summary></entry><entry><title type="html">How to be a Ghostbuster</title><link href="https://seankilleen.com/2025/01/how-to-be-a-ghostbuster/" rel="alternate" type="text/html" title="How to be a Ghostbuster" /><published>2025-01-13T14:00:00+00:00</published><updated>2025-01-13T14:00:00+00:00</updated><id>https://seankilleen.com/2025/01/how-to-be-a-ghostbuster</id><content type="html" xml:base="https://seankilleen.com/2025/01/how-to-be-a-ghostbuster/"><![CDATA[<p>According to some research that was <a href="https://x.com/yegordb/status/1859290734257635439">announced in November</a>, “Ghost developers” are 0.1x<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> devs who barely do any work, and may have multiple jobs. Apparently it’s as high as 9% according to the research. I saw this when <a href="https://twitter.com/Aaronontheweb">Aaron Stannard</a> pointed it out <a href="https://www.linkedin.com/posts/aaronstannard_finally-we-have-a-term-for-the-green-commit-activity-7265391640683397121-KRW4">in a LinkedIn post</a>.</p>

<p>I found that figure striking, given the teams I’ve worked with and worked to build over the years. I don’t know that one of these developers could actually exist in the environments I’ve been lucky enough to be a part of. That such a situation could occur speaks to a massive failure of engineering leadership and process. So, I want to take a little time to dive into how to prevent these sorts of situations from occurring. Let’s become Ghostbusters.</p>

<h2 id="engineering-leaders-need-to-be-able-to-understand-whats-happening">Engineering Leaders Need to be Able to Understand What’s Happening</h2>

<ul>
  <li>You should be able to look at commits, PRs, chats, etc. and know who is participating and who isn’t. If your team is too big or unwieldy for that, solve this problem first so that you can be an effective engineering leader.</li>
  <li>You should be interacting with team members regularly. If you do, your instincts will tell you if there’s somewhere you need to dive deeper around someone’s contributions or growth. You can’t be in the code almost all the time and still be an effective engineering leader.</li>
  <li>You should have some sort of daily communication where the team talks about their work with everyone. Standup meetings are great for this; chat can work too in a pinch. What did someone do yesterday, what did they do today, and where are they stuck? Occasionally follow-up on the claims that are made in these meetings.</li>
  <li>Someone shouldn’t be able to bullshit you. You should know enough about the people and the work that you can verify claims about work.</li>
</ul>

<h2 id="and-they-need-to-be-willing-to-lead">And They Need to be Willing to Lead.</h2>

<p>This means interacting with the people who report to you.</p>

<ul>
  <li>It means coaching and picking up on areas of improvement</li>
  <li>It means setting goals</li>
  <li>It means having hard conversations when an expectation isn’t being met</li>
  <li>It means being visible to team members and asking for feedback for yourself and other teammates that enables the previously mentioned activities.</li>
</ul>

<h2 id="work-shouldnt-be-invisible">Work Shouldn’t be Invisible</h2>

<ul>
  <li>A pull request system makes it clear who is making contributions to the codebase and what they are</li>
  <li>As much as I previously didn’t love ticketing systems (GitHub issues, Jira, etc.) they are a very effective way to show the progress of work (including non-code work) and can be implemented in ways that aren’t painful to use.</li>
  <li>Peers should be checking each others’ work, reasonably often. This is good not just for communicating about and socializing the work and learning from each other, but also helps prevent someone from being able to merge meaningless work.</li>
</ul>

<p>If there isn’t some kind of an artifact or byproduct of the work that’s been done, oftentimes no work has been done at all.<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

<h2 id="it-helps-if-youre-working-on-things-that-matter">It Helps if You’re Working on Things That Matter</h2>

<p>Ghost engineers hide in the places where work doesn’t matter enough to be accountable for it.</p>

<p>If people and teams can be working on things that don’t have enough impact to rate checking to see if folks are showing up to do their job, that’s a problem to solve that might be costing you even more than a ghost engineer’s salary.</p>

<h2 id="quick-digression-github-commits-arent-the-only-type-of-contribution">Quick Digression: GitHub Commits Aren’t the Only type of Contribution.</h2>

<p>I was a little concerned about the way the study seemed to frame the contributions of engineers around specifically commits. So I’d like to push back on those being the primary measure of engineering work / effectiveness. But the other activities can be checked as well:</p>

<ul>
  <li>If devs are pairing/mobbing and therefore not a part of the commit, observe a mob session and see how folks participate.</li>
  <li>If folks are doing docs editing or analysis, make that work visible via tickets or similar systems, or look for the modification history of documents / wikis.</li>
</ul>

<p>My point is – if you’re collecting stats on folks, just remember there’s more than one kind of stat to check. But you can still check them</p>

<h2 id="almost-all-of-the-above-can-be-made-public">Almost all of the above can be made public!</h2>

<p>None of these things need to be hidden from teams or your organization. Your team should embrace transparency as an experiment – if people still actively resist, it’s worth digging deeper.</p>

<p>Examples of transparency from my current team:</p>

<ul>
  <li>We work from tickets on boards that are visible to the whole company. Anyone can look and ask questions.</li>
  <li>We make deployments visible via chat and GitHub releases.</li>
  <li>We send a weekly update on what we’re doing.</li>
  <li>We have a daily standup meeting or chat where we run down the basics (yesterday, today, blockers) and we follow up with each other.</li>
  <li>We use pull requests to show the progress of work. PRs are tied to tickets which are visible on the board to ensure we can all see.</li>
  <li>PRs get reviewed by other developers</li>
</ul>

<p>If someone came to me and said, “what did [x] do last week”, I could provide a concrete answer within minutes.</p>

<p>You could also publish metrics (without attempting to influence them) – PRs/commits per person, tickets closed, etc. I don’t necessarily love this because it could lead to folks trying to game that data, but if I thought I had a ghost developer, it might be a way to root them out.</p>

<h2 id="neither-good-nor-bad-developers-exist-in-a-vacuum">Neither Good Nor Bad Developers Exist in a Vacuum.</h2>

<p>Our workplaces are made up of systems with inputs and outputs. We have to be aware of the systems and leadership that enable the behaviors we want to embrace or improve.</p>

<p>Who you gonna call? Leadership.</p>

<p>I’d love to hear your thoughts on this in the comments.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>Not that I necessarily agree with the idea of 10x devs, but this is used to make a point. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>I say “oftentimes” here because leadership conversations, internal training, design sessions etc. can all have positive impact. However, I would argue that there are also artifacts produced by these activities. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="ghost-developer" /><category term="culture" /><category term="leadership" /><summary type="html"><![CDATA[According to some research that was announced in November, “Ghost developers” are 0.1x1 devs who barely do any work, and may have multiple jobs. Apparently it’s as high as 9% according to the research. I saw this when Aaron Stannard pointed it out in a LinkedIn post. Not that I necessarily agree with the idea of 10x devs, but this is used to make a point. &#8617;]]></summary></entry><entry><title type="html">TIL: Kubernetes Auto-scaling and Requests vs Limits</title><link href="https://seankilleen.com/2025/01/til-kubernetes-auto-scaling-and-requests-vs-limits/" rel="alternate" type="text/html" title="TIL: Kubernetes Auto-scaling and Requests vs Limits" /><published>2025-01-06T14:00:00+00:00</published><updated>2025-01-06T14:00:00+00:00</updated><id>https://seankilleen.com/2025/01/til-kubernetes-auto-scaling-and-requests-vs-limits</id><content type="html" xml:base="https://seankilleen.com/2025/01/til-kubernetes-auto-scaling-and-requests-vs-limits/"><![CDATA[<p>I recently revised an incorrect mental model I had about Kubernetes as part of a strange experience, and I figured I’d share here in case it helps someone else.</p>

<h2 id="background--challenge">Background / Challenge</h2>

<ul>
  <li>I have a Horizontal Pod Auto-scaler set to scale at 80% CPU or 80% RAM, with a minimum of 2 pods and a max of 5.</li>
  <li>I’ve given these pods limits of 1GB RAM (throwing some more resources at a problem temporarily :wink: )</li>
  <li>I recently saw my HPA set the pod count to 3. So I’m curious as to why – maybe these things are just hogging RAM?</li>
  <li>I see the RAM threshold as 84/80 on the HPA, even with 3 pods running</li>
  <li>However, I check our instance of <a href="https://goldilocks.docs.fairwinds.com/">Goldilocks</a> which is giving us recommendations from a vertical pod auto-scaler (in observe-only mode) – and it’s telling me I can set our resources way lower.</li>
  <li>So I run <code class="language-plaintext highlighter-rouge">kubectl top pods --all-namespaces --sort-by=memory</code>
 …and I see the pods are using 145mi, 118mi, 115mi – far from the 1024mi I specified</li>
</ul>

<p>What gives?</p>

<h2 id="first-lesson-learned-horizontal-auto-scaling-works-with-requests-not-limits">First Lesson Learned: Horizontal Auto-scaling Works With Requests, not Limits</h2>

<p>I made the math make sense.</p>

<p>If I request <code class="language-plaintext highlighter-rouge">150mi</code> for each pod, the total requested across all 3 pods is <code class="language-plaintext highlighter-rouge">450mi</code>.</p>

<p>I looked up the other values. 145 + 118 + 115 = 378, which is 84% of 445.</p>

<h2 id="butwhy-the-part-where-i-learn-more-about-requests-vs-limits">But…Why? (the Part Where I Learn More about Requests vs Limits)</h2>

<p>I got a great answer on the <a href="https://randsinrepose.com/welcome-to-rands-leadership-slack/">Rands Leadership Slack</a> – thanks to <a href="https://linkedin.com/in/rbelgrave">Ryan Belgrave</a>. In retrospect, it makes sense – I had the wrong mental model.</p>

<p>In my mind, I was thinking that a pod would ask for more resources, and then this would change its utilization rate, affecting auto-scaling. To do it based on the resource request alone seemed too inflexible.</p>

<p>But where I was going wrong is that the limit, in a sense, doesn’t matter. (Insert Lindsay Lohan gif here). The request defines what the pod should have to run, but if it asks for more memory and none is available, the container will close with an OOM exception.</p>

<p>There probably could be room here to improve horizontal pod auto-scaling to take into account the utilization based on currently granted resources. But I assume there’s a very good reason it’s not that way already, decided by people much better at this than I am.</p>

<p>So, if you need guarantees for your auto-scaling, you need to do it based on requests. What will happen, generally speaking, is:</p>

<ul>
  <li>Memory usage hits the threshold</li>
  <li>Pods horizontally scale and continue to do so as needed</li>
  <li>Those pods may or may not ask for and receive additional resources as needed.</li>
</ul>

<p>For this reason, a lot of people advocate for guaranteed QoS – which is to say, setting the request and the limit to the same value. This way, you will be forced to ask for what your app needs and know that you won’t be getting more. I’m torn on this, because I don’t love the idea of asking for more at the outset that might not be used because I want it available for pods that need it.</p>

<h2 id="id-love-your-thoughts">I’d Love Your Thoughts!</h2>

<p>How do you strategize your pod resource requests and limits? Let me know in the comments!</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="k8s" /><category term="kubernetes" /><category term="devops" /><summary type="html"><![CDATA[I recently revised an incorrect mental model I had about Kubernetes as part of a strange experience, and I figured I’d share here in case it helps someone else.]]></summary></entry><entry><title type="html">What Even Was 2024?</title><link href="https://seankilleen.com/2024/12/what-even-was-2024/" rel="alternate" type="text/html" title="What Even Was 2024?" /><published>2024-12-31T18:00:00+00:00</published><updated>2024-12-31T18:00:00+00:00</updated><id>https://seankilleen.com/2024/12/what-even-was-2024</id><content type="html" xml:base="https://seankilleen.com/2024/12/what-even-was-2024/"><![CDATA[<p><em>Ed. Note: This is a personal post. Comments aren’t on, for a reason.</em></p>

<p>2024 felt like way too much all at once, for almost the entirety of the year. These are in no particular order.</p>

<ul>
  <li>Our 4yo was diagnosed with early onset IBD, likely Crohn’s. This came on in April and wasn’t diagnosed until over 6 months later. In the interim, it was a very difficult time for him (and us), filled with pain and uncertainty about his body, with procedures and blood work. He adapted in many ways – kids are so incredibly adaptable – but it was either a low hum or a blaring alarm in the background of the year for all of us.</li>
  <li>We had a really unfortunate experience with a Pre-K institution who claimed to support the whole child but failed us spectacularly on that front. So, we also had to part ways with a school, leaving us uncertain about where we’ll enroll our guy in the new year.</li>
  <li>My car died. I had a 2013 BMW 3 series with only 80k miles. The transmission went, which it had no right to do. 😆 I loved that car, but I wasn’t about to fork over that kind of money vs getting a new car. It served me well.</li>
  <li>Donald Trump somehow won the election. This will be bad for everyone, except for maybe Donald Trump. These are good days for bad people.</li>
  <li>Israel engaged in genocide, all year. The devastation is incomprehensible, and yet people are forced to live it. There are thousands of children and their promise who are no longer with us. It was on my mind a lot. It’s devastating, and a generational shame that we collectively failed to stop it. The world should never forgive Israel for what they did this year. I won’t.</li>
  <li>I worked a lot. Too much. It was critical to do, but it often left both my wife and I exhausted which is no good for anyone.</li>
  <li>Because of all of the above, I let almost all social relationships lapse. If you’re somehow reading this, it’s absolutely not you, it’s me. Hoping to patch it up in the coming year.</li>
  <li>I also barely got to do the community things I care about. OSS contributions, blog posts, meetups, conferences – it all kind of got set aside this year. Is what it is.</li>
  <li>My fitness and sleep were abysmal. I started tracking it again, which helped toward the end of the year, but obviously combined with everything else, it wasn’t great.</li>
</ul>

<p>Despite all of this, there were bright spots.</p>

<ul>
  <li>While work was hard, it was also the best year of work I’ve ever done. I built an amazing team, and did an incredible amount of work to recover the org from a year of lost progress. We have a cloud platform, in production, running 3 different products, with a team of 7. We have processes for development and operations. We can deliver changes to prod in minutes, safely. I built a huge portion of that this year (my team did a ton too but I can confidently say the platform for our delivery was 95% me). I instituted dozens of processes. I hired some fantastic people who contribute a ton and make me better. I’m excited about the next year there and I’m incredibly proud of what we’ve accomplished and what I’ve contributed. And I managed to avoid burning out for most of the year, because I love the work and the team and the leadership.</li>
  <li>The flip side of a car dying is that there’s a new car. We got a 2025 Honda Accord Touring edition. It’s a hybrid but still fun enough to drive that I don’t miss the BMW. It has all the gadgets and bells and whistles that I could possibly want. I can warm it up from my phone. The touchscreen is huge. Love it so far.</li>
  <li>I moved away from <a href="https://twitter.com/sjkilleen">Twitter</a>, to a combination of <a href="https://mastodon.social/@sjkilleen">Mastodon</a> and <a href="https://bsky.app/profile/seankilleen.com">BlueSky</a>. It led to less social media and healthier engagement with it, which I’m calling a win.</li>
  <li>This is my 5th year as a Microsoft MVP. I would have liked to have done more with it this year, but circumstances simply didn’t allow. But that doesn’t take away my feeling of gratitude for being included in the program and recognized.</li>
  <li>We still had some lovely trips in 2024. An great time in OBX with friends, a really fun family trip to Lancaster.</li>
  <li>I saw Lawrence live in concert. The show was so good that it makes this year’s highlights. Will absolutely be trying to see them whenever they’re in town.</li>
</ul>

<p>So what’s the focus for 2025? I’m not a resolutions person, but I do have some goals.</p>

<ul>
  <li>If the last year at work was “make it happen”, this year at work will be “make it sustainable”.</li>
  <li>I’m hoping family / medical stuff stabilizes enough that I can first get my partner a bit of a break, and then maybe recover some of the joyful community participation that I missed so much this year.</li>
  <li>Building better habits around diet, exercise, and sleep.</li>
  <li>Working to better identify stress levels, work to mitigate them, and ensure I don’t fall back to unhealthy defaults.</li>
</ul>

<p>Dear reader, I wish you – and all of us – health, happiness, and peace in 2025.</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="personal" /><category term="reflection" /><summary type="html"><![CDATA[Ed. Note: This is a personal post. Comments aren’t on, for a reason.]]></summary></entry><entry><title type="html">How to Get Package Updates in Hard-to-Reach Places With RenovateBot</title><link href="https://seankilleen.com/2024/12/how-to-get-package-updates-in-hard-to-reach-places-with-renovatebot/" rel="alternate" type="text/html" title="How to Get Package Updates in Hard-to-Reach Places With RenovateBot" /><published>2024-12-30T14:00:00+00:00</published><updated>2024-12-30T14:00:00+00:00</updated><id>https://seankilleen.com/2024/12/how-to-get-package-updates-in-hard-to-reach-places-with-renovatebot</id><content type="html" xml:base="https://seankilleen.com/2024/12/how-to-get-package-updates-in-hard-to-reach-places-with-renovatebot/"><![CDATA[<h2 id="background">Background</h2>

<p>I’ve adopted <a href="https://docs.renovatebot.com/">RenovateBot</a> in many of my repositories. I’ve found it easier to work with than GitHub’s own Dependabot. Highly recommend checking them and <a href="https://mend.io">Mend.io</a> (their parent company) out.</p>

<p>A challenge I’ve had in a few places has been that package updater tools aren’t always able to detect every location for packages. For example:</p>

<ul>
  <li>In the NUnit Docs repository, we have a reference to the version of NUnit in a build script variable</li>
  <li>In an automated test in a company repo that uses <a href="https://dotnet.testcontainers.org/">TestContainers for .NET</a>, our tests need to use the same version our app does, but the version number is located in a string in the middle of a test.</li>
</ul>

<p>Luckily, RenovateBot has a great way to manage these too!</p>

<h2 id="solution-custom-managers">Solution: Custom Managers</h2>

<p>RenovateBot has a solution for this called custom managers, where you can enter a file type and regex which it will scan for package updates.</p>

<p>In the case of NUnit, where we have a version number for <code class="language-plaintext highlighter-rouge">docfx</code> in a Docker file, I could use the following in my <code class="language-plaintext highlighter-rouge">renovate.json</code> file:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"customManagers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"customType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"regex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"fileMatch"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"^Dockerfile$"</span><span class="p">],</span><span class="w">
      </span><span class="nl">"matchStrings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"docfx --version (?&lt;currentValue&gt;.*?)</span><span class="se">\\</span><span class="s2">n"</span><span class="p">],</span><span class="w">
      </span><span class="nl">"depNameTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"docfx"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"datasourceTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"nuget"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>Let’s break it down. This:</p>

<ul>
  <li>Defines a manager of type Regex, meaning I’ll be checking a string using a Regex matcher.</li>
  <li>Matching only Dockerfile files, so it won’t accidentally be applied to anything else.</li>
  <li>Defining the match string as a Regex that captures the current value of the package. This is so RenovateBot knows what to replace with the new version number.</li>
  <li>The dependency name is hard-coded to <code class="language-plaintext highlighter-rouge">docfx</code> in this case</li>
  <li>And we say that we’re using the nuget package system.</li>
</ul>

<p>Similarly, NUnit makes use of this for updating the version of NUnit used in one of our GitHub actions:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"customManagers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"customType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"regex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"fileMatch"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">"^</span><span class="se">\\</span><span class="s2">.github</span><span class="se">\\</span><span class="s2">/workflows</span><span class="se">\\</span><span class="s2">/build-process</span><span class="se">\\</span><span class="s2">.yml$"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"matchStrings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">"NUNIT_VERSION_FOR_API_DOCS: </span><span class="se">\"</span><span class="s2">(?&lt;currentValue&gt;.*?)</span><span class="se">\"</span><span class="s2">"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"depNameTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NUnit"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"datasourceTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"nuget"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>And here’s it working to keep a container tag up to date from within C# files:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"customManagers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"customType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"regex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"fileMatch"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">".*</span><span class="se">\\</span><span class="s2">.cs"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"matchStrings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">".WithImage</span><span class="se">\\</span><span class="s2">(</span><span class="se">\\\"</span><span class="s2">ironsoftwareofficial</span><span class="se">\\</span><span class="s2">/ironpdfengine:(?&lt;currentValue&gt;.*?)</span><span class="se">\\\"\\</span><span class="s2">)"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"depNameTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ironsoftwareofficial/ironpdfengine"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"datasourceTemplate"</span><span class="p">:</span><span class="w"> </span><span class="s2">"docker"</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<h2 id="in-summary">In Summary</h2>

<p>Dependency management tools like RenovateBot are a game changer. Ensuring they can get into all the nooks and crannies of your app helps them do their job.</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="renovatebot" /><category term="dependencies" /><category term="dependency-management" /><category term="devops" /><summary type="html"><![CDATA[No dependency left behind.]]></summary></entry><entry><title type="html">Communication Tip: The Power of Named Chats</title><link href="https://seankilleen.com/2024/11/communication-tip-the-power-of-named-chats/" rel="alternate" type="text/html" title="Communication Tip: The Power of Named Chats" /><published>2024-11-19T14:00:00+00:00</published><updated>2024-11-19T14:00:00+00:00</updated><id>https://seankilleen.com/2024/11/communication-tip-the-power-of-named-chats</id><content type="html" xml:base="https://seankilleen.com/2024/11/communication-tip-the-power-of-named-chats/"><![CDATA[<p>In many organizations, natural communication pathways start to form. Something happens or information needs to be sent out or a decision needs to be made, and you fire up a Teams window or Slack group message and invite the usual suspects.</p>

<h2 id="the-drawback-of-individualgroup-chats">The Drawback of Individual/Group Chats</h2>

<ul>
  <li><strong>They’re difficult to expand</strong>. Adding someone new, it’s unclear if past history should be shared, and how far back that should go (if you even have control over it).</li>
  <li><strong>They get lost over time</strong>. An important context fades into the background, and it’s difficult to tell that the conversation ever took place unless you’re explicitly scrolling or searching for it.</li>
  <li><strong>They get blurred</strong>. When similar groups are in multiple chats as individuals, it can be difficult to keep subjects straight, leading to cognitive overhead to sort it all out.</li>
</ul>

<h2 id="enter-the-named-group-chat">Enter the Named Group Chat</h2>

<p>The next time you find yourself discussing something that has a distinct “conceptual box” around it, consider creating a named chat (if you’re in MS teams) or a private channel (if you’re in Slack).</p>

<p>Now you have:</p>

<ul>
  <li>A space with explicit context</li>
  <li>A way to keep the chat on topic</li>
  <li>The ability to archive it when it ends</li>
  <li>A way to signal status, in the group name</li>
  <li>A nice package to invite anyone to who needs to jump into the conversation, where you can share the entire history more likely than not.</li>
</ul>

<h2 id="an-example">An Example</h2>

<p>We recently had a strange week at work where 4 different clients had time sensitive issues come up during the same week. Many of the same people on our side were involved in overlapping conversations across the contexts and it got messy to keep track of, fast.</p>

<p>I saw an opportunity. I created a group chat for each client context, added the appropriate people, and titled it “(Client) War Room”. I started each channel by recapping what we knew so far and what the next steps were. I then added a status icon (🔴, 🟡, 🟢) to indicate current urgency.</p>

<p>It felt like things were quickly better organized. And we were able to add leadership team members to the chat when needed, and they had easily digestible context.</p>

<h2 id="what-do-you-think">What do you think?</h2>

<p>I ended up writing this post because someone sent me an IM behind the scenes and remarked on what a neat trick it was. So, dear reader, I wanted to share it with you.</p>

<p>How about you? How do you use group chats more effectively in work contexts?</p>]]></content><author><name>Sean Killeen</name><email>SeanKilleen@gmail.com</email></author><category term="Communication" /><category term="messaging" /><category term="chat" /><summary type="html"><![CDATA[In many organizations, natural communication pathways start to form. Something happens or information needs to be sent out or a decision needs to be made, and you fire up a Teams window or Slack group message and invite the usual suspects.]]></summary></entry></feed>