<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Inghilterra</title>
    <description>The latest articles on DEV Community by Michael Inghilterra (@michael_inghilterra).</description>
    <link>https://dev.to/michael_inghilterra</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4080397%2Fba842581-85a2-48d0-b6b4-088b686e99ee.jpg</url>
      <title>DEV Community: Michael Inghilterra</title>
      <link>https://dev.to/michael_inghilterra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michael_inghilterra"/>
    <language>en</language>
    <item>
      <title>The deals in your forecast that are quietly fiction</title>
      <dc:creator>Michael Inghilterra</dc:creator>
      <pubDate>Sat, 05 Sep 2026 18:28:17 +0000</pubDate>
      <link>https://dev.to/michael_inghilterra/the-deals-in-your-forecast-that-are-quietly-fiction-4j04</link>
      <guid>https://dev.to/michael_inghilterra/the-deals-in-your-forecast-that-are-quietly-fiction-4j04</guid>
      <description>&lt;h1&gt;
  
  
  The deals in your forecast that are quietly fiction
&lt;/h1&gt;

&lt;p&gt;Most forecasts miss for a boring reason. Not because the market turned or a big deal slipped, but because a share of the pipeline underneath the number was never real to begin with. The forecast was a hope with a number attached, and the number inherited every soft deal the hope was built on.&lt;/p&gt;

&lt;p&gt;I have spent my career in revenue operations, and pipeline quality is the dimension I check first, because it is usually the root cause of the two problems leaders complain about most: a forecast nobody trusts and reporting nobody acts on. You cannot report your way out of a pipeline that is not true. So before anyone touches the dashboard, I look at the deals themselves and ask a plain question about each one: is this real, or does it just have a stage and a dollar amount?&lt;/p&gt;

&lt;p&gt;Three kinds of fiction show up over and over. Here is how to spot each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fiction one: fluff
&lt;/h2&gt;

&lt;p&gt;Fluff is the deal that is technically open and effectively dead. No recent activity. A close date that has already passed and quietly rolled forward again. Stuck in the same stage for a quarter while everyone politely looks away.&lt;/p&gt;

&lt;p&gt;Fluff is easy to find and easy to ignore, which is exactly why it accumulates. Nobody wants to be the one who marks their own deal closed-lost, so it sits, padding the pipeline coverage ratio and making the top of the funnel look healthier than it is. The tell is simple: sort by last-activity date and look at anything untouched in the last few weeks that is still counted as active. Most of it is not a deal. It is a deal-shaped placeholder.&lt;/p&gt;

&lt;p&gt;The fix is not a cleanup project every quarter. It is a rule: no activity in X days moves a deal to a review state automatically, and the rep either revives it with a real next step or lets it go. Clean once and it re-rots. Enforce at the edge and it stays honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fiction two: sandbagging
&lt;/h2&gt;

&lt;p&gt;Sandbagging is the opposite problem, and it is sneakier because it hides inside good news. It is the deal that is ready to close now but forecast two quarters out. The rep is protecting themselves, banking a deal they are confident in so next quarter starts with a cushion.&lt;/p&gt;

&lt;p&gt;I understand the human incentive. But treat it as a scheduling quirk and you miss what it actually is: a data-integrity problem and a culture signal. When your best deals are deliberately misdated, your forecast is wrong in both directions at once. This quarter looks light, next quarter looks padded, and neither picture is real. You end up managing to a calendar the reps privately know is fake.&lt;/p&gt;

&lt;p&gt;The tell is a deal with strong qualification, a champion, a paper process underway, and a close date that does not match any of that momentum. When the evidence says now and the date says later, the date is the thing to question. Naming it out loud, without punishing the rep, is usually enough to start straightening the dates out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fiction three: the unqualified commit
&lt;/h2&gt;

&lt;p&gt;The third kind is the most expensive, because it looks the most legitimate. It is the deal sitting in commit or forecast with a confident number next to it and almost nothing underneath. No identified economic buyer. No understanding of how the customer actually buys. A champion who is really just a friendly contact with no power.&lt;/p&gt;

&lt;p&gt;This is where qualification earns its keep. You do not need a heavy framework to catch it, just the discipline to ask what is actually known. MEDDPICC is the shorthand I use, and the letters that matter most for a commit are the ones people skip: the Economic Buyer, the Decision Process, and the Paper Process. If a deal is forecast to close and nobody can name the person who signs, or describe the steps between a yes and a signature, that is not a commit. It is optimism with a due date.&lt;/p&gt;

&lt;p&gt;The single highest-leverage rule I have seen here is small: you cannot put a deal in commit without an economic buyer. Full stop. It sounds obvious. Watch how many deals fail it the first time you enforce it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the root cause, not a side issue
&lt;/h2&gt;

&lt;p&gt;Here is the part that makes pipeline quality worth fixing before anything else. The two problems everyone wants solved, a trusted forecast and reporting that drives decisions, both sit downstream of this. If the deals are fiction, the forecast built on them is fiction, and the dashboard on top is a very clean picture of something untrue. You can rebuild the reporting layer beautifully and still be wrong, because the error was underneath it the whole time.&lt;/p&gt;

&lt;p&gt;Fixing it is not glamorous. It is evidence gates on stage entry, so moving a deal forward requires something you can point to instead of a rep's feeling. It is honest dates. It is a weekly pipeline inspection that treats these three fictions as things to catch, not things to be polite about. Do that, and the forecast stops being a hope with a number attached and starts being a read on reality. Everything downstream gets easier, because it is finally standing on something true.&lt;/p&gt;

&lt;p&gt;The uncomfortable first step is admitting how much of the current number is one of these three. Most teams are surprised. The good news is that once you can see it, it is fixable, and the fix compounds.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I write about the systems that make revenue legible, and I run a productized &lt;a href="https://michaelinghilterra.com/audit" rel="noopener noreferrer"&gt;Revenue Engine Audit&lt;/a&gt; that scores this and four other dimensions of a revenue operation. If your forecast is not trusted, this is usually where it starts.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>revenue</category>
      <category>crm</category>
      <category>data</category>
    </item>
    <item>
      <title>What Tracking Every Job Application Actually Taught Me</title>
      <dc:creator>Michael Inghilterra</dc:creator>
      <pubDate>Tue, 01 Sep 2026 13:44:00 +0000</pubDate>
      <link>https://dev.to/michael_inghilterra/what-tracking-every-job-application-actually-taught-me-4841</link>
      <guid>https://dev.to/michael_inghilterra/what-tracking-every-job-application-actually-taught-me-4841</guid>
      <description>&lt;p&gt;Everyone has opinions about job searching. Apply to more. Apply to fewer. Follow up. Do not be annoying. Network harder. The advice cancels itself out, because almost none of it comes with numbers attached.&lt;/p&gt;

&lt;p&gt;I decided to keep the numbers. When I started my search, I tracked every role through real stages: scored for fit, applied, followed up, and whatever came back. A few weeks in, the data had opinions of its own, and some of them were not what I expected. Here is what it actually told me.&lt;/p&gt;

&lt;p&gt;A note before the numbers: I am keeping the raw figures private, partly because a single person's search is a small sample, and partly because the exact count matters less than the direction. What follows is honest about the direction and careful not to dress up a sample of one as a law of nature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fewer applications, more responses
&lt;/h2&gt;

&lt;p&gt;The headline surprised me. &lt;strong&gt;I applied to about half as many roles as I used to, and I heard back more.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That runs against the loudest advice in job searching, which is essentially "apply to everything, it is a numbers game." For me, treating it as a pure numbers game was the problem. When I scored roles for fit and only put real effort into the strong matches, two things happened at once. I sent fewer applications, and a higher share of them turned into a response.&lt;/p&gt;

&lt;p&gt;Put those together and the improvement was not small. My reply rate roughly doubled once I cut the volume and raised the quality. Same person, same resume underneath, far less scattershot. The effort I used to spread across twenty mediocre-fit roles went into eight good ones, and the good ones answered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow-ups were not optional
&lt;/h2&gt;

&lt;p&gt;The second lesson I would have argued with a few months ago.&lt;/p&gt;

&lt;p&gt;A meaningful share of my responses came only after a follow-up, not the first touch. Not a majority, but enough that if I had skipped following up, I would have simply never heard from those companies. Those responses would not have arrived later on their own. They would not have arrived at all.&lt;/p&gt;

&lt;p&gt;This is the part that is easy to talk yourself out of, because following up feels like nagging. The data did not care about my feelings. It just showed a stack of real conversations that started on the second contact, and none of them would exist if I had left it at "well, I applied."&lt;/p&gt;

&lt;p&gt;The catch is that follow-ups only work if they actually happen, and human memory is a terrible scheduler. Mine were reliable only once they were scheduled instead of remembered. That is a systems fix, not a willpower fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the responses actually came from
&lt;/h2&gt;

&lt;p&gt;The last lesson is the one I would tell every job seeker to check for themselves, because it changes where you spend your time.&lt;/p&gt;

&lt;p&gt;I tracked where each response originated: a warm intro or a referral on one side, a cold application into a portal on the other.&lt;/p&gt;

&lt;p&gt;Here is what I found: my warm reply rate ran about 2.8 times my cold reply rate. A referral or a real introduction was almost three times more likely to turn into a response than the same kind of role applied to cold, through a portal. And warm intros were the smaller share of what I sent, which makes the gap starker. The smaller pile produced the larger share of real conversations.&lt;/p&gt;

&lt;p&gt;Whatever the exact split, the lesson generalizes: the channel matters as much as the effort. An hour spent turning a cold application into a warm one, finding a real person to talk to, was worth more than an hour spent sending three more applications into the void. Once the data made that visible, I stopped treating all applications as equal work for equal reward, because they were not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell someone starting today
&lt;/h2&gt;

&lt;p&gt;None of this is a formula, and I want to be careful not to sell it as one. It is a sample of one person, in one field, over a stretch of weeks. But the direction was consistent enough that I trust it more than the generic advice it contradicts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply to fewer roles, chosen better. Volume is not the lever you think it is.&lt;/li&gt;
&lt;li&gt;Follow up, and schedule it so it actually happens. A real share of your responses is hiding behind a second contact you have not sent yet.&lt;/li&gt;
&lt;li&gt;Spend your time on the channel that answers. Turning cold into warm beats sending more cold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason I could see any of this is that I tracked it. The search stopped being a fog of tabs and became something I could actually read. That, more than any single number, is the thing I would hand to anyone starting out: make your own search legible to yourself, and let your data argue with the advice.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I built the tool I used to track all of this. It is called &lt;a href="https://michaelinghilterra.com/Trajecktory" rel="noopener noreferrer"&gt;trajecktory&lt;/a&gt;, it is open source, and the code is on &lt;a href="https://github.com/michaelinghilterra-creator/trajecktory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I write about building it, and running my search with it, as I go.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>data</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a System to Run My Job Search Like a Pipeline</title>
      <dc:creator>Michael Inghilterra</dc:creator>
      <pubDate>Sat, 29 Aug 2026 20:38:58 +0000</pubDate>
      <link>https://dev.to/michael_inghilterra/i-built-a-system-to-run-my-job-search-like-a-pipeline-54k6</link>
      <guid>https://dev.to/michael_inghilterra/i-built-a-system-to-run-my-job-search-like-a-pipeline-54k6</guid>
      <description>&lt;p&gt;Most job searches look the same from the inside: a dozen open browser tabs, a spreadsheet that was accurate for about four days, and a nagging feeling that something is slipping. Applications leak out the bottom. Follow-ups get forgotten. And after a few weeks of it, you have done a lot of work and learned almost nothing about what is actually working.&lt;/p&gt;

&lt;p&gt;I ran mine that way for a while. Then I stopped treating it as a to-do list and started treating it as a pipeline: named stages, a scoring step at the front, and a follow-up cadence that did not depend on my memory. That one shift changed how the whole search felt. Here is the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a list fails you
&lt;/h2&gt;

&lt;p&gt;A to-do list is good at exactly one thing: telling you what to do next. That is also its limit.&lt;/p&gt;

&lt;p&gt;A list cannot tell you what is working. It has no stages, so you cannot see where things stall. Are you not getting responses because your applications are weak, or because you are aiming at the wrong roles, or because you never follow up? A list shrugs. It just shows you the next unchecked box.&lt;/p&gt;

&lt;p&gt;And because a list rewards volume, it quietly pushes you to apply more without ever asking whether applying more is the problem. You end up repeating the same misses faster.&lt;/p&gt;

&lt;p&gt;The reframe is simple. A job search is not a list of chores. It has stages, the same way a sales pipeline does. Naming those stages is the first thing that changes, because you cannot improve a step you cannot see.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stages
&lt;/h2&gt;

&lt;p&gt;Here is the pipeline I settled on, in plain terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sourced.&lt;/strong&gt; A role you found and might go after, but have not evaluated yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluated.&lt;/strong&gt; You have looked at it seriously and decided it is worth pursuing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applied.&lt;/strong&gt; You are in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow-up.&lt;/strong&gt; You have applied and the clock is running on a nudge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview.&lt;/strong&gt; A human is talking to you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offer.&lt;/strong&gt; The point of the whole thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then the ways a role ends, which matter more than people think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No response.&lt;/strong&gt; You applied and heard nothing back. Ghosted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closed.&lt;/strong&gt; The posting closed before you got a real shot at it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discarded.&lt;/strong&gt; You decided it was not for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the part that took me a while to appreciate. Not every dead end is the same, and if you lump them together you lie to yourself about your own numbers. A role that ghosted you is a very different signal than one that closed before you could act, which is different again from one you walked away from on purpose. When you separate them, you can finally see where you are actually losing, and fix that stage, instead of just applying harder at the top and hoping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoring: spend your effort where it counts
&lt;/h2&gt;

&lt;p&gt;You cannot give forty roles your best cover letter. Anyone who tells you to "just customize every application" has never tried to do it forty times in a week. You have to choose, and the choosing is where a lot of searches quietly fall apart, because the loudest role (the one that just got posted, the one a friend mentioned) is not always the best fit.&lt;/p&gt;

&lt;p&gt;So I put a scoring step at the front. Each role gets a fit number based on what actually matters to me: the kind of work, the level, the things I will and will not compromise on. The strong matches get my real effort. The weak ones get a fast, guilt-free no.&lt;/p&gt;

&lt;p&gt;One nuance is worth calling out, because it is easy to get wrong. A single dealbreaker should cap the score no matter how good everything else looks. A role that is a 90 percent match on the work but requires relocating somewhere you cannot go is not a 90 percent match. It is a no with a nice paint job. Letting a hard constraint override the rest keeps the score honest, and keeps you from talking yourself into the wrong roles because the description was exciting.&lt;/p&gt;

&lt;p&gt;The payoff is not really about efficiency. It is about spending less time agonizing over where to put your energy, and more time actually putting it there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow-ups: timing beats volume
&lt;/h2&gt;

&lt;p&gt;Most people handle follow-ups one of two ways. They never do it, or they do it too much. Both lose.&lt;/p&gt;

&lt;p&gt;The fix is to stop treating follow-ups as something you remember and start treating them as something that is scheduled. In my system, applying starts a clock. A little while later (for me, about a week of business days), the role surfaces itself and asks for a nudge. I do not have to hold it in my head, which is good, because the human head is where follow-ups go to die.&lt;/p&gt;

&lt;p&gt;The other thing that helped was drawing a clear line between warm and cold. A warm follow-up has a real person on the other end, someone you can actually reach. A cold one is a portal, a black hole, an address that will never write back. Those deserve different energy, and pretending a black-hole portal is a warm lead just wastes yours.&lt;/p&gt;

&lt;p&gt;And when something is not dead but not active either, I can mute it indefinitely without deleting it. "Done for now." That keeps the active list honest, which matters, because an active list full of zombies is just a to-do list again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one number that told me the truth
&lt;/h2&gt;

&lt;p&gt;If I had to keep a single metric, it would be reply rate, but defined carefully.&lt;/p&gt;

&lt;p&gt;I count reply rate as the furthest stage a search ever reached, not wherever the role happens to sit today. A role that got to an interview and then went quiet still counts as a reply, because it was one. If I only looked at current status, that interview would eventually decay into "no response" and I would erase my own best signal.&lt;/p&gt;

&lt;p&gt;The honest denominator matters just as much. It is tempting to quietly drop the roles that ghosted you, because your numbers look better without them. But those are exactly the data points that teach you something. Count them. A reply rate that flatters you is worse than useless, because it tells you to keep doing the thing that is not working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;p&gt;I would love to tell you the system got me ten offers in a week. It did not, and that is not the point. What it did was less dramatic and more valuable: far less slipped through the cracks, I actually learned from the misses instead of repeating them, and the search got better over time because for the first time I could see it.&lt;/p&gt;

&lt;p&gt;A job search is stressful enough without also being invisible to the person running it. Giving it stages, a scoring step, and a cadence did not make the market easier. It made me a lot harder to knock off course.&lt;/p&gt;

&lt;p&gt;I built this into a tool called &lt;a href="https://github.com/michaelinghilterra-creator/trajecktory" rel="noopener noreferrer"&gt;trajecktory&lt;/a&gt; because I wanted it for myself. It is open source, and I write about building it as I go. If any of this sounds like the mess you are currently living in, the code is there to look at, or just steal the idea and run it in a spreadsheet. The system is the part that matters, not the software.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>opensource</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Relaunching my career by building the tool I needed</title>
      <dc:creator>Michael Inghilterra</dc:creator>
      <pubDate>Fri, 21 Aug 2026 20:22:06 +0000</pubDate>
      <link>https://dev.to/michael_inghilterra/relaunching-my-career-by-building-the-tool-i-needed-455h</link>
      <guid>https://dev.to/michael_inghilterra/relaunching-my-career-by-building-the-tool-i-needed-455h</guid>
      <description>&lt;p&gt;There is a particular kind of quiet that comes with a career relaunch. The calendar empties out. The feedback loop you were used to, the one where work tells you every day whether you are doing well, goes silent. And you are left with a search that feels less like a plan and more like shouting into a well.&lt;/p&gt;

&lt;p&gt;I know that quiet. On the last day of 2025 I left one of the largest cybersecurity software companies in the world, having owned reporting for the better part of a billion dollars in revenue, and woke up on January 1 with none of it. No title, no team, no dashboard to hide behind. Those first weeks felt less like a job search and more like re-learning who I was without a title in front of my name.&lt;/p&gt;

&lt;p&gt;What I want to write about is not the hard part. It is what I did with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The search itself felt broken
&lt;/h2&gt;

&lt;p&gt;The first thing I noticed, once I actually started applying, was how bad the tools were. Not the job boards. The part where you, one person, try to run a serious search across dozens of roles, keep track of who said what, remember to follow up, and learn anything at all from the whole exercise.&lt;/p&gt;

&lt;p&gt;That part is a spreadsheet and a prayer. And the spreadsheet loses.&lt;/p&gt;

&lt;p&gt;I have spent my career in revenue operations and analytics. Making messy, high-stakes processes legible is the actual job: take something people are running on instinct and memory, and give it stages, numbers, and a follow-up cadence so nothing important falls through. So it bothered me, more than it should have, that the most important process I had ever run for myself was the least organized.&lt;/p&gt;

&lt;h2&gt;
  
  
  I decided to build instead of just apply
&lt;/h2&gt;

&lt;p&gt;At some point the frustration turned into a question I could not put down: what would it look like to run my job search the way I would run a real pipeline?&lt;/p&gt;

&lt;p&gt;So I started building it. A way to score roles for fit so I spent my best effort where it counted. A way to track every application through real stages instead of a color-coded mess. A follow-up system that did not depend on me remembering. The tool I wished someone had handed me on day one.&lt;/p&gt;

&lt;p&gt;I called it &lt;a href="https://michaelinghilterra.com/Trajecktory" rel="noopener noreferrer"&gt;trajecktory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I will be honest about why this helped, because it is not only the obvious reason. Yes, it made the search more organized. But the bigger thing was this: building it gave me back the feedback loop I had lost. On the days when no recruiter wrote back, when the search gave me nothing, the work still gave me something. A problem to solve. A thing that was a little better at the end of the day than it was at the start. That mattered more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  What building it taught me that applying alone would not have
&lt;/h2&gt;

&lt;p&gt;A job search can make you feel like a candidate, a line in someone else's inbox, a yes or a no. Building something pushed back on that. It reminded me, daily, that I am a person who makes things, not just a person waiting to be chosen.&lt;/p&gt;

&lt;p&gt;It also turned out to be the best interview material I have. When someone asks what I have been working on, I do not have to reach for a careful non-answer. I built a tool, I open-sourced it, I use it every day, and I can walk you through exactly why I made the choices I made. That is a very different conversation than explaining a gap. It is a demonstration instead of an explanation.&lt;/p&gt;

&lt;p&gt;And there is a quieter lesson underneath all of it. The instinct that made me good at my work, taking something chaotic and giving it structure, was still there the whole time. The relaunch did not take it away. I just had to point it at my own situation for once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it stands
&lt;/h2&gt;

&lt;p&gt;trajecktory is open source and still evolving. So am I: still searching, still adding to it, still learning from what works and what does not. This is not written from the far side of the story with everything figured out. It comes from the middle, which is where most of us actually are.&lt;/p&gt;

&lt;p&gt;If you are in your own version of that quiet right now, here is the one thing I would pass along: find the piece of the problem where your instincts still work, and start there. It will not fix the market. It will not make the search short. But it will remind you who you are while you wait for the market to catch up, and some days that is the whole game.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If any of this resonates, I would genuinely like to hear from you. You can connect with me on &lt;a href="https://www.linkedin.com/in/michaelinghilterra" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, follow the build as it goes, or look at the code on &lt;a href="https://github.com/michaelinghilterra-creator/trajecktory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>buildinpublic</category>
      <category>jobsearch</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The invisible characters hiding in your AI-written text</title>
      <dc:creator>Michael Inghilterra</dc:creator>
      <pubDate>Sun, 16 Aug 2026 17:44:45 +0000</pubDate>
      <link>https://dev.to/michael_inghilterra/the-invisible-characters-hiding-in-your-ai-written-text-4kae</link>
      <guid>https://dev.to/michael_inghilterra/the-invisible-characters-hiding-in-your-ai-written-text-4kae</guid>
      <description>&lt;p&gt;You paste a paragraph from an AI chat into a job application. It looks clean. You submit it.&lt;/p&gt;

&lt;p&gt;What you cannot see is that a handful of characters came along for the ride: a zero-width space wedged between two words, a non-breaking space where a normal space should be, curly quotes instead of straight ones, and a dash that is technically a different character than the one on your keyboard. None of them show up on screen. All of them are really there.&lt;/p&gt;

&lt;p&gt;Most of the time this is harmless. Sometimes it quietly breaks things: a search that will not match, a copy-paste that renders a little box instead of a letter, a form that rejects your input for no reason you can see, or an applicant tracking system that parses your resume into nonsense. And lately it has a second life in the news, because those same invisible characters are showing up in conversations about AI watermarking and hidden text.&lt;/p&gt;

&lt;p&gt;I hit this problem enough while building my own job-search tool that I built a cleaner for it. Here is what is actually going on, and what I do about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part everyone should know
&lt;/h2&gt;

&lt;p&gt;Text on a computer is not just the letters you see. It is a stream of characters, and plenty of characters are designed to be invisible or nearly so. They exist for good reasons: to hold words together, to control spacing, to support languages that need them. The trouble starts when they get into your text without you knowing.&lt;/p&gt;

&lt;p&gt;A few common ways that happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Copy and paste.&lt;/strong&gt; Copying from a web page, a PDF, or a chat window often brings along formatting characters that were never meant to leave that page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart formatting.&lt;/strong&gt; Many tools "helpfully" turn straight quotes into curly ones and two hyphens into a long dash. Nice on a printed page. Not always welcome in a form field or a code box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI writing tools.&lt;/strong&gt; Text generated by an AI assistant tends to carry its own house style: certain spacing, certain punctuation, the occasional invisible spacer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why should a normal person care? Because the places where your words matter most are often the pickiest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Applicant tracking systems&lt;/strong&gt; read resumes as plain text. A stray invisible character can split a word, hide a keyword, or garble a line, and you never find out why you did not hear back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search and forms&lt;/strong&gt; match on exact characters. A curly quote is not the same character as a straight quote, so a search for your name or a title can silently miss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering.&lt;/strong&gt; Send text with an odd character into an app that does not support it and your reader sees a little box or a question mark where a letter should be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not exotic. It is the digital equivalent of showing up to an interview with a price tag still on your sleeve. Small, invisible to you, and worth removing before anyone else notices.&lt;/p&gt;

&lt;h2&gt;
  
  
  The news angle, and where I draw the line
&lt;/h2&gt;

&lt;p&gt;If you follow AI news at all, you have probably seen two related stories.&lt;/p&gt;

&lt;p&gt;One is &lt;strong&gt;watermarking&lt;/strong&gt;: the idea that AI-generated text can carry hidden signals, sometimes as invisible characters, so it can be identified later. The other is &lt;strong&gt;hidden text used to smuggle instructions&lt;/strong&gt;, where invisible characters are tucked into a document or a web page to quietly influence an AI system that reads it. Both are real, and both are worth understanding.&lt;/p&gt;

&lt;p&gt;I want to be clear about what this article is not. It is not a guide to defeating watermarks or dodging AI detectors. I think that is the wrong goal and, honestly, a losing game. My argument is simpler and older than any of this: &lt;strong&gt;you should be able to see everything that is in your own writing, and you should be able to ship it clean.&lt;/strong&gt; Clean text is portable, professional, and predictable. Whether an invisible character came from a chat tool, a copy-paste, or a watermark, the fix is the same, and the reason is the same. You are the author. You get to decide what is in the file.&lt;/p&gt;

&lt;p&gt;Stripping invisible characters does not defeat a real watermark either. What actually reads as machine-written is cadence, every sentence the same shape and length, and no character cleanup fixes that. This is about clean, honest text, not disguise.&lt;/p&gt;

&lt;p&gt;Call it text hygiene. Same spirit as spell-check, just for the characters you cannot see.&lt;/p&gt;




&lt;h2&gt;
  
  
  For the technically curious
&lt;/h2&gt;

&lt;p&gt;Everything above is the whole point for most readers. If you want the mechanics, here they are.&lt;/p&gt;

&lt;p&gt;The characters worth watching fall into a few buckets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-width characters.&lt;/strong&gt; Zero-width space (&lt;code&gt;U+200B&lt;/code&gt;), zero-width non-joiner (&lt;code&gt;U+200C&lt;/code&gt;), zero-width joiner (&lt;code&gt;U+200D&lt;/code&gt;), and the word joiner (&lt;code&gt;U+2060&lt;/code&gt;). These take up no visible space at all, which is exactly what makes them easy to miss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The byte order mark / zero-width no-break space&lt;/strong&gt; (&lt;code&gt;U+FEFF&lt;/code&gt;). Frequently hitchhikes at the start of copied text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-breaking and exotic spaces.&lt;/strong&gt; The non-breaking space (&lt;code&gt;U+00A0&lt;/code&gt;) is the common one. There is also a whole family of unusual spaces (thin, hair, figure, and so on) in the &lt;code&gt;U+2000&lt;/code&gt; to &lt;code&gt;U+200A&lt;/code&gt; range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart punctuation.&lt;/strong&gt; Curly single and double quotes (&lt;code&gt;U+2018&lt;/code&gt;, &lt;code&gt;U+2019&lt;/code&gt;, &lt;code&gt;U+201C&lt;/code&gt;, &lt;code&gt;U+201D&lt;/code&gt;), plus the en dash (&lt;code&gt;U+2013&lt;/code&gt;) and em dash (&lt;code&gt;U+2014&lt;/code&gt;) that autoformatters love to insert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag characters&lt;/strong&gt; (&lt;code&gt;U+E0000&lt;/code&gt; to &lt;code&gt;U+E007F&lt;/code&gt;). An obscure block that has become the vehicle for so-called ASCII smuggling, where readable-looking text hides an invisible payload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cleaning logic is not complicated in spirit: strip the characters that should never be in plain text, normalize the ones that have an obvious plain equivalent, and leave everything legitimate untouched. The library exposes a few tiers so you can match how aggressive the cleaning is to where the text is going. Install it with &lt;code&gt;npm install ai-text-hygiene&lt;/code&gt;, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stripInvisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanConservative&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ai-text-hygiene&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Full house-style clean for prose: strips invisibles, folds curly&lt;/span&gt;
&lt;span class="c1"&gt;// quotes to straight, em dash to a comma, ellipsis to three dots.&lt;/span&gt;
&lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;We "delivered" results — on time…&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; 'We "delivered" results, on time...'&lt;/span&gt;

&lt;span class="c1"&gt;// Strip-only tier, safe for any language (no punctuation changes).&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;zwsp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x200B&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// a zero-width space, invisible in input&lt;/span&gt;
&lt;span class="nf"&gt;stripInvisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;zwsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; 'invisible'&lt;/span&gt;

&lt;span class="c1"&gt;// Length-stable tier for capped fields: 1:1 swaps, no growth.&lt;/span&gt;
&lt;span class="nf"&gt;cleanConservative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;curly "quotes" to straight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important design choice is what you do &lt;em&gt;not&lt;/em&gt; strip. Normalizing is a judgment call: turning a curly quote into a straight one is safe and almost always what you want in a form field, but you would not want to flatten legitimate content in a language that depends on characters an overeager filter might catch. That is why the strip-only tier is the one that is safe for any language, while the full clean targets English house style. The real work is in choosing the right set to remove versus the right set to normalize, and in doing it predictably every time.&lt;/p&gt;

&lt;p&gt;In my project this lives in a single module (&lt;code&gt;text-hygiene-core&lt;/code&gt;) so the same rules apply everywhere text leaves the app, and it is published on its own as an open-source library under the MIT license. If you want to read the actual code or drop it into your own tools, the repo is here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/michaelinghilterra-creator/ai-text-hygiene" rel="noopener noreferrer"&gt;ai-text-hygiene on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;I did not set out to write a Unicode cleaner. I built &lt;a href="https://michaelinghilterra.com/Trajecktory" rel="noopener noreferrer"&gt;trajecktory&lt;/a&gt;, a tool to run my own job search like a pipeline, and text hygiene turned out to be one of those small, unglamorous problems that quietly matters. Every resume, every cover letter, every message that leaves the app should be clean, plain, and exactly what I wrote. Nothing hidden, nothing I cannot see.&lt;/p&gt;

&lt;p&gt;If you have ever wondered why a form rejected text that looked perfectly fine, this is often the reason. Now you can see it, and clean it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;trajecktory is open source and still evolving. If this was useful, the code is on &lt;a href="https://github.com/michaelinghilterra-creator/trajecktory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and I write about building it as I go.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>writing</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
