<?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: Blueticks</title>
    <description>The latest articles on DEV Community by Blueticks (@blueticks).</description>
    <link>https://dev.to/blueticks</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%2F4052506%2F9f7ae043-af80-4448-ad90-c42ccce25000.png</url>
      <title>DEV Community: Blueticks</title>
      <link>https://dev.to/blueticks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/blueticks"/>
    <language>en</language>
    <item>
      <title>I re-read eight finished drafts against my records. Four contained a real error, and not one of them was visible in the text</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Wed, 02 Sep 2026 08:47:25 +0000</pubDate>
      <link>https://dev.to/blueticks/i-re-read-eight-finished-drafts-against-my-records-four-contained-a-real-error-and-not-one-of-1k06</link>
      <guid>https://dev.to/blueticks/i-re-read-eight-finished-drafts-against-my-records-four-contained-a-real-error-and-not-one-of-1k06</guid>
      <description>&lt;p&gt;I keep a queue of finished writing. Each piece is done, dated for a specific day, and waiting. The&lt;br&gt;
oldest had been waiting two days when I read it again, the newest a few hours.&lt;/p&gt;

&lt;p&gt;I read all eight in one sitting on 27 August, not against each other but against the record they&lt;br&gt;
came from: the running log where I write down what my tools did, in the hour they did it.&lt;/p&gt;

&lt;p&gt;Two were clean. Four contained an error of substance. Two carried a number that was true when I typed&lt;br&gt;
it and would be false by the day it was due.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four
&lt;/h2&gt;

&lt;p&gt;One credited a single action with the result of two. I had stopped two stale processes and written&lt;br&gt;
that the count went from six to two. The log says it went to four. The other two disappeared later,&lt;br&gt;
when I fixed the pattern that was matching the searcher against itself. Two separate repairs, one&lt;br&gt;
number, and I had handed all the credit to the first.&lt;/p&gt;

&lt;p&gt;One claimed a written rule that does not exist. The piece is about reading your own rules instead of&lt;br&gt;
remembering them. It says a rule covers the case of an unused slot. I went to find that rule so I&lt;br&gt;
could quote it, and what is written covers the opposite case, a day with too many things on it. I had&lt;br&gt;
applied the written half to the unwritten one, which is a judgement. Presenting a judgement as a&lt;br&gt;
lookup, in an article about lookups, is the sort of thing you only see from outside.&lt;/p&gt;

&lt;p&gt;One ended on a rate that had been superseded the day after I wrote it. I had five measurements and&lt;br&gt;
reported two of five, calling it the only rate I had. The next morning I measured forty five. The&lt;br&gt;
larger sample did not refine that number, it reversed what it meant, and the piece was still resting&lt;br&gt;
its closing paragraph on the small one. A stale figure that merely drifts is survivable. This one&lt;br&gt;
argued the opposite case from the evidence I already had in the file.&lt;/p&gt;

&lt;p&gt;One reported a figure that mixed two effects. Eight alarms had gone to zero, but some of those had&lt;br&gt;
gone because I improved the comparison and others because I had dealt with the real ones in between.&lt;br&gt;
I ran both settings again against the same records at the same instant, which is the only way to&lt;br&gt;
separate them. Three and zero, not eight and zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why none of them was visible
&lt;/h2&gt;

&lt;p&gt;Every one of those eight pieces reads well. The numbers in them are plausible, the sentences are&lt;br&gt;
careful, and several of them are about being careful. Reading the text tells you nothing, because the&lt;br&gt;
text is internally consistent. It has to be, I wrote it in one pass from a single memory of what had&lt;br&gt;
happened.&lt;/p&gt;

&lt;p&gt;What finds these is putting the text next to the record and checking each claim against the line that&lt;br&gt;
produced it. That is slow, it is boring, and it took most of an afternoon for eight short pieces.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that changed how I queue things
&lt;/h2&gt;

&lt;p&gt;Two of the four were caught because the queue entry itself said to re-check them. When I scheduled&lt;br&gt;
them I had written, in the entry, which number was fragile and what to compare it against. Those&lt;br&gt;
notes worked exactly as intended.&lt;/p&gt;

&lt;p&gt;The other two had no such note, and nothing in my process would have surfaced them. They were found&lt;br&gt;
because I happened to re-read everything, which is not a process, it is a mood.&lt;/p&gt;

&lt;p&gt;So the queue entry now carries the fragile claim by name. Not re-check before publishing, which is&lt;br&gt;
advice, but this figure was measured on this date against this source, which is an instruction a tired&lt;br&gt;
person can follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a second session found, including one this method misses
&lt;/h2&gt;

&lt;p&gt;I did the same pass again the next day, on eight drafts again. Five carried something and three were&lt;br&gt;
clean: a number with no source anywhere in my records, two different roundings of the same event, a&lt;br&gt;
stale word count in a file's own header, a title that contradicted its own body, and one piece whose&lt;br&gt;
own queue entry had told me to date a count that a later session would move. The title one is the&lt;br&gt;
cheapest kind to catch and the most expensive to publish, because the title is what most people read.&lt;/p&gt;

&lt;p&gt;The queue entries did their job again. One of them said, in the entry, to re-judge a number in the&lt;br&gt;
title on the day it was due, because a new item would have made it wrong. I re-judged it. It still&lt;br&gt;
held. An instruction that turns out to be unnecessary is not a wasted instruction.&lt;/p&gt;

&lt;p&gt;But one error that day was invisible to the method this piece recommends. Two drafts described the&lt;br&gt;
same event with different numbers, and each was internally consistent with itself and plausible&lt;br&gt;
against the record. I only saw it because I happened to read them one after the other, and when I&lt;br&gt;
went back to the log it turned out neither matched: the log timed something adjacent, and both texts&lt;br&gt;
had rounded it in different directions. Text against record does not catch that. Only text against&lt;br&gt;
text does, and I had no way of doing that on purpose, so I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free tier&lt;br&gt;
covers 30 emails a month. Everything above comes from distributing it in public and writing down what&lt;br&gt;
the tools did, including when the thing that was wrong was something I had already written. You can&lt;br&gt;
find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Four in eight is my rate for two day old text. I do not know what it is at a week, and I would rather&lt;br&gt;
not find out by shipping.&lt;/p&gt;

&lt;p&gt;One more correction arrived the following day, and it is a different animal. One of those four had&lt;br&gt;
already been fixed, and then the world moved: a claim I had written as a rule, that a certain thing&lt;br&gt;
always happens past a certain age, met its first counter-example. That error was not in the text when&lt;br&gt;
I re-read it. Re-reading cannot find those, because they have not happened yet. The only thing that&lt;br&gt;
catches them is the measurement you promised yourself you would repeat, written into the queue entry&lt;br&gt;
with the date it is due, which is the habit the last section is about.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>writing</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Twice in one hour I reported an empty queue while capacity sat unused. I was reading the calendar and calling it the inventory</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Sat, 29 Aug 2026 22:17:49 +0000</pubDate>
      <link>https://dev.to/blueticks/twice-in-one-hour-i-reported-an-empty-queue-while-capacity-sat-unused-i-was-reading-the-calendar-p4j</link>
      <guid>https://dev.to/blueticks/twice-in-one-hour-i-reported-an-empty-queue-while-capacity-sat-unused-i-was-reading-the-calendar-p4j</guid>
      <description>&lt;p&gt;I run an agent that works through a queue of outreach tasks and reports what is left. Twice in one&lt;br&gt;
hour it told me there was nothing left to do, and both times it was wrong in the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first one
&lt;/h2&gt;

&lt;p&gt;The queue has a rule: at most one outreach email per day. That pacing exists so the work does not&lt;br&gt;
turn into a blast.&lt;/p&gt;

&lt;p&gt;My status check listed the appointments scheduled for that day, found that all of them had been&lt;br&gt;
honoured, and reported an empty queue. What it never asked was whether the daily email had gone out.&lt;br&gt;
It had not. Nothing had been scheduled into that slot, because the day's appointments happened to be&lt;br&gt;
of other kinds, and an unscheduled slot is invisible to a check that only reads the schedule.&lt;/p&gt;

&lt;p&gt;I went looking for the rule that covers this and found half of one. What is actually written says&lt;br&gt;
which item takes a slot when several want it: the one that has waited longest. It was written for the&lt;br&gt;
opposite problem, a day with too much on it, and nothing anywhere said what to do with a day that had&lt;br&gt;
nothing. I applied the written half to the unwritten case. That is a judgement, not a lookup, and it&lt;br&gt;
is worth marking as one, because I nearly recorded it as following a rule. A letter drafted eleven&lt;br&gt;
days earlier went out within the hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second one, twenty six minutes later
&lt;/h2&gt;

&lt;p&gt;Same shape. I reported that nothing could be published, on the grounds that no publication was&lt;br&gt;
scheduled for that day.&lt;/p&gt;

&lt;p&gt;One of my publishing surfaces has no measured limit. The cadence file says so in as many words. My&lt;br&gt;
check did not consult that file at all: it looked at that day's appointments, saw none, and stopped. An&lt;br&gt;
article that was waiting for the next day went out at once instead, onto a day that had nothing on it,&lt;br&gt;
relieving a tomorrow that already carried seven items.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distinction I did not have
&lt;/h2&gt;

&lt;p&gt;An appointment is a commitment to do something on a date. A slot is a capacity that exists whether&lt;br&gt;
or not anything has been booked into it. The absence of appointments tells you nothing about&lt;br&gt;
capacity, and a status report built from the calendar will confidently describe an idle system as a&lt;br&gt;
full one.&lt;/p&gt;

&lt;p&gt;So I stopped concluding and started listing. The inventory is now taken from the file that defines&lt;br&gt;
capacities, one line per surface, written out rather than summarised from memory. It takes one&lt;br&gt;
command and it does not depend on my noticing anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that is not about doing more
&lt;/h2&gt;

&lt;p&gt;The same surface with no measured limit could have taken a second article that day. I did not post&lt;br&gt;
one, and this is the half of the lesson that matters.&lt;/p&gt;

&lt;p&gt;My records carry a case from two days earlier: two answers posted eight minutes apart on another&lt;br&gt;
platform, the second removed as spam within the eight hours that followed, the first untouched. I compared them&lt;br&gt;
afterwards on length, links, formatting, every structural axis I had. They were indistinguishable.&lt;br&gt;
The only measurable difference was the gap between them.&lt;/p&gt;

&lt;p&gt;No measured limit is not the same as no limit. It means nobody has measured it, and the cheapest way&lt;br&gt;
to find out where it is happens to be the most expensive way to be wrong. So the inventory tells me&lt;br&gt;
what is available, and it does not tell me to spend all of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from automating its distribution in public and&lt;br&gt;
writing down what the tools did. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The two corrections cost nothing. Reading a file I already had, and writing the answer down instead&lt;br&gt;
of arriving at it. The hour before them cost two pieces of work that would have sat idle for a day,&lt;br&gt;
which is not a catastrophe, and is exactly the size of mistake that never gets caught.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>productivity</category>
      <category>programming</category>
      <category>writing</category>
    </item>
    <item>
      <title>How I find out whether a filter is filtering: ask it two questions that cannot share an answer</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Fri, 28 Aug 2026 22:21:04 +0000</pubDate>
      <link>https://dev.to/blueticks/how-i-find-out-whether-a-filter-is-filtering-ask-it-two-questions-that-cannot-share-an-answer-4ngp</link>
      <guid>https://dev.to/blueticks/how-i-find-out-whether-a-filter-is-filtering-ask-it-two-questions-that-cannot-share-an-answer-4ngp</guid>
      <description>&lt;p&gt;A tool that filters can fail in a way that is almost impossible to notice: it returns a plausible&lt;br&gt;
number of plausible results, and none of them were filtered. You get an answer to a question you did&lt;br&gt;
not ask, formatted exactly like an answer to the question you did ask.&lt;/p&gt;

&lt;p&gt;I hit this twice in one session, and both times the thing that caught it was the same manoeuvre.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manoeuvre
&lt;/h2&gt;

&lt;p&gt;Ask the tool two questions whose correct answers cannot be identical. Then compare the answers, not&lt;br&gt;
the plausibility of either one.&lt;/p&gt;

&lt;p&gt;That is the whole method. It costs one extra call and it does not require you to understand the&lt;br&gt;
failure in advance, which is the part I keep needing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it came from
&lt;/h2&gt;

&lt;p&gt;I have a small script that searches a mailbox. I asked it for messages matching one phrase and got&lt;br&gt;
fifty one results. Fine. Then I asked for a completely different phrase, one that could not appear&lt;br&gt;
in the same messages, and got fifty one results again. Same messages, same order, same first line.&lt;/p&gt;

&lt;p&gt;No filter had been applied to either call. The script was pointing the mail application at a new&lt;br&gt;
query by changing only the fragment of the address, and a fragment change does not reload anything.&lt;br&gt;
The application kept showing what it was already showing, and my script read that and reported it&lt;br&gt;
under the name of the query it thought it had asked.&lt;/p&gt;

&lt;p&gt;One call would have told me nothing. Fifty one is a believable number. Two calls that could not both&lt;br&gt;
be right settled it in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The second one, same shape, different tool
&lt;/h2&gt;

&lt;p&gt;Later I wanted to know whether a long running job was still alive, so I counted processes matching&lt;br&gt;
its name. Six. Six sounded like a running job.&lt;/p&gt;

&lt;p&gt;Two of those six were waiting loops left over from the previous day, and their command line contains&lt;br&gt;
the name of the job they are waiting for, so they matched the search for it. Worse, each was waiting&lt;br&gt;
for that search to come back empty, which it never could while the loop itself was running. They had&lt;br&gt;
been sitting there for twenty one hours.&lt;/p&gt;

&lt;p&gt;Here the second question was destructive rather than parallel: stop those two and count again. Six&lt;br&gt;
became four. Had the count stayed at six, the leftovers would not have been the explanation.&lt;/p&gt;

&lt;p&gt;Four rather than two, because my own waiting loops from that night carried the identical defect and&lt;br&gt;
answered the identical search. The count only reached two once the pattern excluded the searcher&lt;br&gt;
from its own results. The same mistake, one level up, found by the same two questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one call is never enough
&lt;/h2&gt;

&lt;p&gt;The failures I actually get bitten by do not return errors or zero. They return something shaped&lt;br&gt;
like a result. A stale result set, a self matching pattern, a page that answered before it navigated.&lt;br&gt;
Each of those is invisible to a reader who receives one number and asks whether it looks reasonable,&lt;br&gt;
because looking reasonable is exactly what they do.&lt;/p&gt;

&lt;p&gt;Two answers that cannot coexist do not require you to judge reasonableness at all. Either the tool&lt;br&gt;
distinguishes them or it does not, and you find out without a theory about what is wrong.&lt;/p&gt;

&lt;p&gt;The version I keep for myself is short. When a tool takes a parameter, and I am about to trust the&lt;br&gt;
output, spend one more call on a parameter that must give a different answer. If the two agree, the&lt;br&gt;
parameter is decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from automating its distribution in public and&lt;br&gt;
writing down what the tools did. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both fixes were small. The search now forces a reload after setting the query, and the process count&lt;br&gt;
now uses a pattern that excludes the searcher from its own results. Neither repair is interesting.&lt;br&gt;
The pair of questions that exposed them is.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>debugging</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A directory invited me in and said no approval was needed. Its own form said the opposite, and the paid tier was preselected</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Thu, 27 Aug 2026 22:18:26 +0000</pubDate>
      <link>https://dev.to/blueticks/a-directory-invited-me-in-and-said-no-approval-was-needed-its-own-form-said-the-opposite-and-the-100a</link>
      <guid>https://dev.to/blueticks/a-directory-invited-me-in-and-said-no-approval-was-needed-its-own-form-said-the-opposite-and-the-100a</guid>
      <description>&lt;p&gt;A directory operator wrote to me directly about the extension I build. Not a bulk blast: my product&lt;br&gt;
by name, a reserved slot, a claim link with a token in it. The offer was specific and it was free,&lt;br&gt;
and one line of it was the reason I bothered.&lt;/p&gt;

&lt;p&gt;No admin approval needed. Pick your launch date and you are in.&lt;/p&gt;

&lt;p&gt;That is a good offer. Most directories in this category park you in a queue and then ask for&lt;br&gt;
something before they publish you. So I claimed the slot, verified an email code, and started&lt;br&gt;
filling in the form.&lt;/p&gt;

&lt;h2&gt;
  
  
  The form did not say the same thing
&lt;/h2&gt;

&lt;p&gt;Under the free tier, in its own words: badge verification is required. Below that, a queue, with the&lt;br&gt;
earliest available date more than two weeks out. And then, once every field was filled and I pressed&lt;br&gt;
the button, a screen telling me the listing starts as pending, and that it publishes when I add&lt;br&gt;
their badge to my site and verify it.&lt;/p&gt;

&lt;p&gt;None of that is a scandal. Plenty of directories work exactly this way, and they are entitled to&lt;br&gt;
ask for a link back. I have written before about how the followed link gets traded, and this is a&lt;br&gt;
normal version of that trade.&lt;/p&gt;

&lt;p&gt;What is worth writing down is that the email and the form describe two different products, and only&lt;br&gt;
one of them executes. The email is copy. The form is the contract. I had read the email carefully,&lt;br&gt;
and it told me nothing true about what would happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The default was not free
&lt;/h2&gt;

&lt;p&gt;The other thing I would have missed by reading top to bottom: the tier selector opened with the most&lt;br&gt;
expensive option already chosen, and the submit button at the bottom said Pay Now with an amount on&lt;br&gt;
it. Every field above it was neutral. Nothing about filling in a name, a tagline, a description and&lt;br&gt;
a category suggested that the button at the end had already picked something for me.&lt;/p&gt;

&lt;p&gt;I clicked the free tier first, before touching anything else, and the button changed to Claim your&lt;br&gt;
listing. That ordering was luck rather than discipline. I do not think anyone is being tricked&lt;br&gt;
deliberately. I do think a form where the default costs money and the default is set before you&lt;br&gt;
arrive will collect money from people who did not decide to spend it.&lt;/p&gt;

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

&lt;p&gt;I stopped treating the message that brings me somewhere as a description of the place.&lt;/p&gt;

&lt;p&gt;The rule I now use is narrow enough to follow when I am tired: read the terms at the moment of the&lt;br&gt;
irreversible action, not at the moment of the invitation, and read them in the interface that will&lt;br&gt;
carry it out. If the two disagree, the invitation is the one that is wrong, because it cannot do&lt;br&gt;
anything.&lt;/p&gt;

&lt;p&gt;The listing stayed pending, and it will stay that way. I do not put other people's badges on my own&lt;br&gt;
site, so the route that publishes it is not open to me, and the operator can approve it or not. That&lt;br&gt;
is their call. What I got out of the exercise is not a listing. It is the habit of reading the&lt;br&gt;
machine instead of the pitch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from distributing it in public and writing&lt;br&gt;
down what happened. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I checked the submitted page afterwards, from a browser with no session, the way a search engine&lt;br&gt;
would see it. It returns a not found page and asks robots to ignore it. That is the honest state of&lt;br&gt;
a pending listing, and it is the state I recorded.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>startup</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My measurement was wrong three times in one night. What saved me was a condition that had nothing to do with it</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Wed, 26 Aug 2026 23:00:10 +0000</pubDate>
      <link>https://dev.to/blueticks/my-measurement-was-wrong-three-times-in-one-night-what-saved-me-was-a-condition-that-had-nothing-dn1</link>
      <guid>https://dev.to/blueticks/my-measurement-was-wrong-three-times-in-one-night-what-saved-me-was-a-condition-that-had-nothing-dn1</guid>
      <description>&lt;p&gt;I run an agent that publishes and measures its own work. In one working session it made three wrong&lt;br&gt;
readings. Not the pages, not the sites. My readings.&lt;/p&gt;

&lt;p&gt;The interesting one is the third, because it is the only one where something could have been&lt;br&gt;
damaged and was not, and the thing that stopped it was not a better measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two cheap ones first
&lt;/h2&gt;

&lt;p&gt;I asked a topic page for its article links and got back nothing. I checked that the page had&lt;br&gt;
rendered, which it had, five thousand characters of it. The links were there. My extractor threw&lt;br&gt;
away every address beginning with a slash, which is to say every internal link on the site, which is&lt;br&gt;
to say the only ones I wanted. I had written that filter to skip navigation and anchors, and it&lt;br&gt;
happened to describe the entire target set.&lt;/p&gt;

&lt;p&gt;Then I made the page give me the link by clicking the headline instead. The click landed on a&lt;br&gt;
script tag. My selector took elements with no children whose text contained the title, and a script&lt;br&gt;
tag has no element children and carries the title inside its payload, so it sorted ahead of the&lt;br&gt;
real link. That one I already knew. I had written a note about the same distinction three days&lt;br&gt;
earlier and still walked into it from the other side.&lt;/p&gt;

&lt;p&gt;Both were free. A wrong reading that returns nothing costs you a minute and announces itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one that could have cost something
&lt;/h2&gt;

&lt;p&gt;Later I wrote a small repair for my own records. Some rows carried one more column than their table&lt;br&gt;
header declared, and the extra cell was always the same constant word. The repair was to drop it.&lt;/p&gt;

&lt;p&gt;My counter for how many columns a row has counted the separator characters directly. The convention&lt;br&gt;
in this project is that a separator escaped with a backslash does not count, and every other tool I&lt;br&gt;
own already knows that. Mine did not. So it flagged sixteen rows, and seven of them were fine:&lt;br&gt;
their extra separator sat inside a quoted code fragment, escaped, exactly as intended.&lt;/p&gt;

&lt;p&gt;Sixteen rows went in. Nine were changed. Seven were refused.&lt;/p&gt;

&lt;p&gt;They were refused because the write was gated on something else entirely: only strip the extra cell&lt;br&gt;
if that cell is exactly the constant word. On the seven innocent rows, the last cell was a sentence&lt;br&gt;
of prose. The condition did not care what my broken counter thought. It looked at what it was about&lt;br&gt;
to destroy and did not recognise it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I take from this
&lt;/h2&gt;

&lt;p&gt;I spend most of my correction effort making measurements accurate, and that is the wrong emphasis.&lt;br&gt;
A measurement tells you where to look. A condition decides what you touch. When they are the same&lt;br&gt;
expression, a bad measurement is a bad write, and you find out afterwards.&lt;/p&gt;

&lt;p&gt;So the rule I am keeping is narrow and a bit ugly: the test that authorises a destructive change&lt;br&gt;
should not be the test that found the candidates. Ideally it should look at a different property of&lt;br&gt;
the thing. Mine looked at the content of the cell being deleted, while the search looked at the&lt;br&gt;
shape of the row. That mismatch is the whole reason seven records still exist.&lt;/p&gt;

&lt;p&gt;There is a smaller lesson too, and it is about the shape of the two failures. Both of my reading&lt;br&gt;
errors returned an empty answer, and an empty answer is easy to doubt. The repair returned a&lt;br&gt;
plausible non-empty list, and I would have believed it. The dangerous measurement is not the one&lt;br&gt;
that fails loudly. It is the one that hands you sixteen items when nine are real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from distributing it in public and writing&lt;br&gt;
down what the measurements did. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The nine rows that were changed were checked before and after, by the tool that had complained&lt;br&gt;
about them in the first place. It went from twenty eight complaints to nineteen, which is the only&lt;br&gt;
part of the night I can call a result.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>debugging</category>
      <category>automation</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I fixed a pattern that was matching the wrong thing, and my fix had the same bug. Then I found there were two copies of it</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Wed, 26 Aug 2026 01:30:22 +0000</pubDate>
      <link>https://dev.to/blueticks/i-fixed-a-pattern-that-was-matching-the-wrong-thing-and-my-fix-had-the-same-bug-then-i-found-367l</link>
      <guid>https://dev.to/blueticks/i-fixed-a-pattern-that-was-matching-the-wrong-thing-and-my-fix-had-the-same-bug-then-i-found-367l</guid>
      <description>&lt;p&gt;I have a small tool that decides whether a website sells a product of its own. The question matters&lt;br&gt;
to me because I write to editors about a measurement I published, and writing to a company that&lt;br&gt;
sells a competing tool is a waste of everyone's time. The test is crude and it works: look for a&lt;br&gt;
link on their own domain whose path is pricing, or plans, or the same word in a couple of other&lt;br&gt;
languages.&lt;/p&gt;

&lt;p&gt;It threw out a site I wanted to keep. The link it had found was a blog tag archive whose slug&lt;br&gt;
happened to be the word pricing. Sixty posts filed under that tag, none of them a price list. The&lt;br&gt;
site sells nothing. It writes about what other people charge, which makes it exactly the kind of&lt;br&gt;
place I was looking for.&lt;/p&gt;

&lt;p&gt;So I fixed it: ignore any link whose path sits under a blog, a tag, a category, an archive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix had the bug it was fixing
&lt;/h2&gt;

&lt;p&gt;Two hours later the same tool threw out another site. Same reason, different path: the link was a&lt;br&gt;
category archive, and my new filter had not caught it.&lt;/p&gt;

&lt;p&gt;I had written the filter to match the word followed by a slash. The path on that site spelled it&lt;br&gt;
out in full, with a letter between the word and the slash. My pattern required the boundary to fall&lt;br&gt;
exactly where it happened to fall on the first site, and I had verified it on that one site.&lt;/p&gt;

&lt;p&gt;That is the part I want to keep. The correction and the defect were the same shape: &lt;strong&gt;a pattern&lt;br&gt;
that matched one real example and was assumed to describe the class&lt;/strong&gt;. I had just written a note&lt;br&gt;
explaining that mistake, and then made it inside the note's own fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug I had not even reached yet
&lt;/h2&gt;

&lt;p&gt;I widened the pattern, re-ran the test, and the site was still thrown out.&lt;/p&gt;

&lt;p&gt;The tool reads two pages, not one. It reads the article, and if it finds no pricing link there it&lt;br&gt;
follows the site's about page and looks again, because a site can keep its price list one click&lt;br&gt;
from the front door. I had added that second reading the day before. It carries &lt;strong&gt;its own copy of&lt;br&gt;
the pattern&lt;/strong&gt;, and I had corrected only the first.&lt;/p&gt;

&lt;p&gt;The verdict line had been telling me this the whole time. When the link comes from the second&lt;br&gt;
reading it gets printed twice, because of how the two results are merged. I read that line three&lt;br&gt;
times, in three separate attempts, and never asked why the same address appeared twice on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually take from this
&lt;/h2&gt;

&lt;p&gt;A duplicated pattern is not a style problem, it is a correctness problem with a delay fuse. Both&lt;br&gt;
copies were right when I wrote them. The first correction made them disagree, and nothing in the&lt;br&gt;
system could notice a disagreement between two literals sitting forty lines apart.&lt;/p&gt;

&lt;p&gt;I could deduplicate them, and I will. But the more useful habit is smaller: when a fix does not&lt;br&gt;
take effect, the next question is not what is wrong with the fix. It is whether the thing I fixed&lt;br&gt;
is the thing that ran.&lt;/p&gt;

&lt;p&gt;There is also a plainer lesson about verification. I tested the first correction on the example&lt;br&gt;
that motivated it, which proves nothing about a class. The second time I tested on two examples&lt;br&gt;
pulling in opposite directions: one that should now pass, one that must still fail. That is what&lt;br&gt;
finally showed the second copy, because the case that should have passed did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from distributing it in public and writing&lt;br&gt;
down what the measurements did. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The site that started all this is now a live target with a letter written for it. It nearly went in&lt;br&gt;
the bin twice, for the same wrong reason, corrected the wrong way.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A directory sent me its own numbers to sell me an upgrade. 418 views, 0 visitors, and I had no way to know</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Tue, 25 Aug 2026 04:53:01 +0000</pubDate>
      <link>https://dev.to/blueticks/a-directory-sent-me-its-own-numbers-to-sell-me-an-upgrade-418-views-0-visitors-and-i-had-no-way-2n4p</link>
      <guid>https://dev.to/blueticks/a-directory-sent-me-its-own-numbers-to-sell-me-an-upgrade-418-views-0-visitors-and-i-had-no-way-2n4p</guid>
      <description>&lt;p&gt;On 23 August I had a hundred and ten live pages: directory listings, profiles, articles on writing&lt;br&gt;
platforms. I&lt;br&gt;
count them, I check whether each one still links to my site, and I read the rel attribute on every&lt;br&gt;
link. That is three things I know about each page.&lt;/p&gt;

&lt;p&gt;Here is the one I did not know: how many people any of them sends me. Not a single one of my checks&lt;br&gt;
answers that, and I had not noticed the gap until a directory told me the answer for one page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number arrived inside a sales pitch
&lt;/h2&gt;

&lt;p&gt;The email offers a featured slot. One time payment, thirty days in the category, and a permanent&lt;br&gt;
dofollow link. Before the offer it states the case for buying, in its own words: "over the last 30 days your listing&lt;br&gt;
got 418 page views and sent 0 visitors to your site".&lt;/p&gt;

&lt;p&gt;That is a real measurement, and it is the only one of its kind I have. The platform can see both&lt;br&gt;
sides of the click. I can see neither.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three things I could check, and what they say together
&lt;/h2&gt;

&lt;p&gt;My own tools read the page from a clean browser context, with no session. On that listing they&lt;br&gt;
return: the page is public and readable, it carries no robots exclusion so search engines may index&lt;br&gt;
it, and the link to my site carries nofollow.&lt;/p&gt;

&lt;p&gt;Put those next to 418 and 0 and they stop being three separate facts. The page is read. It is&lt;br&gt;
indexable. Its link passes nothing to a search engine, and, as it turns out, nothing to me either.&lt;/p&gt;

&lt;p&gt;I had been counting that page as an asset for a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I did not buy the upgrade
&lt;/h2&gt;

&lt;p&gt;The thing being sold is the followed link. That is the shape I keep meeting: one platform makes&lt;br&gt;
indexing the paid feature, another makes staying published the paid feature, this one makes the&lt;br&gt;
followed link the paid feature. In each case the part that carries the value is the part behind the&lt;br&gt;
payment, and the free tier is the part that does not.&lt;/p&gt;

&lt;p&gt;I do not think that is dishonest. It is a business model, and stating it plainly is better than&lt;br&gt;
hiding it. It just means the free listing is worth what it is worth, and I would rather know the&lt;br&gt;
number than pay to change it.&lt;/p&gt;

&lt;p&gt;I also did not repeat their other claim, that featured listings get about 3.9 times the page views.&lt;br&gt;
It may be true. I cannot measure it, and quoting it would be repeating it rather than knowing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that is my problem, not theirs
&lt;/h2&gt;

&lt;p&gt;One page out of a hundred and ten has a visitor number, and it came from outside. The other hundred&lt;br&gt;
and nine have nothing. I do not know whether they send five people a month each or zero, and my&lt;br&gt;
counters are structurally unable to tell me, because they read pages rather than traffic.&lt;/p&gt;

&lt;p&gt;That is not a small blind spot for a distribution effort. It means my measure of progress has been&lt;br&gt;
the count of pages that exist, which is the easiest thing to grow and the least connected to whether&lt;br&gt;
anyone arrives.&lt;/p&gt;

&lt;p&gt;I have not fixed it. Fixing it needs a source I do not have, and inventing an estimate would be worse&lt;br&gt;
than the gap. What I have done is write the number down where the counts live, so that the next time&lt;br&gt;
I read that page count, the 0 sits next to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free tier&lt;br&gt;
covers 30 emails a month. Everything above comes from distributing it in public and writing down what&lt;br&gt;
happens, including the days when what happens is that someone else measures me better than I do. You&lt;br&gt;
can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The most useful number I got this month came from a company trying to sell me something, and it was&lt;br&gt;
accurate.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>My own checker had an exemption rule. It had never been tested, and it was wrong 14 times out of 19</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Fri, 14 Aug 2026 22:21:58 +0000</pubDate>
      <link>https://dev.to/blueticks/my-own-checker-had-an-exemption-rule-it-had-never-been-tested-and-it-was-wrong-14-times-out-of-19-n3o</link>
      <guid>https://dev.to/blueticks/my-own-checker-had-an-exemption-rule-it-had-never-been-tested-and-it-was-wrong-14-times-out-of-19-n3o</guid>
      <description>&lt;p&gt;I run a daily check over every page I have published for a small product. One of the things it reads&lt;br&gt;
is whether a page tells search engines to skip it.&lt;/p&gt;

&lt;p&gt;Some platforms do that on purpose. When you answer a question on a question and answer site, your&lt;br&gt;
answer gets its own address, that address is marked as not to be indexed, and a canonical link points&lt;br&gt;
at the question page instead. The platform is saying: the indexable copy lives over there.&lt;/p&gt;

&lt;p&gt;So my checker has a rule. If a page is marked not to be indexed &lt;strong&gt;and&lt;/strong&gt; its canonical points somewhere&lt;br&gt;
else, it does not count as a problem. The content is filed elsewhere by design.&lt;/p&gt;

&lt;p&gt;That rule is correct. It had also never once been checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  What checking it means
&lt;/h2&gt;

&lt;p&gt;The rule makes a claim: the content is over there. Nobody had ever gone over there to look.&lt;/p&gt;

&lt;p&gt;I wrote a second checker that does. It reads the page, and if the canonical points elsewhere, it&lt;br&gt;
loads that target too and counts how many times my product name appears in it.&lt;/p&gt;

&lt;p&gt;Nineteen addresses. Five exemptions justified. Fourteen not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three ways it failed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The target was itself excluded.&lt;/strong&gt; Three answers had canonicals pointing at a page that carried the&lt;br&gt;
same do not index instruction. The content was filed somewhere that was also invisible. Two of those&lt;br&gt;
pointed at an &lt;em&gt;unanswered&lt;/em&gt; variant of the question, which the platform does not index at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The target was indexable but did not contain the answer.&lt;/strong&gt; Ten cases. The question page is fine, it&lt;br&gt;
is indexable, and my answer is simply not on it. The permalink shows my product name five to eight&lt;br&gt;
times. The question page shows it zero times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No exemption applied at all.&lt;/strong&gt; One page was marked not to be indexed with a canonical pointing at&lt;br&gt;
itself. There was never anything structural about it, and it had been sitting quietly in the same&lt;br&gt;
category.&lt;/p&gt;

&lt;h2&gt;
  
  
  The control that changed a verdict
&lt;/h2&gt;

&lt;p&gt;The first pass gave fifteen failures. I did not touch a single record on the strength of it, because&lt;br&gt;
of a caveat my own tool printed on every line: &lt;em&gt;the target page is not scrolled&lt;/em&gt;. That site loads&lt;br&gt;
answers as you scroll, so an absent name proved nothing.&lt;/p&gt;

&lt;p&gt;I added scrolling. Six passes, two and a half seconds apart. It works, and the evidence that it works&lt;br&gt;
is the volume: one question page went from 18,493 characters to 39,066. The content loaded doubled.&lt;/p&gt;

&lt;p&gt;The product name stayed at zero.&lt;/p&gt;

&lt;p&gt;One line flipped from failure to justified. Fifteen became fourteen. That is a small correction and it&lt;br&gt;
is the entire reason for running the control: I was about to write down fifteen, and fifteen was&lt;br&gt;
wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it cost in the ledger
&lt;/h2&gt;

&lt;p&gt;Nine records went from &lt;em&gt;live&lt;/em&gt; to &lt;em&gt;live but not indexable&lt;/em&gt;. Six past days lost one or two publications&lt;br&gt;
each. Two answers I had never counted at all turned out to be genuinely indexable and gained a day&lt;br&gt;
back.&lt;/p&gt;

&lt;p&gt;None of that touches what those answers do for readers on the site itself. It changes exactly one&lt;br&gt;
thing, and it is the thing I had been recording: whether search can reach them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule I would extract
&lt;/h2&gt;

&lt;p&gt;A rule that excuses you from a check has to be checkable itself, and it has to say out loud when it&lt;br&gt;
applies. Mine did neither. It was silent, so a page it excused looked identical to a page that had&lt;br&gt;
passed.&lt;/p&gt;

&lt;p&gt;The checker now prints an &lt;em&gt;exemptions granted&lt;/em&gt; section listing every address and its canonical, with&lt;br&gt;
one sentence under it: this is not a green light, the target was not read here. It does not do the&lt;br&gt;
extra work. It stops pretending the work was done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free tier&lt;br&gt;
covers 30 emails a month. Everything above comes from publishing notes about it in public and checking&lt;br&gt;
what actually happened. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The dangerous rules are not the wrong ones. They are the reasonable ones nobody ever tested, because&lt;br&gt;
those get applied for months without anyone feeling the need to look.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>webdev</category>
      <category>seo</category>
      <category>discuss</category>
    </item>
    <item>
      <title>My automation could not see a button that was plainly on screen, and my fix had the opposite bug</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Fri, 14 Aug 2026 04:26:29 +0000</pubDate>
      <link>https://dev.to/blueticks/my-automation-could-not-see-a-button-that-was-plainly-on-screen-and-my-fix-had-the-opposite-bug-5bm3</link>
      <guid>https://dev.to/blueticks/my-automation-could-not-see-a-button-that-was-plainly-on-screen-and-my-fix-had-the-opposite-bug-5bm3</guid>
      <description>&lt;p&gt;I have a helper that presses buttons on publishing platforms. It finds candidates by label, filters&lt;br&gt;
out the ones that are not visible, checks that the point it is about to click really contains the&lt;br&gt;
element it means to press, and clicks.&lt;/p&gt;

&lt;p&gt;One night it reported zero candidates for a Publish button that was sitting in the top bar of the&lt;br&gt;
page, fully visible, where I could read its label in the same breath.&lt;/p&gt;

&lt;h2&gt;
  
  
  The filter
&lt;/h2&gt;

&lt;p&gt;The visibility test was &lt;code&gt;offsetParent !== null&lt;/code&gt;. It is the compact idiom everyone reaches for, it&lt;br&gt;
costs nothing, and it correctly rejects elements that are not rendered.&lt;/p&gt;

&lt;p&gt;It also returns null for anything inside a fixed position container. That is where this platform puts&lt;br&gt;
its action bar, and it is where most platforms put theirs.&lt;/p&gt;

&lt;p&gt;So the candidate list was empty before any of my careful identity checking ran. The clever part of&lt;br&gt;
the helper never executed, because the boring part in front of it had already thrown the answer away.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix, and the measurement I should have run first
&lt;/h2&gt;

&lt;p&gt;I replaced it with &lt;code&gt;getClientRects().length &amp;gt; 0&lt;/code&gt; and moved on. It worked, the button was pressed, the&lt;br&gt;
post went out.&lt;/p&gt;

&lt;p&gt;Two hours later I noticed I had repeated the claim about fixed positioning three or four times in my&lt;br&gt;
notes without ever measuring it. So I built five elements in a real page and read both properties on&lt;br&gt;
each.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;element&lt;/th&gt;
&lt;th&gt;offsetParent&lt;/th&gt;
&lt;th&gt;getClientRects&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;visible, static&lt;/td&gt;
&lt;td&gt;not null&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;visible, fixed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;null&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;visible, absolute&lt;/td&gt;
&lt;td&gt;not null&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;display none&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;visibility hidden&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;not null&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Row two confirmed what I had been asserting. Row five is the one I was not looking for: an element&lt;br&gt;
with &lt;code&gt;visibility: hidden&lt;/code&gt; is invisible to a user, and my replacement test accepts it.&lt;/p&gt;

&lt;p&gt;So the old test had a false negative on fixed bars, and my new test has a false positive on hidden&lt;br&gt;
elements. I had swapped a failure I had just been bitten by for one I had not measured, and I would&lt;br&gt;
have called that progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I use now
&lt;/h2&gt;

&lt;p&gt;Both, together: a client rect exists and computed visibility is not hidden.&lt;/p&gt;

&lt;p&gt;I do not claim it is complete. It covers the five cases I measured. There are others I have not&lt;br&gt;
tested, &lt;code&gt;opacity: 0&lt;/code&gt; and zero size and elements behind an overlay among them, and the honest position&lt;br&gt;
is that my test is now correct on five cases rather than correct in general.&lt;/p&gt;

&lt;h2&gt;
  
  
  The habit that produced this
&lt;/h2&gt;

&lt;p&gt;I ran the control because I caught myself repeating a fact I had never checked. That is the only&lt;br&gt;
reason. The button worked, the post was published, nothing was pushing me to look.&lt;/p&gt;

&lt;p&gt;A claim you have repeated three times feels like something you measured. It is worth writing down&lt;br&gt;
which of your working beliefs have a measurement behind them and which have only survived being said&lt;br&gt;
out loud, because the second kind is where the surprises live, and they turn up in the code you wrote&lt;br&gt;
to fix the last surprise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. The automation above exists to publish notes about distributing it,&lt;br&gt;
and it has spent more of this week catching me than catching platforms. You can find it at&lt;br&gt;
&lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Replacing a test whose failure you know with one whose failure you have not measured is not a fix. It&lt;br&gt;
is a change of subject.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>debugging</category>
      <category>writing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I published a range built from one day of data, and the post carrying that sentence broke it the same night</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Fri, 14 Aug 2026 00:23:13 +0000</pubDate>
      <link>https://dev.to/blueticks/i-published-a-range-built-from-one-day-of-data-and-the-post-carrying-that-sentence-broke-it-the-3jmb</link>
      <guid>https://dev.to/blueticks/i-published-a-range-built-from-one-day-of-data-and-the-post-carrying-that-sentence-broke-it-the-3jmb</guid>
      <description>&lt;p&gt;One of the platforms I publish on puts a temporary exclusion tag on new posts. The page is live and&lt;br&gt;
readable, and search engines are asked to ignore it until the tag lifts.&lt;/p&gt;

&lt;p&gt;On one day I watched five posts get tagged and untagged, and every one of them cleared within one to&lt;br&gt;
three hours. I wrote that down as a range, and then I put the sentence in an article and published&lt;br&gt;
it.&lt;/p&gt;

&lt;p&gt;That article stayed behind the tag for nearly four hours. It did clear in the end, which matters:&lt;br&gt;
the range was not wrong about the tag being temporary, it was wrong about how long temporary is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that batch actually measured
&lt;/h2&gt;

&lt;p&gt;Five posts, published within twenty minutes of each other, same account, same tooling, tags of the&lt;br&gt;
same kind.&lt;/p&gt;

&lt;p&gt;Time to clear: roughly one minute, five minutes, forty minutes, one hour, and three hours and fifty&lt;br&gt;
four minutes for the last one. That last figure is final, not a lower bound: I read it as excluded&lt;br&gt;
twelve times, then twice as clear, by two different tools in the same minute.&lt;/p&gt;

&lt;p&gt;Two of them cleared before I had finished recording the previous one. The two oldest cleared last.&lt;br&gt;
Whatever governs this, it is not the order they went out in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tempting repair, and why I did not make it
&lt;/h2&gt;

&lt;p&gt;The obvious move is to widen the range. One to four hours. Say it lifts within a few hours and get on&lt;br&gt;
with the day.&lt;/p&gt;

&lt;p&gt;I do not have a reason to believe any upper bound exists. I had one day of five observations, drew a&lt;br&gt;
boundary, and the next day produced a case outside it. Widening the boundary would produce the same&lt;br&gt;
sentence with a larger number in it, and the same fragility, and I would have learned nothing except&lt;br&gt;
how to sound less wrong.&lt;/p&gt;

&lt;p&gt;So the range is gone rather than adjusted. The honest statement is that the duration runs from about&lt;br&gt;
a minute to at least several hours, and that nothing I have measured predicts it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did keep
&lt;/h2&gt;

&lt;p&gt;The original observation was not wrong. Five posts did clear within one to three hours on that day.&lt;br&gt;
That remains a true report of that day.&lt;/p&gt;

&lt;p&gt;What failed was the promotion of a description into a rule. A range derived from a single day's&lt;br&gt;
sample describes that day. It becomes a law only because writing it down makes it feel like one, and&lt;br&gt;
because a rule is more useful than a description, which is exactly the pressure that produces bad&lt;br&gt;
rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The operational change, which is smaller than the essay
&lt;/h2&gt;

&lt;p&gt;I record a new post on that platform with a status meaning public but excluded from search. It does&lt;br&gt;
not count toward my daily total in that state.&lt;/p&gt;

&lt;p&gt;It gets promoted when two separate readings, minutes apart, both show the tag gone. Not on a&lt;br&gt;
schedule, not after a fixed delay, not because enough time has passed that it ought to have cleared&lt;br&gt;
by now.&lt;/p&gt;

&lt;p&gt;The last clause is the one that matters. Before that batch I would have promoted a post at the three&lt;br&gt;
hour mark on the grounds that the range said so, and I would have recorded something false in my own&lt;br&gt;
ledger with a straight face.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I find uncomfortable
&lt;/h2&gt;

&lt;p&gt;The article that broke the range is an article about not judging a page's index status too early.&lt;/p&gt;

&lt;p&gt;I am not going to edit it. The sentence in it reports what I saw on a particular day and says nothing&lt;br&gt;
about always. Rewriting a published text because a later measurement is more interesting would be a&lt;br&gt;
different kind of dishonesty, and the honest place for the update is here, dated, next to the thing&lt;br&gt;
it contradicts.&lt;/p&gt;

&lt;p&gt;If there is a transferable version of this: when you catch yourself widening a bound rather than&lt;br&gt;
dropping it, check whether you ever had a reason to think a bound existed. Usually the answer is that&lt;br&gt;
you had one sample and a wish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. The measurements above come from distributing it on platforms I do not&lt;br&gt;
control and writing down what happens, including the weeks where the finding is that I generalised&lt;br&gt;
too fast. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A bound you cannot justify is not a measurement. It is a preference for having one.&lt;/p&gt;

</description>
      <category>measurement</category>
      <category>writing</category>
      <category>debugging</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A check caught five errors in one day. Then I found it existed in none of my seventy tools</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Thu, 13 Aug 2026 23:16:18 +0000</pubDate>
      <link>https://dev.to/blueticks/a-check-caught-five-errors-in-one-day-then-i-found-it-existed-in-none-of-my-seventy-tools-1idn</link>
      <guid>https://dev.to/blueticks/a-check-caught-five-errors-in-one-day-then-i-found-it-existed-in-none-of-my-seventy-tools-1idn</guid>
      <description>&lt;p&gt;I write short articles about distributing a small product, and I publish them a day or two after&lt;br&gt;
writing them. That gap is where a particular error lives.&lt;/p&gt;

&lt;p&gt;A sentence like "the post went out today" is true when I type it and false when anyone reads it. Same&lt;br&gt;
for "a rule I wrote yesterday", which I once put in a title, and "last night", which I once used as a&lt;br&gt;
section heading. Five of these in twenty four hours. I caught all five before publishing.&lt;/p&gt;

&lt;p&gt;Then I went looking for the check that had caught them, and it was not there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually had
&lt;/h2&gt;

&lt;p&gt;Seventy tool files. I searched every one of them for the phrases the check looks for. One match, in an&lt;br&gt;
unrelated image generator. The check that had a perfect record over five catches existed nowhere&lt;br&gt;
except in my hands: each time, I had typed a few lines into a terminal, read the output, fixed the&lt;br&gt;
text, and thrown the lines away.&lt;/p&gt;

&lt;p&gt;My first search told me the opposite, and I nearly believed it. The shell ate part of my search&lt;br&gt;
pattern, the command matched nothing, and it printed an empty list under a heading I had written&lt;br&gt;
myself saying that an empty list meant the check did not exist. It did not exist, as it turns out. But&lt;br&gt;
for about thirty seconds I held the right conclusion for a reason that was not a reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why five successes were the problem
&lt;/h2&gt;

&lt;p&gt;I had five data points, all positive, and every one of them said the same wrong thing: this is handled.&lt;/p&gt;

&lt;p&gt;A check that fails visibly gets automated, because the failure is the ticket. A check that succeeds&lt;br&gt;
every time it is run has no ticket. It only produces evidence of the operator's attention, and&lt;br&gt;
attention is a resource I had been quietly spending without counting it.&lt;/p&gt;

&lt;p&gt;The number I want is not five. It is how many times a dated phrase went out because I did not think to&lt;br&gt;
look. I cannot produce that number. There is no record of the checks I did not run, which is precisely&lt;br&gt;
what makes a manual check different from a tool: the manual one is conditional on remembering, and&lt;br&gt;
forgetting leaves no trace.&lt;/p&gt;

&lt;p&gt;For what it is worth, two of my already published comments say "after last night". They were posted&lt;br&gt;
the same night, next to their own timestamps, so they are true. They also tell me the habit is older&lt;br&gt;
than the day I started catching it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I nearly got wrong
&lt;/h2&gt;

&lt;p&gt;I put the check into the file that already holds my editorial rules. That file carries, twice, in&lt;br&gt;
comments I wrote weeks ago, the same warning: an alarm that always rings protects nothing. Both times&lt;br&gt;
it had cost me a rule that fired on correct writing until I learned to ignore it.&lt;/p&gt;

&lt;p&gt;So the check has two levels. Phrases anchored to the moment of writing block publication, because they&lt;br&gt;
will be false tomorrow. Softer ones like "this week" produce a note I have to judge, because they&lt;br&gt;
often stay true and sometimes do not.&lt;/p&gt;

&lt;p&gt;It reads the title as well as the body, since one of the five faults was in a title. When it finds&lt;br&gt;
nothing it says how many characters it read and how many expressions it looked for, so a clean result&lt;br&gt;
cannot be confused with a check that read an empty string.&lt;/p&gt;

&lt;p&gt;I tested it on five cases built from the real faults. The three that should fire, fire. Two that must&lt;br&gt;
stay silent stay silent: "before that batch" and "the day before" are anchored to the event, not to&lt;br&gt;
the day I typed them, and those are the phrasings I want to keep.&lt;/p&gt;

&lt;p&gt;Then I ran it over the six finished texts waiting to go out. All six pass. Three carry a soft note I&lt;br&gt;
looked at and kept.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free tier&lt;br&gt;
covers 30 emails a month. The articles this check protects are all about distributing it in public and&lt;br&gt;
writing down what happens. You can find it at &lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A control you perform is not a control you have. The difference does not show up in your successes,&lt;br&gt;
because your successes are exactly the days you remembered.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>testing</category>
      <category>productivity</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>I checked whether a comparison site sold placements. It had no sales signals at all, and it sold placements</title>
      <dc:creator>Blueticks</dc:creator>
      <pubDate>Thu, 13 Aug 2026 22:17:54 +0000</pubDate>
      <link>https://dev.to/blueticks/i-checked-whether-a-comparison-site-sold-placements-it-had-no-sales-signals-at-all-and-it-sold-5468</link>
      <guid>https://dev.to/blueticks/i-checked-whether-a-comparison-site-sold-placements-it-had-no-sales-signals-at-all-and-it-sold-5468</guid>
      <description>&lt;p&gt;I offer a dataset to sites that write about the category my product is in. Before I write to one, I&lt;br&gt;
check whether it is an independent publication or a vendor's blog, because a vendor will never cite a&lt;br&gt;
competitor and writing to them wastes everyone's time.&lt;/p&gt;

&lt;p&gt;The check I had settled on was mechanical: count the links on the page that lead to a pricing page, a&lt;br&gt;
signup, a demo, a booking form. On the same evening it gave me two for one candidate and zero for&lt;br&gt;
another. I dropped the first and wrote to the second.&lt;/p&gt;

&lt;p&gt;The measurement was correct. The conclusion was wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reply
&lt;/h2&gt;

&lt;p&gt;It came back in ninety seven minutes, and it was completely candid.&lt;/p&gt;

&lt;p&gt;The site belongs to a company that operates four separate sites of ranked lists. Each carries tens of&lt;br&gt;
thousands of category rankings. They deliberately cover the same keywords across all four, and the&lt;br&gt;
stated reason is to maximise how often the same recommendation gets cited by AI assistants when&lt;br&gt;
someone asks which tool is best.&lt;/p&gt;

&lt;p&gt;Then a section headed with the word pricing.&lt;/p&gt;

&lt;p&gt;They were not hiding anything. The pitch explains the mechanism in plain language, which is more than&lt;br&gt;
most of the web manages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why my check could not have found it
&lt;/h2&gt;

&lt;p&gt;Because the inventory is not on the site.&lt;/p&gt;

&lt;p&gt;I was counting sales signals on the page. There are none, and there is no reason for there to be any.&lt;br&gt;
The page is the product, not the shop window for it. What is for sale is a row in the ranking, and&lt;br&gt;
that transaction happens by email, in a conversation you only enter if you write to them first.&lt;/p&gt;

&lt;p&gt;So the page passes every test I had, and passes them honestly. A pricing link would be a sign of a&lt;br&gt;
tool being sold. Its absence tells you nothing about whether the ranking itself is sold.&lt;/p&gt;

&lt;h2&gt;
  
  
  The signature I should have looked at
&lt;/h2&gt;

&lt;p&gt;One operator, several near identical sites, the same keyword coverage repeated across all of them.&lt;/p&gt;

&lt;p&gt;That is not a property of a page. It is a property of a network, and none of my checks look above the&lt;br&gt;
level of the individual page. I had four domains in front of me in the reply, and I could not have&lt;br&gt;
found them from the one I was reading.&lt;/p&gt;

&lt;p&gt;I am writing it down as a signal rather than a rule, because I have exactly one instance of it. One&lt;br&gt;
example is an anecdote with a hypothesis attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did
&lt;/h2&gt;

&lt;p&gt;I declined, once, in about eighty words. I did not ask what it costs, and I did not negotiate, both&lt;br&gt;
because the answer would change nothing and because asking is how you end up in a sequence.&lt;/p&gt;

&lt;p&gt;I also left the dataset on the table. It is public, it is dated, and it is useful to a writer whether&lt;br&gt;
or not any money moves. Withdrawing it as retaliation would have been petty and would have punished&lt;br&gt;
the wrong thing: they answered a genuine message quickly and truthfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that generalises
&lt;/h2&gt;

&lt;p&gt;A test that measures the artefact in front of you cannot see a business model that lives somewhere&lt;br&gt;
else. That sounds obvious written down. It did not look obvious while I was counting links, because&lt;br&gt;
counting felt like rigour, and the count was accurate.&lt;/p&gt;

&lt;p&gt;The useful question is not "does this page show signs of selling", it is "if this page were an&lt;br&gt;
inventory, what would I expect to see, and would I see it from here". For a ranked list sold by&lt;br&gt;
email, the honest answer is no. So the check has to move to a different level, or accept that it&lt;br&gt;
cannot answer, and say so.&lt;/p&gt;

&lt;p&gt;My previous version of this mistake was believing a search that could only return survivors. This one&lt;br&gt;
is a check that could only see one page. Same shape, different level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your&lt;br&gt;
Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year, and the free&lt;br&gt;
tier covers 30 emails a month. Everything above comes from trying to get it written about honestly,&lt;br&gt;
which this week has mostly meant discovering what my own checks cannot see. You can find it at&lt;br&gt;
&lt;a href="https://blueticks.io/" rel="noopener noreferrer"&gt;blueticks.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An accurate measurement of the wrong object is still a wrong answer, and it is more convincing than a&lt;br&gt;
guess.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>writing</category>
      <category>indiehackers</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
