﻿<?xml version="1.0" encoding="utf-8"?>
<rss
  version="2.0">
  <channel>
    <title>Rileytech</title>
    <link>https://rileytech.net/</link>
    <description>Ramblings and things around product, culture and code.</description>
    <lastBuildDate>Fri, 12 Dec 2025 00:14:47 Z</lastBuildDate>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/skills-over-seats-why-youre-botching-your-new-transformation-strategy-with-ai-this-time</guid>
      <link>https://rileytech.net/posts/skills-over-seats-why-youre-botching-your-new-transformation-strategy-with-ai-this-time</link>
      <title>Skills Over Seats: Why You’re Botching Your New Transformation Strategy with AI this time</title>
      <description>&lt;h2 id="your-ai-rollout-has-a-structural-flawand-the-window-to-fix-it-is-closing"&gt;Your AI rollout has a structural flaw—and the window to fix it is closing.&lt;/h2&gt;
&lt;br&gt;
You've deployed enterprise-wide licenses across thousands of employees, but six months in, utilization is stalled at 15% and renewal costs just jumped 40%. The pattern's familiar from previous transformation initiatives—but this time the financial exposure is higher and competitive implications are immediate.
&lt;br&gt;
You can still course-correct.
&lt;h2 id="the-choice-point-month-6"&gt;The Choice Point: Month 6&lt;/h2&gt;
&lt;hr&gt;
&lt;table class="comparison-table"&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Timeline&lt;/th&gt;
      &lt;th&gt;Current Trajectory&lt;/th&gt;
      &lt;th&gt;Skills-First Alternative&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Month 6&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;
        &lt;ul&gt;
          &lt;li&gt;Public "AI-enabled" positioning&lt;/li&gt;
          &lt;li&gt;Actual usage: ~15%&lt;/li&gt;
          &lt;li&gt;Technical teams missing deadlines&lt;/li&gt;
          &lt;li&gt;Renewal shock: 40% increase ($2M spent, minimal ROI)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/td&gt;
      &lt;td&gt;
        &lt;ul&gt;
          &lt;li&gt;Five experts complete focused pilot&lt;/li&gt;
          &lt;li&gt;Documented wins distributed cross-functionally&lt;/li&gt;
          &lt;li&gt;Measurable: 3+ hours saved per person weekly&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Month 12&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;
        &lt;ul&gt;
          &lt;li&gt;Escalating contract obligations&lt;/li&gt;
          &lt;li&gt;Executive sponsor transitions; initiative orphaned&lt;/li&gt;
          &lt;li&gt;Talent retention issues as credibility erodes&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/td&gt;
      &lt;td&gt;
        &lt;ul&gt;
          &lt;li&gt;Original cohort upskilling 50 more&lt;/li&gt;
          &lt;li&gt;3-10x productivity gains on pilot workflows&lt;/li&gt;
          &lt;li&gt;Documented revenue impact, justified expansion&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;This is the delta between your current path and what's achievable with a strategy adjustment.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="case-study-the-1.4m-adoption-gap"&gt;Case Study: The $1.4M Adoption Gap&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;A &lt;a href="https://x.com/gothburz/status/1999124665801880032"&gt;technology executive recently documented&lt;/a&gt; a representative scenario: Microsoft Copilot deployment to 4,000 employees at $30/seat/month. $1.4M annual investment. Board approval in eleven minutes under &amp;quot;digital transformation&amp;quot; positioning.&lt;/p&gt;
&lt;p&gt;Three months post-launch: &lt;strong&gt;47 employees had accessed the tool. 12 demonstrated sustained usage.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The response? Expansion request for 5,000 additional seats.&lt;/p&gt;
&lt;p&gt;The stated rationale: &amp;quot;Adoption means mandatory training. Training means a 45-minute webinar no one watches. But completion will be tracked. Metrics go in dashboards. Dashboards go in board presentations.&amp;quot;&lt;/p&gt;
&lt;p&gt;This pattern—spending as strategy, metrics as theater—is endemic.&lt;/p&gt;
&lt;p&gt;Separately, J.P. Morgan's analysis indicates &lt;a href="https://x.com/mweinbach/status/1987912908567916693"&gt;AI investments require $650 billion in annual revenue generation&lt;/a&gt; to deliver 10% returns on current buildout costs—equivalent to $35 per iPhone user or $180 per Netflix subscriber in perpetuity.&lt;/p&gt;
&lt;p&gt;The disconnect: significant capital deployment without corresponding capability development or measurable utilization.&lt;/p&gt;
&lt;p&gt;Organizations winning this transition aren't spending more. They're spending differently.&lt;/p&gt;
&lt;h2 id="the-core-issue-scale-without-foundation"&gt;The Core Issue: Scale Without Foundation&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Conventional approach—broad licensing as adoption forcing function—delivers 15% utilization. Alternative: deep-skill focused team to prove value in production workflows, leverage organic demand for expansion.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Capital allocation: $50K to develop five experts with measurable outcomes vs. $5M in distributed licenses with uncertain adoption.&lt;/strong&gt; One generates ROI data in less than 90 days. The other becomes a sunk cost you're defending in next year's planning.&lt;/p&gt;
&lt;p&gt;A Fortune 500 logistics operator executed this in Q1 2025. Five supply chain analysts focused on route optimization.&lt;/p&gt;
&lt;p&gt;Results by Month 3: 40% faster planning, $1.2M annualized fuel savings.&lt;/p&gt;
&lt;p&gt;By Month 6: second cohort training.&lt;/p&gt;
&lt;p&gt;By Month 9: CFO inquiring why other divisions weren't matching pace.&lt;/p&gt;
&lt;h2 id="current-market-performance"&gt;Current Market Performance&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Recent research reveals stark bifurcation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MIT 2025&lt;/strong&gt;: 95% of enterprise pilots generate zero measurable P&amp;amp;L impact&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S&amp;amp;P Global&lt;/strong&gt;: 42% of firms terminated majority of AI initiatives in 2025 (vs. 17% in 2024)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gartner 2025&lt;/strong&gt;: Organizations prioritizing skills development show 2x+ likelihood of reaching mature implementation with sustained ROI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pattern: high-visibility launches without capability development, followed by quiet shutdowns. Attribution shifts to &amp;quot;culture&amp;quot; while key talent departs for competitors who executed foundation work.&lt;/p&gt;
&lt;h2 id="six-strategic-adjustments"&gt;Six Strategic Adjustments&lt;/h2&gt;
&lt;hr&gt;
&lt;br&gt;
&lt;h3 id="target-high-impact-applications-first"&gt;1. Target High-Impact Applications First&lt;/h3&gt;
&lt;p&gt;Identify specific operational bottlenecks. Define success concretely: hours saved, revenue generated, error rates reduced. Honestly evaluate team capacity to execute within 90 days. High performers need clear understanding of both AI capabilities (rapid iteration) and failure modes (confidently incorrect outputs). Without this, you're funding frustration and flailing of your top people.&lt;/p&gt;
&lt;h3 id="develop-prompt-engineering-as-organizational-capability"&gt;2. Develop Prompt Engineering as Organizational Capability&lt;/h3&gt;
&lt;p&gt;Performance gap between basic queries and structured prompting represents the difference between marginal utility and transformative value.&lt;br&gt;&lt;br&gt;
Basic: &amp;quot;Summarize this data&amp;quot;  &lt;br&gt;&lt;br&gt;
Structured: &amp;quot;Analyze Q3 enterprise software sales. Summarize: (1) deal velocity by region, (2) discount patterns above $100K, (3) win/loss themes. Format as executive brief—3 key insights with metrics, flag data gaps. For a deeper example, &lt;a href="https://www.linkedin.com/posts/jeriley_so-heres-what-ive-been-saying-its-coming-activity-7369715991582289925-0awr?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAAGEPucBo42BkbKGL2I2dhyEoNnoUsvyOQ8"&gt;go here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Organizations treating this as learnable skill—context + task + constraints + format + examples—achieve 5-10x output improvements, &lt;em&gt;&lt;strong&gt;and more&lt;/strong&gt;&lt;/em&gt;. Those approaching casually dismiss AI as &amp;quot;not production-ready&amp;quot; when the constraint is input quality, not model capability.&lt;/p&gt;
&lt;h3 id="diversify-model-selection-strategically"&gt;3. Diversify Model Selection Strategically&lt;/h3&gt;
&lt;p&gt;Single-vendor approaches create unnecessary constraints. Claude demonstrates superior performance in complex reasoning for articles and writing. Gemini excels at code and massive contexts. Grok is good at the latest and greatest ideas and concepts. Model capabilities vary significantly by use case. Test aggressively across vendors for your workflows. How you use it and the value you get will vary.&lt;/p&gt;
&lt;h3 id="create-knowledge-sharing-infrastructure"&gt;4. Create Knowledge-Sharing Infrastructure&lt;/h3&gt;
&lt;p&gt;When DevOps develops a prompt saving three hours weekly, Product should know within days. When development can deliver 5x stories, devops and the business should know within days. Establish distribution channels—dedicated Slack spaces, demo sessions, searchable documentation—or accept each team independently rediscovering solutions.&lt;/p&gt;
&lt;h3 id="conduct-vendor-due-diligence"&gt;5. Conduct Vendor Due Diligence&lt;/h3&gt;
&lt;p&gt;Many &amp;quot;AI-powered&amp;quot; solutions are thin wrappers around foundation models with significant markup. Investigate technology ownership, pricing volatility, exit costs. Critical question: What's our operational exposure if this vendor quadruples pricing or gets acquired?&lt;/p&gt;
&lt;h3 id="plan-for-continuous-capability-development"&gt;6. Plan for Continuous Capability Development&lt;/h3&gt;
&lt;p&gt;Model capabilities evolve weekly. Six-month knowledge stagnation creates meaningful competitive disadvantage. Budget for quarterly refreshers, not just launch training.&lt;/p&gt;
&lt;h3 id="bonus.its-not-just-for-software"&gt;7. Bonus. It's not just for software&lt;/h3&gt;
&lt;p&gt;Yes, the SDLC side of the house will be at the forefront of this, but that does not mean you cannot use the patterns and idiosyncratic knowledge of your organization to your advantage everywhere.&lt;/p&gt;
&lt;h2 id="implementation-framework"&gt;Implementation Framework&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identify Change Agents&lt;/strong&gt; – Who's already maximizing AI quotas? First cohort identified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Launch Focused Pilot&lt;/strong&gt; – Fund agents, target single high-pain issue, surface blockers within weeks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enforce Rapid Win/Kill&lt;/strong&gt; – Month one: measurable metric movement or project termination. No zombie initiatives.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Establish Metric Accountability&lt;/strong&gt; – Demand 50%+ utilization. Require documented improvements within 90 days. Quarterly reviews, public scorecards.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assess Organizational Prerequisites&lt;/strong&gt; – Clear goal-setting and problem-solving cultures adopt efficiently. Political friction and risk-aversion amplify existing dysfunction.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Execute this and payback manifests in weeks. Miss the window and you're documenting failure for next year's planning.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Scale from demonstrated wins, not strategic assumptions. Then, and only then, &lt;em&gt;go full send&lt;/em&gt;.&lt;/b&gt;&lt;/p&gt;
</description>
      <pubDate>Fri, 12 Dec 2025 00:14:47 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/ai-retired</guid>
      <link>https://rileytech.net/posts/ai-retired</link>
      <title>AI Retired</title>
      <description>&lt;h2 id="from-the-farmer-effect"&gt;From the Farmer Effect&lt;/h2&gt;
&lt;p&gt;Back in 2016, I coined &lt;a href="https://rileytech.net/posts/the-farmer-effect-theory"&gt;“The Farmer Effect”&lt;/a&gt; after telling a frustrated dev team, “Let’s all quit and go be farmers.” The joke hit a nerve I wasn’t expecting. Even today, on occasion, I’ll get a message to the tune of “farmer effect hitting hard today man!” so that is still alive and well. But now I’m noticing something …different. And it’s AI driven.
In tech, we have had a front-row seat to AI. When AI “burst onto the scene”, I would joke how terrible it is, being less than helpful, pointing out an extensive list of things it was missing. From glazing over proper patterns in code, grossly simplifying concepts and approaches, sometimes being outright dangerously wrong… It was easy to laugh at. Now? It’s getting better. A lot better.&lt;/p&gt;
&lt;p&gt;So What? A lot. The amount of effort to find pretty damn good, deep knowledge has compressed down into minutes. What takes you a full day can be done better in under 2 hours. Even for me, it’s becoming way easier to have AI “do the thing” I want it to do. It doesn’t take much.&lt;/p&gt;
&lt;p&gt;With this newly freed up cognitive load, the joke of “when AI takes our jobs” has shifted. It’s not about when AI takes our job, it’s what are we going to do with the spare brain power.&lt;/p&gt;
&lt;h2 id="ai-retired"&gt;AI Retired.&lt;/h2&gt;
&lt;p&gt;The same draw that once made us daydream about farming now pushes us toward skills that can’t be promptly replaced. Looking in first, I noticed my own behavior shift. Instead of another AI conference, I signed up for a car detailing master class. Why? I have no (paying) customers. For me, it’s a 1:1 craftsmanship carryover - I have an eye for it, I’m good at it, I love the process, the science, the art of it, people appreciate it …and an LLM cannot detail your car. It also has a hard time explaining it incase you were wondering.&lt;/p&gt;
&lt;p&gt;The original Farmer Effect was about digital burnout and a human need to do physical things. AI Retired is about finding your irreplaceable human value. Tap into the same primal need for tangible creation, completion, and craftsmanship—except now it’s not just about sanity and balance, it’s about what will you do next? The line between hobby and hedge bet is blurring fast — and that’s ok!&lt;/p&gt;
&lt;p&gt;So are you AI Retired? What’s your AI Retirement plan? What physical, hands-on skill are you developing for when “AI takes our jobs”? Maybe it’s farming…powered with AI.&lt;/p&gt;
</description>
      <pubDate>Sat, 19 Apr 2025 18:20:49 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/the-path-of-truth-tellers-is-littered-with-dead-scapegoats</guid>
      <link>https://rileytech.net/posts/the-path-of-truth-tellers-is-littered-with-dead-scapegoats</link>
      <title>The Path of Truth Tellers is Littered with Dead Scapegoats</title>
      <description>&lt;p&gt;Wildfire Labs &lt;a href="https://wildfirelabs.substack.com/p/the-icarus-trap-why-every-startup"&gt;posted an article&lt;/a&gt; a few days ago that directly encourages the need for someone to tell you, in my words, “that’s dumb, don’t do that”.  The catch is, that comment may have years of reasons behind it. Reasons most people don’t want to hear, understand, nor believe. That’s completely fine! You probably already fired them anyway by now. Or dismissed them, forgot to respond, got busy …all the excuses I’ll cover. Ask me how I know.&lt;/p&gt;
&lt;p&gt;Anyway, here’s a bit of a view from the other side.&lt;/p&gt;
&lt;h2 id="steps-you-will-fail-embracing-truth-tellers"&gt;Steps you will fail Embracing Truth Tellers&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-Honesty is Lacking&lt;/strong&gt;: It’s fashionable to say, “I have imposter syndrome” and be a victim. It’s an excuse. Change your language, be intimately honest with yourself …there’s your truth. Only then can you bring in someone else’s.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ugly Baby&lt;/strong&gt;: It’s not easy to be told your baby is ugly. It is. Good news -- it’s early and it’s time to find out what your baby is good at and turn them into an Olympian.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Idea&lt;/strong&gt;: In complete puppy love with your idea? How many people have you known they weren’t right for each other, and they wouldn’t listen because they’re in love? Now that’s you… and your idea.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Polite vs Honesty mismatch&lt;/strong&gt;: “I love this idea, it’s SO great!” is polite. Honest is “This has at least 100 competitors, how and what are you doing differently?” We get it, it’s the comment you want to hear in a crowd …so plan accordingly and follow up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The words&lt;/strong&gt;: We tell you this because we really do care. Not about your feelings and short term strife, but you, your success and what you are building. Don’t forget that.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You are not ready for a Truth Teller&lt;/strong&gt;: They come in, give you the beans and your response? Freeze, crawl back into the safety of the chamber of yes and pretend it never happened.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ultimately, it’s up to you&lt;/strong&gt;: It’s your company, your effort, your sweat, blood, sleepless nights and moments of euphoria.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All that said, one point they made on this, is spot on and if you’re a founder, you should do this, A LOT.__ Regularly seek feedback__. Not fake feel good “feedback” either. It’s invaluable, but you, yes you, must know where and when to ask for it… and prepare for what they have to say because you probably won’t like it, but need it all the same.&lt;/p&gt;
&lt;h2 id="you-dont-remember-us"&gt;You Don't Remember Us&lt;/h2&gt;
&lt;p&gt;It's thankless and forgettable. I've seen companies pivot to success or dodge fatal bullets because someone like me picked up the phone and delivered an uncomfortable truth. Here's the reality check:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;That investor call that made your Series A actually happen? The one where someone told you your pitch was garbage and helped you rebuild it at 11 PM? Yeah, that was three weeks before you &amp;quot;figured it out yourself.&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember that &amp;quot;gut feeling&amp;quot; that saved you from that catastrophic partnership? Funny how you forgot the two-hour call where someone walked you through exactly why it would implode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That brilliant pivot that saved your company? Somewhere, there's a truth-teller who got ghosted right after they forced you to see what you didn't want to see.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We're the antibodies to BS in the startup ecosystem - we do our job and get forgotten. That's fine. We didn't do it for the credit. But here's the truth about truth-tellers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We're the equivalent of that friend who stopped you from drunk driving - essential in the moment, awkward to acknowledge after&lt;/li&gt;
&lt;li&gt;Our value often only becomes clear in retrospect, long after you've written us out of the story&lt;/li&gt;
&lt;li&gt;We measure success in disasters avoided, not credits received&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The ultimate irony? The better we do our job, the more &amp;quot;obvious&amp;quot; our advice seems in hindsight. Because once you see it, you can't unsee it. And that's exactly why you forget us - the truth, once seen, feels like it was always there.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But ask yourself this&lt;/em&gt;: If you can't remember who told you the hard truths that saved you, how many are you ignoring right now?&lt;/p&gt;
</description>
      <pubDate>Fri, 11 Oct 2024 01:59:33 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/are-you-parroting</guid>
      <link>https://rileytech.net/posts/are-you-parroting</link>
      <title>Are You Parroting?</title>
      <description>&lt;h2 id="stop-parroting-leadership-advice"&gt;Stop Parroting Leadership Advice&lt;/h2&gt;
&lt;h3 id="youre-doing-it-wrong"&gt;(You're Doing It Wrong)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;'Leaders eat last!'&lt;/strong&gt; they parrot enthusiastically, while shoving to the front of the lunch line, giving you a smaller cut, leaving for that 3 week vacation and don’t forget the holiday party you’re not invited to. Welcome to the world of leaderbullship (ahem) theater, where everyone's memorized the lines you’ll remember (I’m batman) but nobody's read the stage directions, much less know what the whole damn play is about.&lt;/p&gt;
&lt;p&gt;With all the different patterns and “be better, do this thing!” out there, I’ve been noticing a …trend. It’s a trend that hits both sides, good and bad. The good being that people are reading, hearing, and observing seemingly better behaviors - &amp;quot;Leaders eat last!&amp;quot;. What could possibly be bad about that you ask? The application of it is just …&lt;em&gt;parroting&lt;/em&gt; -- the act of just repeating what was heard and dare I say, without much thought to what is being said.&lt;/p&gt;
&lt;p&gt;I see far too many people skirting the effort it takes to apply, or at least dissect an idea into their own. Yes, it's a good thing to add more tools in the toolbox but blindly buying tools and throwing them in a box does not a craftsman create.  Throwing these concepts into a drawer, feeling prepared when all they have is another hammer looking for a nail. No matter how hard you squint, those aren't nails ...and they're not looking for a hammer.&lt;/p&gt;
&lt;h2 id="the-911-problem"&gt;The 911 Problem&lt;/h2&gt;
&lt;p&gt;For example, and stick with me on this, I'd like to think during an emergency, everyone knows to call 911 in case of an emergency.  Most will hear that, nod, and not give it another thought. However, there's a catch to this.  During some emergency medical training I took (ok, I’ve taken it 4-5 times) there’s a phenomenon (bystander effect) when someone yells out “someone call 911!” …and no one does. Assuming they’re not on their phones, they look at each other, deciding who should call 911. We watched several videos showing exactly this happening, in REALLY bad situations. Situations I'd expect people to know that one thing to do - call 911. It &lt;em&gt;doesn't happen&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="why-it-doesnt-work"&gt;Why it doesn’t work&lt;/h2&gt;
&lt;p&gt;Instead, it's instructed and practiced for us to call on someone, &lt;strong&gt;anyone&lt;/strong&gt;, ideally looking at you and directly point them out -- “YOU, yes you, call 911”. Even if that person has no idea what is going on, giving a direct call to action is far better than expecting someone to act. This is on top of everything else happening around the situation. To be frank, there's a LOT to it, but that simple understanding is a big jump in being effective.&lt;/p&gt;
&lt;h2 id="parroting-to-practice"&gt;Parroting to Practice&lt;/h2&gt;
&lt;p&gt;What does this have to do with being better? Not only being able to parrot &amp;quot;call 911!&amp;quot; but adding the layer of &amp;quot;YOU call 911&amp;quot; ...it changes the actions, the outcomes and by extension, the experience when it isn't just parroting what you saw on TV.&lt;/p&gt;
&lt;p&gt;We already took a shot at “leaders eat last” so let's take another example that every 'thought leader' loves to parrot: “Does anyone have feedback for me?” …and you get &lt;em&gt;crickets&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Without question, it's good to get feedback (even HBR did a write up on how to not suck at it), but like saying &amp;quot;someone call 911&amp;quot; it doesn't work that well by itself and there's a lot more to it. Digging deeper into &amp;quot;call 911&amp;quot;, it's a big jump to be more direct. “Scott, you’ve been at this for a while, where can we do better?”. Scott's been at this longer than anyone and I REALLY want him to call 911 ...me. If that doesn’t get the ball rolling, try the negative question – “I’m not feeling good about this, where will it all go wrong?” and be specific what -this- is and share your concerns.&lt;/p&gt;
&lt;h2 id="lets-pile-it-on"&gt;Let’s Pile it on.&lt;/h2&gt;
&lt;p&gt;The more you look, the more of these are out there if taken only at the surface. “Move fast and break things” hasn’t been a mantra for a long time now. Does Spotify use the Spotify model? Spoilers. Target has removed the Dojos from their site. “Win friends and influence people” is a book on manipulation. The list goes on.&lt;/p&gt;
&lt;h2 id="the-price-of-cheap-signals"&gt;The Price of Cheap Signals&lt;/h2&gt;
&lt;p&gt;Reading between the lines here -- when a new concept is heard, read, maybe the first paragraph isn't understanding a concept. That's called &lt;em&gt;cheap signaling&lt;/em&gt;. Having those tools in the toolbox requires more than just buying it, the tools and a space to put them. Knowing those tools (concepts) and when to use them (applications) helps bring on the most important thing — when those can be combined with other tools…
That’s when you make pure magic.&lt;/p&gt;
&lt;h2 id="the-real-toolbox"&gt;The Real Toolbox&lt;/h2&gt;
&lt;p&gt;Becoming a master mechanic doesn’t happen by buying a ton of tools and watching YouTube. You have to, ya know, actually go out and build, fix, maintain, bust your knuckles, screw up, break shit, find out what was missing from it all, and modify it with you know. Same goes for leadership concepts. Read the books, digest them, noodle on them for a bit, counterpoint it, find the flaws with the strengths… and certainly try them out and find the lines in between.&lt;/p&gt;
&lt;h2 id="how-to-not-suck-at-this"&gt;How to Not suck at This&lt;/h2&gt;
&lt;p&gt;I don’t care what the book says – I care about what YOU think about it and how you’ve applied it. &lt;em&gt;Be specific&lt;/em&gt;. Go back to your toolbox and evaluate what tools you now how to use.&lt;/p&gt;
&lt;p&gt;So next time you're about to repost that “inspiring” leadershit quote, ask yourself: Do I actually know how to use this tool, or am I just carrying it around to look important and sound like a parroting “thought leader”? Take what they wrote about (it’s outdated by the time its published) …and give us all a view of what’s next.&lt;/p&gt;
</description>
      <pubDate>Fri, 04 Oct 2024 00:21:56 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/6-years</guid>
      <link>https://rileytech.net/posts/6-years</link>
      <title>6 years.</title>
      <description>&lt;p&gt;Early in your career? Wondering why things take so long to materialize and get better? Can I tell you a story about 6 years?&lt;/p&gt;
&lt;p&gt;Last month, I had three separate instances where people/organizations I worked with directly, come to a conclusion I had pointed out 6-8 years ago. Not just pointed out at the time, but insisted, Mandalorian style, &amp;quot;this is the way&amp;quot;. I used the data and existing feedback to guide us towards what I thought set us up for success. At the time, I was overruled - some more severely than others - due to other wants and needs. So what changed? What happened? I started to dig into this a bit.&lt;/p&gt;
&lt;p&gt;This was new data to me, in a way I had not experienced. I mean really, when was the last time you heard about something you did 5+ years ago making any kind of impact or change? This was also a bit exciting and made a pit stop to look at which kind of trap I was experiencing. Was it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hindsight bias (see, see, I was right!)&lt;/li&gt;
&lt;li&gt;Confirmation bias (my advice was dead on)&lt;/li&gt;
&lt;li&gt;Actor-Observer (they didn't understand)&lt;/li&gt;
&lt;li&gt;Mandela Effect (remembering it wrong)&lt;/li&gt;
&lt;li&gt;Fundamental Attribution Error maybe? (making up a story)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In case you are wondering, yes, I have these biases written down with a short summary for times when I come across moments like these - like a cheat sheet …yet these instances felt different and didn't align with any of them. Being it was an outcome I had pushed for years ago, but wasn't until now that it was … understood? Appreciated? Internalized? Was this simply the time necessary for Bloom's Taxonomy to take shape? 6+ years? really!? That's the time it takes to get a doctorate or professional degree. What the hell!?&lt;/p&gt;
&lt;p&gt;It would certainly be easier for pure cynicism to take over -- &amp;quot;I told you so!&amp;quot; … it can't be that, the time difference was so great and I'm sure the statute of limitations ran out for such lazy conclusions. And this was a call out, without a trace of regret or anything as petty as &amp;quot;I should've listened&amp;quot;. Again, more questions.&lt;/p&gt;
&lt;p&gt;Insert the cliché … &lt;em&gt;and then it hit me&lt;/em&gt;. Ok, it didn't hit me, I ended up talking about it enough and sorting through the whole thing to finally come up with something that made too much sense.&lt;/p&gt;
&lt;h3 id="the-motivations-had-changed"&gt;The motivations had changed.&lt;/h3&gt;
&lt;p&gt;They had moved to different ...things, different culture, different environment, different goals. Therefore, their experience in approaching, dealing with, and solving the problems had changed with it. I've heard over the years companies being asked &amp;quot;Why are you here? Why do you exist?&amp;quot; Most of it is a spew of pure, total bullshit — a weak attempt to create a collection of words, lacking merit and any tangible meaning to have people smile and nod during speeches. It's no different than a player who is brilliant on one team be completely terrible on another.&lt;/p&gt;
&lt;p&gt;Now, this is way clearer to me than ever in meaning, importance, belonging and seriousness. My mistake? I had missed the mark entirely on how to convey how fundamental this is. So now, selfishly, I don't want it to take another 6+ years for others to really appreciate ...which is something I have to work on. How far would they be along if I was able to get that message across? What would they have accomplished?&lt;/p&gt;
</description>
      <pubDate>Thu, 14 Sep 2023 12:59:08 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/how-do-you-price-your-product-a-real-example</guid>
      <link>https://rileytech.net/posts/how-do-you-price-your-product-a-real-example</link>
      <title>How do you price your product? A real example.</title>
      <description>&lt;p&gt;Not long ago I was working with a very small company, maybe 8 people total, and the big question came up, very hard question to answer, especially when it isn't a thing doesn't exist...&lt;/p&gt;
&lt;h2 id="what-do-we-charge-for-this"&gt;What do we charge for this?&lt;/h2&gt;
&lt;p&gt;This is a huge problem, a good problem, and one that if you solve it incorrectly either leaves money on the table (they would've paid more) or lose a sale (too expensive) – both not great outcomes. So how do you know, really KNOW what the best price point is ...for something that hasn't even been sold yet?&lt;/p&gt;
&lt;p&gt;Searching around the ole internet, you'll find a lot of strong opinions on this. From limits (never charge more than X) to steadily increasing (raise it until they say no!), make it a percentage (always xx% or more!) and this post is not that. It also won't solve everyone's product pricing dilemma although it should help. What this is -- a real example of how this small company not only landed on a price, it was backed up by actual data (and money changing hands!) and also solved for &amp;quot;&lt;em&gt;what should we build first?&lt;/em&gt;&amp;quot; implementation of this product.&lt;/p&gt;
&lt;p&gt;First off, we knew what it cost to produce the thing. Let’s say $25 each. So we knew we had to charge more than that. Also, due to customer interviews, our demographic was more niche so an assumption was we could charge a lot more than $25. But how much more? Could we charge 50, 100, 500? How many of them at a time? What could the market allow? What WOULD it allow? We went back to the customer interviews.&lt;/p&gt;
&lt;p&gt;During several of the interviews a dollar amount came up. This was important because, unsolicited, the customers were giving us a range they expected. Bonus, it was above the $25 it cost. Way above. So that gave us very loose, almost subjective evidence our first assumptions were in the right direction (niche, and high value). Most interviews have a problem of leading the witness and giving the customers a range -- but this? This was a customer saying if it existed, right now, they would pay X.&lt;/p&gt;
&lt;p&gt;This was solid gold, and we took the extremes, 50-1000 …and did another round of interviews with qualified buyers. The answer we got was around 6 for 250. Was this number real? Would people actually pay this amount or was it just a polite, courtesy number? The business side of the house pushed -- “People want this, they love it! We need it done so we can sell it!” So, I issued a challenge.&lt;/p&gt;
&lt;h3 id="call-up-the-last-10-people-and-take-their-money"&gt;Call up the last 10 people and take their money.&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Four&lt;/em&gt; (!!) people put their money down, each was completed via manual process, start to finish. Each of the 4 customers were beyond happy and started to tell their friends and introduce us.&lt;/p&gt;
&lt;p&gt;We now had a real number to start with, knew exactly what to build/automate and the customers were on our side. Wins all around and stronger evidence we were on the right path! We ran with this immediately (actionable data!) and started looking into what almost everyone does, create tiers of offerings, which we did. 100, 250, and 500. With a bit of that anchoring, we expected customers to pick the middle one – and that was the assumption we were really testing now.&lt;/p&gt;
&lt;p&gt;All of this took a few weeks, thanks to a highly engaged team that had no problems reaching out to potential customers, asking them some questions and reporting back. Oh, and as for the various tiers? We were wrong, an overwhelming percentage went for the top tier, signaling they wanted more. A wonderful problem to have.&lt;/p&gt;
</description>
      <pubDate>Mon, 31 Jul 2023 18:34:56 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/restore-an-azure-sql-or-bak-file-to-a-docker-container</guid>
      <link>https://rileytech.net/posts/restore-an-azure-sql-or-bak-file-to-a-docker-container</link>
      <title>Restore an Azure Sql or .bak file to a docker container</title>
      <description>&lt;p&gt;Moving a sql server from on-prem to cloud isn't nearly as bad as it use to be, but I ran into an interesting problem around restoring the production copy of a database to my local docker container. Soooo I created a script to fully, completely restore a local database. I'll say this again for those in the back...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This script builds from nothing, each time.&lt;/strong&gt; If you need to save stuff, modify it as necessary.&lt;/p&gt;
&lt;p&gt;The only tool you'll need to download is SqlPackage. It's small and if you have dotnet CLI already installed, it's painless. Grab it here and pick your flavor of host OS.
&lt;a href="https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-download"&gt;https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Also I'm assuming you already have docker installed and some sql database out in Azure.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="tldr"&gt;TL;DR&lt;/h3&gt;
&lt;p&gt;Feel free to skip ahead and go right to the one stop gist shop I created. Drop the files in a folder, the script will figure it out. Also, on the first run &lt;strong&gt;it will throw an error&lt;/strong&gt;, but be completely fine, it's because you don't have a named container yet, but you will soon. Also, I've included it all down below (it's also from gist).
&lt;a href="https://gist.github.com/jeriley/2f9ab76536edac2d78e554f44d80d31a"&gt;https://gist.github.com/jeriley/2f9ab76536edac2d78e554f44d80d31a&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="details-and-breakdown.a-modern-take-on-an-old-script-dbnuke"&gt;Details and breakdown. A modern take on an old script &amp;quot;DBNuke&amp;quot;&lt;/h3&gt;
&lt;p&gt;A while ago, the team I worked on had a script that was called &amp;quot;DBNuke&amp;quot;. It was the script I ran when I had messed up my database so bad, I had to completely start over. It was a fantastic thing and I did it regularly and this is sort of a modern take on that idea. Start over, with a known set of data. You could use this to do exactly that if you wish. Check in a DB version you like into your code and point a curl command to it - maybe for another time.&lt;/p&gt;
&lt;h3 id="bacpac"&gt;bacpac&lt;/h3&gt;
&lt;p&gt;Now for the details of each of these. Let's start with the bacpac file and I'll skip the parameters, because those are somewhat boring and boilerplate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull mcr.microsoft.com/mssql/server:2022-latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pull yourself a sql server container. I didn't test this out with 2019 but prior versions of this, I did, and the spin up procedure use to be a bit different, I had to set an SA password in a separate step so just be aware. At the time of this writing the size was around 1.8gb.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker kill ${containerName}
docker container rm ${containerName}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This freaks out on the first run because I didn't bother to create a check to see if the containers already existed and if they're running. After the first time, you might see the &lt;code&gt;docker kill&lt;/code&gt; command throw an error (because the container isn't running) but meh, it's good enough and doesn't hurt anything.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
cd $dir
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Boiler plate to get the location that the script is running from.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SqlPackage /Action:Export /TargetFile:&amp;quot;./${azureDbServer}-backup.bacpac&amp;quot; /SourceConnectionString:&amp;quot;Server=tcp:${azureDbServer}.database.windows.net,1433;Initial Catalog=${dbName};User ID=${azureSqlUser};Password=${azureSqlPassword};Persist Security Info=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most, if not all of this I pulled from an example on Microsoft's site and parameterized it. This is entirely runnable independently and I plan on created a cron job to have an offsite backup.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -e &amp;quot;ACCEPT_EULA=Y&amp;quot; -e &amp;quot;MSSQL_SA_PASSWORD=${localSqlSAPassword}&amp;quot; --name ${containerName} -p 1433:1433 -v /var/opt/mssql/backups -d mcr.microsoft.com/mssql/server:2022-latest

#wait for the container to spin up
Start-Sleep -Seconds 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This hurts me to do a wait-state (they're a huge code smell, this is this no different) - I wasn't able to find a way to know if the docker container had fully spun up. So when the &lt;code&gt;docker run&lt;/code&gt; command fires off, it takes a little bit to come up. My local has a very healthy amount of power and still takes at least 7 seconds. Adjust this as necessary, your mileage may vary.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SqlPackage /Action:Import /SourceFile:&amp;quot;.\${azureDbServer}-backup.bacpac&amp;quot; /TargetConnectionString:&amp;quot;Server=localhost;Initial Catalog=${dbName};User ID=sa;Password=${localSqlSAPassword};TrustServerCertificate=True;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we restore that database to the local (and ideally fully running) sql server! Go look at the log output during this time. It's kinda fun to see it doing its thing.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker cp ./addUser.sql ${containerName}:/var/opt/mssql/backups
docker exec -it ${containerName} /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${localSqlSAPassword} -i &amp;quot;/var/opt/mssql/backups/addUser.sql&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These last two lines are more security minded. The application I have doesn't use the SA account to run the server so script setups a db user with datareader and datawriter. Again, your mileage may vary, but for most, this should be sufficient.&lt;/p&gt;
&lt;h3 id="bak"&gt;bak&lt;/h3&gt;
&lt;p&gt;Most places I know of are still on-prem with regular sql backups that result in a .bak file. These are totally fine too! The beginning of the script is the same, until the actual restore.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#copy files to container
docker cp ./${backupFileName} ${containerName}:/var/opt/mssql/backups
docker cp ./restore.sql ${containerName}:/var/opt/mssql/backups
docker cp ./addUser.sql ${containerName}:/var/opt/mssql/backups

#restore
docker exec -it ${containerName} /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${localSqlSAPassword} -i &amp;quot;/var/opt/mssql/backups/restore.sql&amp;quot;
docker exec -it ${containerName} /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${localSqlSAPassword} -i &amp;quot;/var/opt/mssql/backups/addUser.sql&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, I copy over the necessary files into the container and execute them from the inside. It's worth noting and considering if I should leave those files behind or not -- I can hear the security team saying &lt;strong&gt;DO IT!!!&lt;/strong&gt; Again, your mileage may vary (but yes, you should clean up those files)&lt;/p&gt;
&lt;h3 id="and-thats-it"&gt;And that's it!&lt;/h3&gt;
&lt;p&gt;I really like the idea of being able to go from nothing to full, operational database in a few minutes. It was something that was awesome years ago ...except now, it's WAY faster!&lt;/p&gt;
&lt;p&gt;And here's the code for those that want to save a click or two.&lt;/p&gt;
&lt;script src="https://gist.github.com/jeriley/2f9ab76536edac2d78e554f44d80d31a.js"&gt;&lt;/script&gt;
</description>
      <pubDate>Wed, 19 Jul 2023 16:12:15 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/clientid-option-must-be-provided-buti-already-provided-it</guid>
      <link>https://rileytech.net/posts/clientid-option-must-be-provided-buti-already-provided-it</link>
      <title>ClientId option must be provided. But...I already provided it!</title>
      <description>&lt;p&gt;Hopefully this'll save someone time off their life.&lt;/p&gt;
&lt;p&gt;If you want the TL;DR -- Are you on a Linux instance running .net? Remove dots out of the configuration key. ie, &amp;quot;Auth.Google.ClientId&amp;quot; to &amp;quot;AuthGoogleClientId&amp;quot; and it works.&lt;/p&gt;
&lt;p&gt;Now for the robots and AI out there. Say I have this error being spit out of the Azure instance, taking down my app...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.ArgumentException: The 'ClientId' option must be provided. (Parameter 'ClientId')
         at Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions.Validate()
         at Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions.Validate(String scheme)
         at Microsoft.AspNetCore.Authentication.AuthenticationBuilder.&amp;lt;&amp;gt;c__DisplayClass4_0`2.&amp;lt;AddSchemeHelper&amp;gt;b__1(TOptions o)
         at Microsoft.Extensions.Options.ValidateOptions`1.Validate(String name, TOptions options)
         at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
         at Microsoft.Extensions.Options.OptionsMonitor`1.&amp;lt;&amp;gt;c__DisplayClass10_0.&amp;lt;Get&amp;gt;b__0()
         at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a moment of &amp;quot;...what ClientId?&amp;quot; I see a bit lower in that stack above, OAuth. Ah, I must have my ClientId and/or secret incorrect. Jumping over to Configuration, App Settings ...hmm.&lt;/p&gt;
&lt;p&gt;&lt;img src="/data/jesse/2023/7/clientId-is-there.jpg" alt="data/jesse/2023/7/clientId-is-there.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Ok, well, maybe I didn't hit save, and the values are blank&lt;/p&gt;
&lt;p&gt;&lt;img src="/data/jesse/2023/7/clientid-has-stuff.jpg" alt="data/jesse/2023/7/clientid-has-stuff.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;I verify these entries with the googles and its right. Maybe I messed up something with the code? (I was playing around in there so...)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services.AddAuthentication(options =&amp;gt; {})
    .AddGoogle(googleOptions =&amp;gt;
    {
	    googleOptions.ClientId = builder.Configuration[&amp;quot;Auth.Google.ClientId&amp;quot;];
	    googleOptions.ClientSecret = builder.Configuration[&amp;quot;Auth.Google.Secret&amp;quot;];
	    googleOptions.CallbackPath = &amp;quot;/auth/google&amp;quot;;
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For fun, I run the app locally, JUST to be sure I'm not totally missing something ...and of course it works just fine. I love these kind of problems.&lt;/p&gt;
&lt;p&gt;I burned down the entire instance which wasn't at all necessary but when things don't make sense, I like to start over. This time, I happen to pick a windows based container instead of linux. To my surprise, everything worked, setup the exact same way. So what is going on?&lt;/p&gt;
&lt;p&gt;Seeing the &lt;code&gt;ClientId&lt;/code&gt; error seemed strange to me, like it wasn't picking up the rest of the configuration key (spoilers) so I pushed up a new bit of code, removing the dots out of the keys. Simple thing to test out, right?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;googleOptions.ClientId = builder.Configuration[&amp;quot;AuthGoogleClientId&amp;quot;];
googleOptions.ClientSecret = builder.Configuration[&amp;quot;AuthGoogleSecret&amp;quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="/data/jesse/2023/7/no-more-dots.jpg" alt="data/jesse/2023/7/no-more-dots.jpg" /&gt;
&lt;em&gt;Don't forget to hit save!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Everything worked as expected. Sigh.&lt;/p&gt;
&lt;p&gt;Oh, and don't forget to update your local secrets. For the lazy, that command is&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet user-secrets set &amp;quot;key&amp;quot; &amp;quot;value&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet user-secrets remove &amp;quot;key&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and to find if you're on a linux instance or not, that's found here.
&lt;img src="/data/jesse/2023/7/linux.jpg" alt="data/jesse/2023/7/linux.jpg" /&gt;&lt;/p&gt;
</description>
      <pubDate>Fri, 14 Jul 2023 15:05:58 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/is-luck-a-dirty-word</guid>
      <link>https://rileytech.net/posts/is-luck-a-dirty-word</link>
      <title>Is Luck a dirty word?</title>
      <description>&lt;h3 id="the-harder-i-work-the-luckier-i-get"&gt;The harder I work, the luckier I get&lt;/h3&gt;
&lt;h4 id="someone.probably"&gt;- Someone. Probably.&lt;/h4&gt;
&lt;p&gt;All too often, in order to explain how in the world things all came together at one magical moment, we as humans will do a few things - force meaning and reason onto it, say it was all skill, chalk it up to luck. Is that fair? Is that a disservice to those I'm explaining it to?&lt;/p&gt;
&lt;p&gt;We've all heard that before, work hard and create your own luck. I recently found myself deeply rethinking this. It was not luck. At all. What I found more interesting was when I talked about luck, it was hiding the hard work and other things that I may not be able to put into words.  &amp;quot;How'd you know?&amp;quot; &amp;quot;Just got lucky&amp;quot;. It was also the context, who I was talking to, and so on.&lt;/p&gt;
&lt;h3 id="dont-show-your-work"&gt;(Don't) Show your work&lt;/h3&gt;
&lt;h4 id="busting-knuckles-for-years.is-lucky"&gt;Busting knuckles for years... is lucky&lt;/h4&gt;
&lt;p&gt;I recently bought a car with a blown engine that was... undriveable. I got it cheap, and knew the amount work I had to do before I got into it. I had done another car, long before this one and it was an absolute, total disaster. Worse than that, I did not have any type of support network, nor people around that were truly knowledgeable. Learning from my very educational (and expensive) mistakes, this time, I had decided it was within my realm of skill and knowledge, (the race team I had joined was a big help) even though I had not done this level of work to this kind of car. At least I knew what I was getting into this time around.&lt;/p&gt;
&lt;p&gt;The list of things that could go wrong is staggering but I accepted that risk for the reward. The reward? A reliable, fun car ... with ~60% more power than it had before. What, I'm not going to do all this work without fixing literally everything in the process. Like writing a bunch of unit tests for code I didn't write.&lt;/p&gt;
&lt;p&gt;During a holiday break, I wasn't prepared. The family had seen my posts about it and everyone wanted to ask me about it, &amp;quot;how's the car coming along?&amp;quot;. At the time I had run into a nasty problem where the car wouldn't run for more than 30 seconds and I had no idea why. I left that part out. Instead, I said overall it went way better than I could've expected and how &lt;strong&gt;lucky&lt;/strong&gt; I was during the whole process.&lt;/p&gt;
&lt;p&gt;Luck had nothing to do with any of it. It was paid for way ahead of time from the countless hours of past car work, having nearly all the right tools (for the first time in my life by the way), a heated garage (heaven), the space for it, another car to drive in the meantime, and a literal expert on this type of car on standby if I got stuck. In other words, all the things I needed, and more, to make it as seamless as possible.&lt;/p&gt;
&lt;h3 id="not-everyone-wants-to-work-for-it"&gt;Not everyone wants to work for it&lt;/h3&gt;
&lt;h4 id="fans-vs-athletes"&gt;Fans vs Athletes&lt;/h4&gt;
&lt;p&gt;Context comes into play, like hearing a winning team talk about how &amp;quot;the plan just came together&amp;quot;, &amp;quot;a few key plays&amp;quot; and &amp;quot;we just kept at it to win&amp;quot;. What they don't talk about is the weeks of preparation, the analysis, the drills, the work that went into giving themselves the best chance of winning. Depending on who's around, this may not be good to dive into, and worse if you do - alienating them doesn't take long, and they get bored.&lt;/p&gt;
&lt;p&gt;Going back to the family's questions about the car, I found most of them were fans of the work I was doing. Not only the &amp;quot;I can't believe you have done so much work in so little time&amp;quot; but even a &amp;quot;thank you for sharing, I feel like I was part of this somehow&amp;quot;. They were &lt;strong&gt;fans&lt;/strong&gt;, and no desire to turn a wrench - and that's fine!&lt;/p&gt;
&lt;p&gt;When I would talk with others that knew what I was doing and had done it themselves, I could dive into those plans that I couldn't with &amp;quot;fans&amp;quot;. They'd offer up reminders and pit-falls to look out for, and ask when would I be working on it next. No luck to be found while around other athletes.&lt;/p&gt;
&lt;h3 id="there-is-a-catch"&gt;There is a catch&lt;/h3&gt;
&lt;h4 id="hi-confirmation-bias-here-hello"&gt;hi, confirmation bias here, hello!&lt;/h4&gt;
&lt;p&gt;I've certainly been using &amp;quot;luck&amp;quot; to carry on the conversation, the story, of what I was doing and finding a balance of how much detail to include. Ultimately, it hides how much work it really did take to come to a conclusion, an outcome. So what? It's a dirty word when luck and skill are mistaken, and confirmation bias shines.&lt;/p&gt;
&lt;p&gt;If the number of variables that lead to success make it unclear if what I did was &lt;em&gt;the&lt;/em&gt; thing that made it happen, then yes, I think luck is a dirty word and can be quite dangerous. If I were to say how clearly I'm an expert in selecting a replacement engine, confirmation bias would kick in my door like the kool-aid man. I had no control of it being a complete failure. I got lucky.&lt;/p&gt;
</description>
      <pubDate>Tue, 13 Dec 2022 17:27:36 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://rileytech.net/posts/yes-you-should-test-logging-statements</guid>
      <link>https://rileytech.net/posts/yes-you-should-test-logging-statements</link>
      <title>Yes, you should test logging statements</title>
      <description>&lt;p&gt;Tell me if this sounds familiar.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Something breaks, somewhere in the code.&lt;/li&gt;
&lt;li&gt;It's reported, usually in some kind of panic.&lt;/li&gt;
&lt;li&gt;Emails are exchanged&lt;/li&gt;
&lt;li&gt;&amp;quot;All hands on deck&amp;quot;&lt;/li&gt;
&lt;li&gt;The problem is identified&lt;/li&gt;
&lt;li&gt;It had nothing to do with your product.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Working with a team and noticing a lot of things being logged left and right, I mentioned how testing can build all kinds of confidence in a system. From small parts to full on selenium tests that mimic a user, these parts all work together to get that feedback &lt;strong&gt;sooner&lt;/strong&gt;. A part of this that is way too often overlooked is logging statements. This team was no different in treating logging statements as a &amp;quot;we have to&amp;quot; and not looking deeper into how they could make them not only more meaningful, but also tightening up debugging and other serious problems that will certainly be long forgotten by the time it happens.&lt;/p&gt;
&lt;h3 id="why-do-you-bother-with-logging-statements-in-the-first-place"&gt;Why do you bother with logging statements in the first place?&lt;/h3&gt;
&lt;h4 id="to-know-what-happened"&gt;&amp;quot;To know what happened&amp;quot;&lt;/h4&gt;
&lt;p&gt;Logging statements isn't to be overlooked. It's code, real code, that is meant for humans at a later time. The better that is, and if it has a test around it, the faster I can find it and the code associated with it. Maybe even fix it quickly and safely.&lt;/p&gt;
&lt;p&gt;I went around the internet to find how so many devs dismiss this as well. The answer is simple really - it's really hard to do in most frameworks. Why? Static injection of old frameworks (looking at you java) which makes it way harder to mock and capture the items logged. Also, log statements aren't really seen as a valuable thing in development, even in the all mighty enterprise.&lt;/p&gt;
&lt;h3 id="are-you-sure-you-logged-what-you-think-you-logged"&gt;Are you sure you logged what you think you logged?&lt;/h3&gt;
&lt;h4 id="prove-it-with-a-test"&gt;Prove it with a test!&lt;/h4&gt;
&lt;p&gt;Most logging statements I see go something like this...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_logger.log(&amp;quot;Attempting the impossible&amp;quot;);
try {
  _logger.log(&amp;quot;here we go &amp;quot; + User.Name);
  _service.doStuff();
   _logger.log(&amp;quot;yay &amp;quot; + objectOfSomeKind.Property + &amp;quot; did its thing and all is well!&amp;quot;;
}
catch Exception ex {
  _logger.log(&amp;quot;This thing went boom&amp;quot;, objectOfSomeOtherKind.Property + &amp;quot; : failed in every way &amp;quot; + ex.Message)&amp;quot;;
}
  _logger.log(&amp;quot;All done!&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A simple test is to verify those logging statements &lt;em&gt;ARE ACTUALLY LOGGING THE THING YOU WANT TO LOG&lt;/em&gt;. So many times when a team goes back and tests and finds out it isn't, or the statement isn't particularly useful. A decent test would do the easy stuff first, test the successful pass, and maybe it looks like this...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Test]
public void process_logger_contains_4_message(){
  _logger.Messages.Count.ShouldEqual(4);
}

... 

[Test]
public void process_logger_contains_message_about_finishing(){
  _logger.Messages.Contains(&amp;quot;All done!&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not only does this &lt;strong&gt;prove&lt;/strong&gt; it works, and it works the way you think it does, it also brings into question its usefulness. Does it really matter if it logs that it completed a thing? Do we need four different logging statements or would a single summary at the end matter? What about that exception, can we do better or put some sort of extra information (or even a specific exception) that will help should something go wrong? These are important, and if they're not, why are you writing log statements in the first place?!&lt;/p&gt;
&lt;h3 id="it-also-helps-find-the-code-faster"&gt;It also helps find the code faster&lt;/h3&gt;
&lt;p&gt;Adding in tests documents what you were thinking at that point in time. If an issue comes out and one of these statements happens, its easy to do a search, find the tests and run them. Those tests should have a good set of assumptions in them too - you tested some things and not others? Perhaps those were not design considerations or things that were important. Now I have context and I can go back to ask &amp;quot;hey, this broke, but it doesn't look like any of it mattered at the time... can you tell me more about it and if we care?&amp;quot;&lt;/p&gt;
</description>
      <pubDate>Fri, 08 Jan 2021 15:00:00 Z</pubDate>
    </item>
  </channel>
</rss>