<?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>Forem: Al Goodniss</title>
    <description>The latest articles on Forem by Al Goodniss (@al_goodniss_roguecoderz).</description>
    <link>https://forem.com/al_goodniss_roguecoderz</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%2F3652164%2Fc6ce205a-7e82-4ab7-aaa2-52fb6304bdcf.png</url>
      <title>Forem: Al Goodniss</title>
      <link>https://forem.com/al_goodniss_roguecoderz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/al_goodniss_roguecoderz"/>
    <language>en</language>
    <item>
      <title>Ways to stay current</title>
      <dc:creator>Al Goodniss</dc:creator>
      <pubDate>Mon, 15 Dec 2025 19:43:15 +0000</pubDate>
      <link>https://forem.com/al_goodniss_roguecoderz/ways-to-stay-current-31m2</link>
      <guid>https://forem.com/al_goodniss_roguecoderz/ways-to-stay-current-31m2</guid>
      <description>&lt;p&gt;I’ve found that the best way to stay technically sharp is to live with the consequences of old decisions. Over time, even “good” architectures show their cracks. Keeping a long-running personal project, one that I revisit, rewrite, migrate, and refactor as my skills and expectations evolve, has been my way of staying current.&lt;/p&gt;

&lt;p&gt;My project tracks win/loss statistics for poker games I've played in. Version 1 was XML, XSLT, and a bit of shell scripting that produced a simple static HTML/CSS site. Version 2 moved to C# and JSON and shifted from a web application to a CLI. That transition is where I learned more deeply about dependency injection and event-sourced architectures. Today, the project is written in Python, backed by NDJSON, and uses Polars, which has been a great way to deepen my Python data-processing skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right early decisions can set you up for success.&lt;/strong&gt;&lt;br&gt;
Projects evolve, and the architecture you start with is rarely the one you need later. That means intentionally designing for change. For example, while my project has gone through multiple JSON libraries, the rest of the code never cared.&lt;/p&gt;

&lt;p&gt;Early on, I implemented the Repository pattern, which meant the only thing that mattered was the contract. Testing out a new library, or completely porting over to one, was as easy as adding a new class and changing the factory. Which also allowed me to run the new code side by side for testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your skills evolve — and so does your tolerance for “good enough.”&lt;/strong&gt;&lt;br&gt;
Code that felt acceptable a year ago can become painful to work with once your expectations (or experience) change.&lt;/p&gt;

&lt;p&gt;For a long time, I avoided refactoring my argument parser module because it worked and rarely needed updates. When I recently added several new commands, that changed. The module had grown into a single large function that configured &lt;code&gt;argparse&lt;/code&gt; and then used a dispatch pattern to route commands. It worked, but it was brittle and hard to reason about.&lt;/p&gt;

&lt;p&gt;My first pass was to break that function into individual command registration functions. Better, but still awkward. Registration and execution were separate concerns and the linkage between them relied on convention rather than structure. You had to know that &lt;code&gt;_register_stats_command(...)&lt;/code&gt; corresponded to &lt;code&gt;stats(...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That was the signal that a different abstraction was needed.&lt;/p&gt;

&lt;p&gt;I introduced a &lt;code&gt;@Command&lt;/code&gt; decorator to register commands. I added a few supporting abstractions like &lt;code&gt;Argument&lt;/code&gt; and &lt;code&gt;ExclusiveGroup&lt;/code&gt;. This allowed me to keep &lt;code&gt;argparse&lt;/code&gt; configuration directly alongside the dispatch function. It was cleaner, easier to reason about, and enabled additional validation that wasn’t practical before. For example, I now validate that the command and the function name match.&lt;/p&gt;

&lt;p&gt;Does this decorator support everything argparse does? Nope, and that’s intentional. It supports exactly what this project needs today. Nothing more.&lt;/p&gt;

&lt;p&gt;For me, staying current isn’t primarily about chasing the latest framework. It’s about revising real systems, refining judgment, and being willing to outgrow both old code and old assumptions. That’s where the learning is.&lt;/p&gt;

</description>
      <category>career</category>
      <category>python</category>
      <category>architecture</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Why You Need to Manage AI Like a New Hire</title>
      <dc:creator>Al Goodniss</dc:creator>
      <pubDate>Mon, 08 Dec 2025 15:08:17 +0000</pubDate>
      <link>https://forem.com/al_goodniss_roguecoderz/why-you-need-to-manage-ai-like-a-new-hire-4boh</link>
      <guid>https://forem.com/al_goodniss_roguecoderz/why-you-need-to-manage-ai-like-a-new-hire-4boh</guid>
      <description>&lt;p&gt;When I asked AI to review a different post, it added a sentence that made the post better: "One team I worked with eliminated 2+ hours per week of "fix the linter" PR comments."&lt;/p&gt;

&lt;p&gt;Punchy. Specific. Persuasive.&lt;/p&gt;

&lt;p&gt;… and a complete lie.&lt;/p&gt;

&lt;p&gt;I didn’t have that data. I never wrote that. It wasn't in my draft. The AI just... made it up. When I removed that line, the AI told me to put it back in because removing it made my post weaker. I had to explain to the AI that "[It] fabricated this. I will not lie about my experience."&lt;/p&gt;

&lt;p&gt;That moment taught me an important lesson about working with AI in 2025.&lt;/p&gt;

&lt;p&gt;AI is like an eager new hire: smart, helpful, and desperate to please. It will confidently give you exactly what you think you want. Including things that aren't true. So here's what I've learned after a year of using AI daily:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tell it to cite sources.&lt;/strong&gt; I started with Perplexity because it automatically links to sources. Now I use that habit everywhere: "Cite your sources" turns any AI into a research assistant instead of a creative writer. You get facts you can verify, not facts you hope are real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask for brutal honesty.&lt;/strong&gt; When I need real feedback, I add "Be brutally honest." It strips away the AI's tendency to praise everything. The feedback I got on an earlier draft of this very post: "Floppies and streaming movies? Every tech post from the last decade has this same tired intro." Harsh. Accurate. Actionable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Give it a role.&lt;/strong&gt; "As a Staff Engineer doing a code review..." or "As my Editor, review this post..." frames how the AI thinks about your problem. You're not just getting generic AI responses; you are getting responses shaped by that perspective.&lt;/p&gt;

&lt;p&gt;The bottom line: AI is a tool that will confidently hand you garbage if you let it. Treat it like that eager new hire: direct it, question it, verify everything, and you'll get real value. Treat it like an oracle, and you could end up publishing lies about your experience.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
