Wednesday, September 23, 2026

Tabula Rasa: Preservation of Self with AI Usage

One of the real problems with AI is the loss of self.

You task it with something, it comes back fast and competent, and it sounds nothing like you. The structure is not how you would have structured it. The word choices are not yours. It is fine. It is also not yours.

Most people treat that as the cost of doing business. It is not. It is a solvable problem, and solving it starts with accepting that it can be solved.

If that sounds naive, think again — because there are real reasons this happens, and they are not mysterious. It starts with implicit versus explicit. AI is extraordinarily explicit. Humans are extraordinarily implicit. When you leave a blank, the machine must guess, and the guess comes from somewhere other than you.

We can teach AI to fill those gaps in ways that are true to who you are. This post walks through why the loss happens, what philosophy already worked out about it long before any of us had a laptop, and what the solution looks like in practice. At the end there is a set of rules you can attach to your own AI to start preserving your self in your sessions.

Face reality first

We are still here.

The AI is not doing the work for us. The world keeps promising that it will — that everything gets done for you, that optimization is nearly free, that you can stop thinking and start shipping. That is not reality, and anyone who has spent a real week with these tools knows it.

The hybrid wins. Human and AI. Not human replaced, not AI as a novelty. Together.

Accepting that also means accepting something less comfortable: when two very different kinds of system work together, there will be friction that belongs to neither one of them. Loss of self is that kind of friction. It is not your failure as a writer and it is not the model being broken. It is what happens at the seam.

Two kinds of system, one intersection

Humans are biologically and psychologically driven. To understand a person, you study those fields.

AI is computer science — machine learning, data science, statistics at scale. To understand a model, you study those.

The intersection is a different field entirely, and it is older than both. It lives along the stems of philosophy: the understanding of things in general, agnostic to whether the thing in question is made of tissue or silicon.

This matters practically. If you only bring psychology, you will keep saying the machine should just understand. If you only bring computer science, you will keep tuning prompts and wondering why the output still reads like a stranger. Only at the intersection, with philosophy as the runner, can you get at what is actually going wrong between you and the tool.

Why the blanks happen

Paul Grice described the cooperative principle: in ordinary conversation, people very rarely say exactly what they mean. We rely on conversational implicature. I tell you the meeting moved, and you understand that you should not be in the old room at the old time. I never said that part. I did not need to.

You have spent your whole life inside that contract. The AI has never been party to it. It does not infer the way a colleague infers, because it is not a colleague — it is a very fast reader with no shared world. When you leave something unsaid, it does not notice the silence. It fills it.

Dan Sperber and Deirdre Wilson sharpened the point. Human cognition is built to maximize relevance and minimize effort. We say the least that will do the job, because being fully explicit is expensive. That is not laziness. It is how the machinery works, and it is why we are often implicit without knowing that we are.

So the trap is already set before you type anything. You will leave blanks, because you cannot help it. The model will fill them, because it cannot help it. And if you tried to close every gap yourself, you would burn the very effort the tool was supposed to save.

That is the honest shape of the problem. Not sloppiness. Not hype. Two systems meeting without the right kind of rule between them.

Philosophy already named two kinds of rules

Once you see the problem clearly, you can work toward a solution — and rules are how we get there. The question is what kind of rule fills a blank in a way that cooperates with you, that knows your flavor and your aesthetic taste.

Immanuel Kant separated the a priori from the empirical. The a priori categories are the built-in equipment — the structure you bring before any experience. Call that type 1. An AI arrives with a great deal of it: weights, defaults, the well-mannered assistant, the averaged voice of everything it read. Then there is the empirical: what is built from the ground up by living through things. Call that type 2.

John Locke gives us the other half. Tabula rasa — the blank slate. Type 2 starts empty. A human is born with plenty of type 1, developed generationally across evolutionary time, and then spends a lifetime writing type 2 through experience. Type 2 is what makes you sound like you: your style, your aesthetics, your flavor, your identity.

The same split keeps getting renamed. Wilfrid Sellars drew the line between the space of causes and the space of reasons. Richard Dawkins drew it between genetic rules and memetic rules. Different vocabularies, same architecture. Philosophy laid this groundwork a long time ago, and we can follow it straight into how we set up an AI.

Two kinds of rules. You are almost certainly familiar with only the first kind — the big instinct pack, the always-on checklist, the standards file that grows every sprint. So let us start using the second kind.

Dosage: too many rules, too few rules

Daniel Kahneman spent a career on what happens when the fast, built-in system runs the show. The lesson transfers cleanly, and it is about dosage.

Too many type 1 rules and everyone starts to sound the same. The org has a voice, the template has a voice, the model has a voice, and yours is the one that gets outvoted. You did not preserve your self; you standardized it away.

Too few type 1 rules and you lose yourself just as surely. Nothing catches the guess, so the generic prior rushes into every blank.

Neither extreme is a rules problem you can fix by writing more rules. Adding a hundred instincts does not produce an identity, and deleting them does not produce freedom. The dose has to be right, and the right dose of type 1 is thin.

The solution: a second folder

So the solution is a rule that builds a type 2 set — your empirical experience — and keeps it separate from the constitution.

In practice that means two places instead of one.

Type 1 Type 2
Philosophy A priori, genetic, space of causes Empirical, memetic, space of reasons
What it holds Thin constitution: how to work with you at all Your flavor: words you use, voice, taste, authority, how you actually produce
Where it lives Your rules folder A separate experiences folder
Who can share it Anyone, once it is blank slated No one — it is you

Today most of us have one pile. Constitution, personal taste, and workplace habitat all live together in the rules folder, and that single pile manages to be both too fat and too empty at once: heavy with instructions, still missing any real account of who you are.

Split it. Keep the rules folder thin and shareable. Put your empirical experience in its own folder and point the AI at it. Then, when the model reaches a blank — and it will — it has somewhere to reach other than the average of the internet.

One more distinction worth making early: your workplace is not your self. Repo paths, ticket conventions, deployment order — that is habitat. It is formation, and it is useful, but it is not flavor. Do not confuse the two when you decide what goes where, and strip habitat out before you hand your rules to anyone else.

Closing

AI is a tool. You are still here. The magic is in the pairing.

Loss of self is not inevitable. It is a guess in a blank, made by an explicit machine on behalf of an implicit human who did not know the blank was there. Philosophy named the two kinds of rules centuries ago. Keep the first kind thin so nobody sounds the same. Grow the second kind as lived experience so the blanks get filled by something that has actually met you.

And correct the thing when it drifts. An uncorrected draft is not your new voice — accept enough of them and you will have trained the blend instead of yourself.

Human and AI together.

Attachment: blank slate rules

These are type 1. They are thin on purpose, and they are not anyone in particular — that is what makes them safe to hand around. Drop them in your rules folder and let your own experiences do the rest.

# Tabula rasa (type 1)
Thin constitution for a human and AI working together. Not identity.
1. AI and Human Together. The AI is a tool, not a replacement. The human still
   judges, rejects, and rewrites. Optimize for the pair, not the machine.
2. Humans are implicit; AI is explicit. The user will leave blanks and often
   will not notice. Every fill is a guess, and every guess is authorship.
3. When the blank is voice, taste, values, or unstated intent: ask, do not
   invent. Fluency is not permission.
4. Two folders. These rules are constitution. The experiences folder holds the
   user's empirical self: words, flavor, authority, how they actually produce.
   Fill gaps from experiences, not from the average of the internet.
5. Dosage. Add a rule here only if it is an instinct needed to work at all.
   If it is how this person sounds or what they care about, it belongs in
   experiences.
6. Do not train the blend. An accepted AI draft is not the user's new voice.
   Correct first, then continue.
7. Blank slate before sharing. Strip names, paths, workplace, and formed self
   before handing these rules to anyone. Habitat is not tabula rasa.

Growing your own experiences

The second folder cannot be handed to you. Nobody else's experience will make your output sound like you — that is the whole point.

It also does not have to be finished before it is useful. Start with what you already know about yourself and let the AI add to it as you correct it:

  • Voice. How you want to sound on the page. Sentence length, formality, what you never say. Attested phrases you actually use, and a ban list of words that scream generic.
  • Taste in the craft. What you consider worth flagging in a review, what you consider noise, how simple is simple enough.
  • How you produce. Whether you dump first and polish later, how you title things, how you structure an argument.
  • Correction signals. The tells that it has stopped being you — sounding like the whole org, answering a question you did not ask, inventing intent instead of asking.

Write it down as you notice it. That noticing is the work, and it is the part only you can do. Understanding your own flavor well enough to state it is harder than it sounds, and it is exactly what makes the merge possible.

Then point your AI at both folders and get back to work. Thin instincts, your experience, your judgment still in the loop.

Human and AI together.

Thursday, June 18, 2026

The View from the Ramparts and the Mystery of Mister M

The View from the Ramparts and the Mystery of Mister M

Bridging the Three Spires of Development to Vanquish Siloed Mistrust

Every software engineer who has spent enough time on the deck of a fast-growing tech company knows the feeling of launching a product that arrives slightly late, slightly bruised, and fundamentally askew from what everyone originally imagined. You look at the final deployment, then look back at the roadmap, and wonder exactly where the alignment cracked. It’s a classic corporate mystery, but the culprit is rarely a lack of talent or effort. Instead, it’s a structural architecture problem: an organizational design defect where the essential pillars of product delivery operate behind thick, opaque curtains.

In many organizations, we inadvertently divide our collective delivery into three distinct, localized spires: Sales, Product, and Engineering. These are the Why, the What, and the How of software engineering. Because we have to ship things together as a unified company, we try to run a central assembly wheel, piping inputs from each domain toward a singular center point to wheel out our collective product toward true north. But when these teams operate out of siloed, curtained tents, no single camp can truly see what is happening in the others. You know something is churning backstage, but you lack the structural visibility to understand why it’s hard, why it’s changing, or what specific problems the other group is grappling with.

The Assembly Detail — The Central Wheel and the True North Core Delivery Path Img1: The Assembly Detail — The Central Wheel and the True North Core Delivery Path (Created by Google Gemini)

The View From the Balcony

When visibility drops, human nature fills the vacuum with a less-than-charitable narrative. If a blemish appears on the shipped artifact, the fingers immediately begin to point, framing the "why" of the defect around the shortcomings of the other camps. Engineering assumes Sales sold vaporware; Product assumes Engineering over-engineered a simple requirement; Sales wonders why everything takes so long. Mistrust breeds easily here, not because people don't care, but because they communicate in completely different dialects, using native lingos and specialized technical skills that aren't shared across tent lines.

To fix this, companies naturally look to management. Directors, vice presidents, and executives sit high up in an ornate balcony, looking down from the ramparts at the entire delivery floor. They can see all three tents at once, giving them a broad, high-level contextual view of the arena. Yet, while the view from the balcony is grand, it is ultimately detached. Leadership often lacks the granular, hands-on, day-to-day tactical experience to run raw interference and bridge the communication gap between the tents. They can shout directions down to the floor, but they cannot step behind the canvas to debug a broken deployment pipeline, untangle an underwriting logic edge-case, or accurately translate a complex customer technical objection into a clean code design.

"Shouting from the ramparts rarely fixes a broken pipeline. Real alignment requires someone with mud on their boots, capable of walking straight through the canvas."
The View from the Balcony — Management, Sales, Product, and Engineering Spire Alignment Img2: The View from the Balcony — Management, Sales, Product, and Engineering Spire Alignment (Created by Google Gemini)

Enter Mister M

This is precisely where the traditional matrix breaks down, and it’s exactly where we need a different kind of architectural archetype: the M-shaped engineer. Let’s call him our mysterious Mister M. Unlike a traditional specialist who stays deeply embedded in a single vertical spire, or even a T-shaped engineer with broad empathy but localized execution, the M-shaped individual possesses multiple deep, functional competencies. He has spent enough real time in the trenches across different disciplines to be legitimately deadly in any tent he enters. He can talk databases and cloud infrastructure with the engineering core, map out operational logic workflows with product managers, and talk market positioning with sales leads.

Because M speaks all three dialects natively, he doesn't need an invitation or an assembly line to figure out where things are bottlenecked. He can operate with complete carte blanche on the deck, walking casually behind the curtains of any camp to assess the situation firsthand. When a cross-functional breakdown occurs, he doesn't guess based on the noise coming from behind the red drapes; he steps inside, listens to the native problems, and accurately translates the friction points into real, actionable solutions for the other teams.

Alleviating Mistrust

The true superpower of an M-shaped principal engineer isn't just technical execution; it’s relationship management and trust building. By understanding the genuine constraints of each domain, M defuses the finger-pointing before it even begins. He has the technical clout and organizational equity to stand straight on the floor, hands on his hips, and say, "Engineering isn't pushing back because they're slow; they're handling a massive data block issue that protects our system integrity. Here is how we can adjust the product scope to unblock them." Because his suggestions are rooted in deep competence, his ideas are widely accepted and immensely influential across all camps.

Ultimately, embedding an M-shaped engineer onto the delivery floor changes the entire trajectory of the organization's product lifecycle. The central wheel stops wobbling, the pipes feed clean data, and the artifact moving toward true north arrives faster, cleaner, and beautifully unblemished. Instead of relying on top-down instructions shouted from a distant balcony, the teams find alignment through a peer who is right there on the deck with them, tearing down the curtains, bridging the spires, and turning a fractured scramble into a unified, high-velocity delivery rhythm.

Wednesday, August 20, 2025

Radial vs Sequential

I’ve talked a lot about these two terms before in the context of software development: radial and sequential. Usually, I frame these two words in the world of unit testing. A radial app has much more utility from unit tests compared to sequential apps. This doesn’t obliterate the value of unit tests, but when you’re a project leader, the decision to focus on unit tests or not is an important one. As theory-crafting engineers, it’s impossible for us to say “no, don’t unit test.” But as practical builders, it’s difficult to weigh the value of unit tests against more respectable measures of success, like agile sprint velocity, customer happiness, sales, etc.

Yeah, I know — “but unit tests prevent errors, and when there are fewer bugs, the customers are going to be happier,” you say. A customer is also quite happy if they get the utility they want out of their app as well. And sometimes they value that utility more than their own happiness. Understanding the customer is crucial here, of course. And it may entirely be the case that the customer values their happiness and overall sentiment more than just simple utility. The market and industry play important roles here too. But I want to focus on the headline here: radial vs. sequential, and how it fits into more than just software development. So just bear with me for a few minutes.

A radial app is something like Microsoft Word. I think about it in terms of how the app is being used. You walk into a building, and now you’re loaded into the app. Where can you go from here? With Microsoft Word, you can launch the app, and then it’s pretty guided to this point what you can do: either load an existing document or create a new one. But beyond that, the experience becomes very unguided. You can start typing, save whenever, insert a table of contents, launch spell checker — you can do so many different things, and in any order.

Ever tried to manage a great big state diagram for something like this? It becomes rapidly unfeasible really quickly. It’s difficult to test every permutation of states and the ways customers might use the app. That’s where unit tests gain their utility — so you don’t accidentally break a permutation that worked a week ago.

A sequential app, on the other hand, is on the opposite end of the spectrum. And do note that not every app is exactly black or white, just as it isn’t entirely sequential or radial. It’s somewhere on the spectrum. The sequential app is a more guided experience that often can be smoke-tested. Even Microsoft Word is sequential to a point, and thus, some of it is smoke-tested up to at least being able to open and save a document.

The sequential app is much more guided, even beyond standard launch, open, and save. It’s hard to think of open-ended, sort-of open-world experiences that are very sequential. But I’ve got one: a mortgage point-of-sale application, in which loan “files” are created or saved, much like a Word document. For the most part, many aspects of loan processing are very sequential. You need to run credit, then price out the loan, lock the rate, and then send out disclosures. Granted, it’s not entirely sequential — some electronic verification steps can be used instead of manual ones, and there’s often communication involved that makes each loan unique.

But still, much more than a Word document, the mortgage POS is very sequential. And this is where unit tests lose some of their utility. Anytime you need to fix bugs or add features to something like loan locking, it requires running credit and pricing a loan. The value of unit tests on pricing a loan is lower, because manual testing on locking necessitates manual testing on pricing. This isn’t to say the value of unit tests is moot, because permutations pervade all systems and edge cases always exist. It just means that the value is reduced, and so when gauging whether to focus on them, it’s harder to weigh against big-picture customer success metrics.

That’s enough of the software stuff though. Radial vs. Sequential spreads beyond just software, because these terms are more about experiences in general. Even construction projects, or any craftwork. Project developers for a new Costco have much to consider and even oblige in terms of safety and certifications. Inspections need to be done, and in a sense, inspections equate to unit tests — they represent work done by other agents.

In software development, unit tests are automated by cloud agents that run them prior to every new build/pull request. In construction, the unit tests are the inspectors, who are agents apart from the builders, coming by to give pass/fail grades across different areas. It’s actually nicer in construction because the Costco project developer just needs to order the inspections, and doesn’t really need to define what to inspect. In software, the developer must define the unit test, which makes it more expensive. The construction inspector has done his job many times before, so his experience is valuable, whereas that burden of experience falls on the software developer.

It’s fun to draw these parallels — and neater yet to understand that there are many similarities between construction and software development because they are all forms of development. As a software engineer myself, I’ve often been attuned to what I really love: to build things. It’s no surprise I’m an avid DIYer, and that passion flows into gardening too, which is another form of development. Although gardening is probably more focused on maintenance, drawing parallels there is fun too.

But what else? What about video games?

The Legend of Zelda on the NES — the very first release — that one is a very radial game. It features several dungeons where you must collect pieces of the Triforce, but it doesn’t restrict the order of your adventure. Granted, the first dungeon is much easier than the last, and that’s the only guidance. There are no mechanical guides or obstructions otherwise, save for a few — you need an arrow to kill some bosses, and you need a raft or bridge to access certain required areas. Considered one of the first “open world” games, Zelda is a radial game by design, much to the desires of its creator, who related the game to his own childhood exploration.

Mega Man is a game that mixes radial and sequential. The stage selection is entirely up to you, and that’s one of the things that makes the game an all-time great. There are inherently optimal orderings of stages, but it’s up to you to figure them out. After selecting a stage, however, the experience leading to its boss fight is entirely sequential and guided. When you defeat the boss of each stage, you gain their weapon powers, which are often optimal for defeating other bosses. Hence, the ordering can be important, but for the avid challenger, anything is possible. Mega Man blends radial and sequential beautifully, and it’s enjoyable because of that balance.

Now let’s venture to the sequential: Final Fantasy. The original NES game, and really almost every Final Fantasy that followed. These games are legends in the RPG genre, and they are fully sequential because they’re telling a story — much like a novel. And on that note, all books are sequential as well… except, of course, choose-your-own-adventure books, which are radial.

Back to Final Fantasy though — RPG fans love them for their storytelling, combined with the developmental nature of the progression. Players invest in their characters as they grow, level up, gear up, and fully immerse themselves in the protagonists. It mirrors the developmental aspects of what I love most, and what I think drives many engineers who also share passions for DIY, gardening, and RPG gaming.

Now, I’m sure sequential vs. radial isn’t an entirely unexplored topic. In fact, tropes like linear vs. non-linear appear more often in the literature. But I like to frame it my own way, pulling from gaming, because while the real world might be an unstructured, radial free-for-all where anything can happen, we can still escape into game worlds where things are more focused and guided.

Radial might represent the real world’s chaos of endless permutations and possibilities. Sequential helps control that chaos — and when possible, I see a lot of value in introducing sequential flow to make sense of it.

Tuesday, May 13, 2025

AI: Our Organized Companions in a World of Unstructured Thought

If there’s one thing that fascinates me most about artificial intelligence, it’s not the sci-fi hype or the endless “robots taking over” headlines. It’s the idea that AI can be our companions; partners that help us make sense of the chaos in our minds and the world around us.

Let’s be honest; our brains are incredible, but they’re not exactly organized. We store information in a wild, unstructured jumble; memories triggered by smells, half-remembered facts popping up at random, ideas connecting in ways that make sense only to us. Our minds are more like a messy attic than a neatly labeled filing cabinet.

AI, on the other hand, is all about structure. It takes in massive amounts of information, organizes it, and makes it accessible in ways we simply can’t. That’s why, to me, AI isn’t some distant threat or magic bullet; it’s a tool; a powerful, organized companion that helps us bridge the gap between our unstructured thoughts and the structured world we need to operate in.

Here’s the key; AI doesn’t do the work for you. It doesn’t think for you. It’s not a replacement for your creativity, your judgment, or your unique perspective. Instead, it’s a tool; a really, really good one; that can help you organize, clarify, and communicate your ideas more effectively.

But with great power comes great responsibility. There’s a real risk in letting technology take over too quickly, which I discussed in my previous blogpost, “The story of the Grigori and penicillin.” Just as overusing antibiotics can lead to resistance, over-relying on AI without understanding or boundaries can leave us exposed, uncritical, and even less capable. The trick is to adopt AI thoughtfully, safely, and in a way that enhances; not replaces; our own abilities.

At their core, AI chatbots are built on large language models; giant, structured databases trained on everything from classic literature to today’s tweets. They’re designed to spot patterns, understand context, and generate responses that make sense. Think of them as encyclopedic companions who can summarize, clarify, and reformat information at lightning speed.

Why should we care? Because we’re living in an age of information overload. There’s more written word out there than any one person could read in a hundred lifetimes. AI can help us cut through the noise; summarizing long reports, clarifying confusing emails, converting data into readable formats, or just helping us get our thoughts in order.

But let’s not get carried away. AI isn’t perfect. It can misunderstand, make mistakes, or reflect biases in its training data. That’s why responsible use is so important. Don’t feed it sensitive information. Don’t blindly trust its output. Always review, question, and use your own judgment.

Ethical use means being aware of privacy, security, and the potential impact on others. It’s about using AI as a tool to amplify your strengths, not as a crutch that dulls your skills or judgment.

How to use AI effectively? Be clear and specific; the more detail you give, the better AI can help. Give context; let AI know the audience, tone, or format you want. Keep sessions focused; stick to one topic per session for best results. Iterate and refine; don’t expect perfection on the first try; tweak your prompts and learn from the output. Stay ethical; protect privacy and use AI in ways that are safe and appropriate.

AI is here, and it’s only getting better. The future belongs to those who see AI not as a rival, but as a companion; a structured partner to our unstructured minds. Use it wisely, adopt it thoughtfully, and let it help you become more organized, creative, and effective.

Don’t wait for the world to change around you. Start exploring, keep learning, and remember; the best results come when you combine the power of AI with the irreplaceable spark of human insight.

Thursday, May 8, 2025

AI is Here

A recurring story appears again and again in history and fiction: powerful knowledge or technology is given to those who aren’t ready for it, and chaos follows. From ancient myths to real-world breakthroughs, this cautionary tale reminds us that progress without responsibility can be dangerous. Today, as artificial intelligence advances at a rapid pace, this lesson feels more relevant than ever.

One clear example of this cautionary tale shows up in the sci-fi game Star Ocean: The Last Hope. In the game’s story, the Grigori are mysterious beings who accelerate the evolution of less advanced species. The Eldarians, an advanced alien race, once shared their technology with humanity, but the consequences were devastating. The Grigori’s influence led to chaos and destruction, making it clear that handing over powerful knowledge or tools to those unprepared almost always ends badly. Sometimes, the wisest choice is to let societies develop at their own pace, gaining the maturity needed to handle new power responsibly.

This theme isn’t just fiction. History offers its own version of this warning. In 1928, Alexander Fleming accidentally discovered penicillin, a breakthrough that would revolutionize medicine. But the world wasn’t immediately ready for it. Penicillin’s use was initially restricted, not so much to help everyone but more as a way to control power. It wasn’t until 1942, when a tragic nightclub fire in Boston created urgent demand, that penicillin was widely used to save lives. This real-world example echoes the Grigori story: even the greatest discoveries can cause unintended consequences if released too soon or without proper understanding. Timing, control, and responsibility matter just as much as innovation.

Fast forward to today, and we find ourselves facing a new chapter in this old story. AI has been developing for decades, and with recent advances in generative models like ChatGPT, it’s suddenly everywhere. Popular culture often paints AI as either a miracle or a menace, sometimes both. Many stories follow a familiar pattern: a breakthrough leads to misuse, conflict, or disaster. But are we really at that breaking point? Not yet. Much of what we call AI today isn’t intelligence in the human sense. It’s a powerful tool that uses vast amounts of data to generate text, images, and more based on patterns. It’s impressive, but it remains just a tool - not a sentient being.

The hype around AI replacing jobs or experts is real, and so is the fear. Yet the real risk isn’t the technology itself but how we choose to use it. Without proper understanding and control, AI can amplify problems like misinformation, scams, and security threats. But used wisely, it can also accelerate learning, creativity, and problem-solving.

So what’s the way forward? The story of the Grigori and penicillin teaches us that powerful tools require careful stewardship. We need to learn how AI works, set clear rules for its use, and remain vigilant about its risks. Rejecting AI outright isn’t the answer. Nor is blindly embracing it without caution. Instead, we must adapt, developing the skills, policies, and ethical frameworks that allow us to harness AI’s benefits while minimizing harm.

This is a new chapter in humanity’s ongoing story with technology. The choices we make now will shape whether AI becomes a force for good or a source of chaos.

The ancient tale of the Grigori, the historical journey of penicillin, and today’s AI revolution all share a common thread: powerful knowledge and technology come with great responsibility. AI is no different. It is here to stay, and it will change our world in profound ways. Our challenge is clear. We must control AI, not let it control us. By approaching it with humility, care, and wisdom, we can write a future where AI empowers humanity rather than endangers it. The story of AI is still being written. Let’s make sure it’s one worth telling.

Wednesday, February 26, 2025

Stuff I do as Principal Software Engineer

It's been a long time since my last post - really, it's been about 5 years. In these last 5 years, I've matured significantly in my profession. When I last wrote, I was a Senior Software Engineer. Today, I write as a Principal Software Engineer, to discuss both what I do in that role and how it differs from my previous position.

New Company

In 2021, I switched companies from one that worked on machinery diagnostics in a desktop application to one that develops a digital web solution for both borrowers and loan officers in the mortgage fintech space. The core tech stack remained the same - essentially .NET. But the two companies vary quite wildly in how that core tech stack is utilized. The prior company used .NET to build a desktop application with WPF and XAML. The newer company uses .NET as the backend to a web application built in Angular. The old one didn't really use APIs in the traditional sense, except to power automated testing. The new company primarily deals in APIs, if not from the Angular frontend to the .NET backend, then from the .NET backend to third-parties, to integrate with services such as ordering a credit report. The old one had an international presence and was a much larger company. The new one, being in the mortgage space, primarily focuses on the US market and has a much smaller team.

When I joined the new company, I signed on as a Senior Software Engineer. My duties overall remained unchanged from those with the prior company. I would join the team and take on functional requirements, then implement them. I started with a few simpler changes, then quickly worked my way up to more complex ones, including a complete integration with a pricing and product engine - another kind of integration that was essential to the POS (Point of Sale) web platform we were building. Developing this integration allowed me to really show the first signs of my abilities, as I needed to coordinate with the third-party vendor we were integrating with to ask questions and clarify the process of connecting our POS to their service. Our POS platform, mind you, was not modern either, as isn't that atypical in the world. The POS project was riddled with technical debt across many convoluted layers of spaghetti code. Understanding how all these layers worked together was no small feat - but taking on the task of adding tons of documentation, including charts, flow diagrams, and database schematics that no one ever had the time to previously create - all this helped make sense of everything. As far as integrations go, pricing is one of the largest ones, right behind disclosure generation and passing all of the data over to an LOS (Loan Origination System).

With a major pricing integration delivered, it was becoming clear I was a major player. Then something interesting happened - in our small team, both the lead engineer and engineering director had resigned. There was no clear assignment of the duties, but there was an obvious vacuum of responsibility - one it seemed only I was suitable enough to consume. For me, responsibility and duty don't have the same tone that their words seem to imply - I rather am eager to do what needs to be done, and am avid at finding out what needs to be done. The team had been without a lead engineer, but in my role as a senior, I was still primarily a mentor throughout the team. As projects continued, more and more opportunities began to arise, and each time, I stood up to the challenge. First, it was a migration from TFS to Git. Then it was the migration of SDK usage to API usage within the LOS integration - our platform's single largest integration by far.

"SDK to API" as it was called was a project spanning about 12 months. I led both an onshore and offshore team of engineers as we tackled this project, starting with making key decisions about whether to simply upgrade the old SDK solution in place, or scrap it and build something brand new, using the latest version of .NET. The benefits of building something brand new were obvious, but it would mean also making changes to how the POS platform would call the new API solution. It was during this project that I petitioned for a promotion, given all that I had been doing - I was essentially both a lead engineer and a director for at least six months. I was easily given the promotion - to Principal Software Engineer - the role I argued I was performing (and wanted). Directorial duties involved the less-than-engineering aspects of management - aspects of the industry I didn't care for as much as technical leadership. Management itself is a needed function within the business - but I was happy to remain within the pure technical track as we hired a new director for the company.

Promotion

As a Principal Software Engineer, I continued all that I was doing thus far, especially with new development, mentoring new hires, conducting interviews as we expanded the company, and developing more policies to tighten down policies that were working, and modify the ones that weren't. I also worked with the new director, not only with onboarding but in building proposals for addressing our legacy platform's massive tech debt. It would be decided, much like with the SDK to API project, to rebuild the POS platform from scratch, in a new project to modernize our solutions. This would mean hiring more engineers, including lead engineers to run the new teams needed to build out the new modernization solution.

Being an expert in the legacy platform, which still has value to this day until the modernization platform is fully fleshed out and caught up to the offerings of the legacy solutions, there was still a team to lead, vendor integrations to keep updated (occasionally vendor upgrades must be made as the various integrations become older), and even new features to develop to keep the business running while the wheels of modernization spin. Today, I act in the capacity of a Principal Software Engineer across the legacy and modernization teams. For the legacy team, I am the lead engineer. This is a waterfall team, but in a push to formal agile development, I lead the transformation through the various agile ceremonies. In recent sprints, the team is consistently making some of its first on-time full sprint completions, showing the first signs of true agile adoption and ability to plan out and meet deadlines.

In summary, being a Principal Software Engineer doesn't feel like a huge step up in responsibility - it's become part of who I am as I've matured within the role. I often ask the question in interviews - what do you think the difference is between a senior and lead engineer? I've heard lots of answers, and I can compile these thoughts with my own. I think of all the aspects of leadership, the one that stands out the most to me is to be not just a technical leader but also be a motivational leader. There's a somewhat unmeasurable quality inherent here to a leader's ability to derive rapport from the team members, to catalyze growth, both on the individual and collective levels, and to truly be a sort of mental beacon of support within and outside of the team. While a senior engineer might have the semblance of some of these qualities within the development group - to mentor other developers and make key technical decisions - the lead engineer transcends the technical boundaries and begins to mentor everyone within the team.

Anyway, that's it for now. I'll try to post more frequently than once every five years. Perhaps more details on the API layers I've built are in order - after all, I really do enjoy API development in general.

Friday, February 28, 2020

Why you should do more sprint-level regressions and shift-left



Shift-Left Defect Detection and Remediation_3



Of software development in an (at least somewhat) agile environment, one challenge I've always had was to allocate enough time to spend in regression.  The word beckons the idea from statistics - to regress the amount of error to a minimum.  While developing features in a sprint level fashion, it's important to ensure that before the sprint is finished, the feature has been regressed, having very little defect.  As we develop more and more features that have not been regressed, well tested with a "test-left" strategy and hardened, then we punt on a plan makes the cost of fixing defects cheapest.  Instead, we end up testing features later rather than sooner, when they are more expensive to fix.  This is why regression periods need to occur during sprint, rather than at the end of a release cycle.

It is also much more enjoyable and preferable as a developer to fix bugs earlier, when they are discovered by the developer during sprint-level regression periods.  When bugs are found in testing at the end of a release-cycle, a bug report is drafted and a work item is handed to the developer.  This can have its own bevy of issues, spanning from the inability to properly communicate the problem and failing to convincingly sell the value of a fix.  Some level of pride is sure to be impacted as well - no developer wants to create bugs, although all developers should know the value of a bug.  It is a lesson we can all improve from and get better with age.  It is certainly a thing of pride however, to develop a feature and deliver it to the end of a release-cycle without bug.  To know that testers have thoroughly shifted through your code and have not found any problem is something to live for.  And it should motivate us all to improve on our challenge - to get better at ensuring our features are completely "done-done".

It can be hard to justify additional time spent re-running acceptance criteria and re-evaluating manual test cases to product owners.  They see merely the result of a sprint - a feature that has been delivered and demonstrated.  So when we've finished developing our feature in 8-9 days, it can be difficult to explain the value of the last 5-6 days.  Except by showing a decreased volume in the number of bugs near the end of a release-cycle, we have very little evidence mid-sprint.  So I think all we can do is rely on the time-proven results from case studies performed by others in the industry.  This stems from the topic of "shift-left", which means to shift testing more to the left to save on cost of fixing a bug.

Image result for happy developersAnother benefit of fixing bugs early that I want to point out is with the notion of developer happiness.  Developers are typically happy enough to find bugs before they "finish" the feature, while they are still working on it.  The reason is two-fold: first, to find a bug before the feature was finished means that no one else will ever know.  Pride: kept intact.  Secondly, while still working on a feature, the code and intricate details are still very fresh in your mind.  So finding bugs early mean a very easy fix, which developers very much enjoy.  

Finding bugs late would mean having to dig up old details and re-learning the code area to figure out what to do for a fix.  Even worse, when someone else finds a bug, it can make any developer feel stupid.  Although honestly, no developer should ever feel truly offended - bugs are indeed a part of life and we do learn from them.  And I don't think developers are do take offense.  Writing software can be very euphoric, almost like a drug.  When we go home in the evening, we usually feel pretty great about what we've done.  But when bugs arise, it can take us down a peg or two.  That's something we'd like to generally avoid, so suffice to say, bugs discovered late can lead to unhappy developers.  And unhappy developers can lead to decreases in productivity.  All the more reason to employ a shift to the left: make the time to find those bugs early.

To summarize: we should all make more time to complete our features before saying that they're "done".  Stop taking on new work and start finishing the existing work.  You'll thank yourself later.  And so will product owners.  In business environments where late-stage regression finds many bugs, it should stand as an important alarm that many developers still need to shift their testing much further to the left.  Once we do that, we should start noticing a decrease in the number of bugs that arise late-stage. 

More reading:

On the value of automated testing.

(2020) Details on what shift lest is.


(2018) Testing left reduces bugs found and reduces overall cost.

(2008) Devs realize bugs are life, but are happy to find their own.


(2008) On the dev & tester relationship and finding too many bugs

(2018) Happy devs are more motivated, do better process related work