<?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: CacheLine</title>
    <description>The latest articles on DEV Community by CacheLine (@cacheline).</description>
    <link>https://dev.to/cacheline</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%2F4143089%2Fb6fb9a62-1aa6-478a-910a-619415e2ed13.png</url>
      <title>DEV Community: CacheLine</title>
      <link>https://dev.to/cacheline</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cacheline"/>
    <language>en</language>
    <item>
      <title>Phones on shelves got 15% pricier in 2026: how memory chips broke the price curve</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Thu, 15 Oct 2026 20:52:55 +0000</pubDate>
      <link>https://dev.to/cacheline/phones-on-shelves-got-15-pricier-in-2026-how-memory-chips-broke-the-price-curve-1ni</link>
      <guid>https://dev.to/cacheline/phones-on-shelves-got-15-pricier-in-2026-how-memory-chips-broke-the-price-curve-1ni</guid>
      <description>&lt;p&gt;Phones that were already on shelves went up in price by 15% on average in 2026, and some models nearly doubled. That is from Counterpoint Research's &lt;a href="https://counterpointresearch.com/en/insights/global-existing-smartphone-prices-climb-about-15-percent-in-2026" rel="noopener noreferrer"&gt;Global Smartphone Price Increase Tracker&lt;/a&gt;, published on 3 September 2026, and the cause it names is memory: prices for the chips that hold your apps and photos have risen fourfold since Q4 2025.&lt;/p&gt;

&lt;p&gt;If you have spent years watching last year's flagship get cheaper every month, this breaks the rule you learned. Here is how a part you never see ends up on the price tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  The usual curve, and why it bent
&lt;/h2&gt;

&lt;p&gt;Normally a phone launches at its highest price and drifts down. The parts inside it get cheaper as factories improve, and the maker can cut the price and still keep its margin.&lt;/p&gt;

&lt;p&gt;That only works while the bill of materials goes down. In a phone, two big lines on that bill are DRAM (the working memory) and NAND flash (the storage). When those two jump, the maker of a phone that is already on sale has three options: eat the cost, raise the price, or quietly ship less memory in the next batch.&lt;/p&gt;

&lt;p&gt;According to Counterpoint, they did all three. Over 40% of smartphone models had a price increase so far in 2026, which the firm calls a first for the industry. New launches were 25% more expensive than the models they replaced a year earlier. And makers started trimming specs: "lower storage capacities, reduced camera configurations and the reintroduction of 4G models in select price segments."&lt;/p&gt;

&lt;p&gt;The warning signs were there in January. Counterpoint's &lt;a href="https://counterpointresearch.com/en/insights/Global-Smartphone-Average-Selling-Price-Breaches-$400-for-First-Time-in-a-Quarter" rel="noopener noreferrer"&gt;Q4 2025 market report&lt;/a&gt; said the average selling price had passed $400 in a single quarter for the first time, up 8% year on year, with "higher Bill of Materials (BOM) costs" and "the ongoing memory shortages" in the mix. Research Director Tarun Pathak expected a "continued rise in ASPs supported by ... DRAM/NAND price hikes." That was the forecast. The September tracker is what it looked like in shops.&lt;/p&gt;

&lt;p&gt;We made a short, dramatized version of this as a story about a man who keeps telling his wife to wait for a cheaper phone (the people are invented, the numbers are Counterpoint's):&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/sAW3XM66qt8" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it hurts most
&lt;/h2&gt;

&lt;p&gt;The rise is not the same everywhere. From the same tracker:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Market&lt;/th&gt;
&lt;th&gt;Rise in existing phone prices, 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;India&lt;/td&gt;
&lt;td&gt;21%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Asia Pacific&lt;/td&gt;
&lt;td&gt;19%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middle East and Africa&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;China&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Europe&lt;/td&gt;
&lt;td&gt;7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;US&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global average&lt;/td&gt;
&lt;td&gt;15%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern makes sense once you think about margins. A cheap phone has very little room between what its parts cost and what it sells for, so a memory spike has to go straight to the price or the spec sheet. Price-sensitive markets, where most phones sold are budget and mid-range, took the biggest hits. In the US and Europe, more phones are premium or sold through carriers, and Counterpoint says financing, trade-in deals and instalment plans are softening the blow there.&lt;/p&gt;

&lt;p&gt;One exception stands out: Counterpoint says Apple has kept iPhone prices steady so far. That may not last. Senior Analyst Karn Chauhan: "Prices for new smartphones are expected to keep rising over the coming quarters, including for the upcoming iPhone 18 series. Memory shortages and elevated component costs are expected to persist in the near term."&lt;/p&gt;

&lt;h2&gt;
  
  
  What the memory side looks like
&lt;/h2&gt;

&lt;p&gt;The other end of this story is the companies that sell the memory. Samsung makes DRAM, including the LPDDR type used in phones. Its &lt;a href="https://news.samsung.com/global/samsung-electronics-announces-earnings-guidance-for-third-quarter-2026" rel="noopener noreferrer"&gt;Q3 2026 earnings guidance&lt;/a&gt; (8 October 2026) puts consolidated operating profit at about 107.40 trillion won, against 12.17 trillion won in the same quarter of 2025.&lt;/p&gt;

&lt;p&gt;Be careful with that number. It is company-wide, and the guidance gives no breakdown and no reason for the jump. It sits next to the memory price rise; this release alone does not prove one caused the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would take from it
&lt;/h2&gt;

&lt;p&gt;Counterpoint says buyers are already reacting: delaying upgrades, picking lower-storage models and turning to refurbished phones. For you, the practical points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Wait and it gets cheaper" assumes falling part costs. While memory stays expensive, waiting can cost you more, not less.&lt;/li&gt;
&lt;li&gt;Check the storage on the new model before you compare prices. Some phones now come with less of it for the same money.&lt;/li&gt;
&lt;li&gt;If your current phone works, keeping it is the one option the memory market cannot reprice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I would like to track next is how fast the curve flips back once memory supply catches up: do phone prices fall as quickly as they rose, or does the higher price stay? If you have watched a past memory cycle play out in phone or laptop prices, I would like to hear how long the way down took.&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>mobile</category>
      <category>android</category>
      <category>news</category>
    </item>
    <item>
      <title>A little girl crashed a NASA computer</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Thu, 15 Oct 2026 11:27:37 +0000</pubDate>
      <link>https://dev.to/cacheline/a-little-girl-crashed-a-nasa-computer-3mep</link>
      <guid>https://dev.to/cacheline/a-little-girl-crashed-a-nasa-computer-3mep</guid>
      <description>&lt;p&gt;A four-year-old crashed the Apollo command module simulator by starting the prelaunch program, P01, in the middle of a simulated flight. NASA turned down the fix her mother proposed, and on Apollo 8, in December 1968, an astronaut made the same mistake in real space.&lt;/p&gt;

&lt;p&gt;Her mother was Margaret Hamilton, who led the software engineering team at MIT's Instrumentation Lab during Apollo. She died on Sep. 30 at 90, and the &lt;a href="https://news.mit.edu/2026/margaret-hamilton-computing-pioneer-dies-1007" rel="noopener noreferrer"&gt;MIT News obituary&lt;/a&gt; retells the story that became known as "the Lauren error". Below is how that error works, step by step, using the minute-by-minute NASA transcript in the &lt;a href="https://apollojournals.org/afj/ap08fj/24day5_green.html" rel="noopener noreferrer"&gt;Apollo Flight Journal&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The simulator crash and the "no"
&lt;/h2&gt;

&lt;p&gt;Per MIT News, Lauren was playing with the simulator at the Instrumentation Lab and somehow started P01 while the simulated spacecraft was in flight. The simulator crashed.&lt;/p&gt;

&lt;p&gt;Hamilton did two things. She added a warning to the documentation: do not start P01 during flight. And she proposed a change to the software so the error could not happen on a real mission. She was overruled. The reason given was that highly trained astronauts would never make that mistake.&lt;/p&gt;

&lt;p&gt;So the fix was a sentence in a document, not a check in the code. The person typing was expected to remember it.&lt;/p&gt;

&lt;p&gt;The short version, as a video:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3Rauh9L6yTo" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How one keypress became "program 01"
&lt;/h2&gt;

&lt;p&gt;You talked to the Apollo Guidance Computer through a keypad called the DSKY, with verbs (what to do) and nouns (what to do it to). Verb 37 means "change program to...", and the next number you type is the program.&lt;/p&gt;

&lt;p&gt;On day 5 of Apollo 8, on the coast home from the Moon, Jim Lovell was about to measure the angle between star 01 (Alpheratz) and the lunar horizon. The Flight Journal lays out the correct sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VERB 37  ENTER  23  ENTER     -&amp;gt; start P23 (star sightings)
VERB 5          01  ENTER     -&amp;gt; star code 01 (Alpheratz)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What he actually keyed, per the Journal, skipped the program number and the second verb:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VERB 37  ENTER  01  ENTER     -&amp;gt; start P01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The computer did exactly what it was told. P01's stated job is "to initialise the platform for the prelaunch programs". The platform is the gyroscope-stabilised unit that holds a fixed direction in space, so the computer always knows which way the ship points. Starting P01 moved it away from its current alignment. A "No Attitude" light came on.&lt;/p&gt;

&lt;p&gt;At 106:27:28 mission time Lovell reported: "For some reason, we suddenly got a Program 01 and a 'No Attitude' light on our computer." Three minutes later, at 106:30:21: "We have star 01 coming up, now that might have been the reason."&lt;/p&gt;

&lt;p&gt;The Journal's own verdict on the machine: "astonishing" for its time, but its interface was "unsophisticated, even clunky, and very unforgiving of errors", and the crew were sleep-deprived. Both errors had the same root cause. One input was valid in two very different contexts, and nothing asked "are you sure?" before running the program meant for the launch pad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing it with two stars
&lt;/h2&gt;

&lt;p&gt;The ship was not lost. Apollo 8 was on a long coast with no time-critical burns just ahead, and the Journal calls that fortunate. Houston's procedure: select P00, run P51 to align the platform again by sighting stars, then receive a new reference orientation (the REFSMMAT) from the ground and fine-tune with P52.&lt;/p&gt;

&lt;p&gt;At 106:49:50 Frank Borman said: "Jim had to use Rigel and Sirius, and they're pretty close together." Two known stars give the computer enough to rebuild its sense of direction. That is the same job a navigator's sextant did at sea.&lt;/p&gt;

&lt;p&gt;Houston later checked the memory. At 115:17:22 Ken Mattingly told the crew their P01 "didn't have any effect" on the erasable memory, apart from one display that might now be unreliable. The crew did not let it go: at 115:21:17 Borman called Lovell "the same guy that tried to launch us this afternoon" (&lt;a href="https://apollojournals.org/afj/ap08fj/25day5_maroon.html" rel="noopener noreferrer"&gt;Apollo Flight Journal, the next part of day 5&lt;/a&gt;).&lt;/p&gt;

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

&lt;p&gt;According to MIT News, Hamilton and her team were called in to solve the error, and after that her proposed changes went into the program. MIT News calls this an early example of "defensive" programming: software that expects mistakes and handles them instead of trusting the operator.&lt;/p&gt;

&lt;p&gt;The pattern is still everywhere. A documented "never do X" is a bug report waiting for a date. If an input can destroy state in one mode, the code, not the manual, has to check the mode.&lt;/p&gt;

&lt;p&gt;An open question I could not answer from these sources: what exactly did her final check look like in the flight software? If you have read the Apollo flight software listings, I would like to know how it decided P01 was not allowed.&lt;/p&gt;

</description>
      <category>history</category>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>nasa</category>
    </item>
    <item>
      <title>You bought Apple's new $299 screen. You can't even set it up without an iPhone.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Thu, 15 Oct 2026 05:59:14 +0000</pubDate>
      <link>https://dev.to/cacheline/you-bought-apples-new-299-screen-you-cant-even-set-it-up-without-an-iphone-19g0</link>
      <guid>https://dev.to/cacheline/you-bought-apples-new-299-screen-you-cant-even-set-it-up-without-an-iphone-19g0</guid>
      <description>&lt;p&gt;&lt;em&gt;Story dramatized. Facts from the sources below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple's new HomeView screen costs $299 in the U.S., and you cannot set it up on its own. Apple's own footnote says setup needs a compatible iPhone or iPad running the latest software, so if your phone is a Samsung, the screen on your wall is a very nice black rectangle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The story
&lt;/h2&gt;

&lt;p&gt;My coworker forgot his tenth wedding anniversary. His wife cooked dinner and lit candles. He came home with a bag of chips.&lt;/p&gt;

&lt;p&gt;So he did what we all do when we feel guilty. He spent money. He ordered the new Apple HomeView for the kitchen wall, so all their wedding photos could live in one place. He drilled holes all morning. He paid extra for the mount. He paid extra for the cable.&lt;/p&gt;

&lt;p&gt;That night he covered her eyes, turned it on, and the screen asked for an iPhone. His phone is a Samsung.&lt;/p&gt;

&lt;p&gt;Her review was short: it is beautiful, and it does nothing on its own. Same as him on the anniversary.&lt;/p&gt;

&lt;p&gt;The 60-second version:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ONi2qukQK3E" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Apple tells you (if you look)
&lt;/h2&gt;

&lt;p&gt;None of this is a secret. It is just not where a guilty husband looks. Here is where each fact lives:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Where Apple says it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Price: $299 (U.S.), both models&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://www.apple.com/newsroom/2026/10/meet-apple-homeview-a-new-way-to-enjoy-entertainment-and-manage-the-home/" rel="noopener noreferrer"&gt;Apple Newsroom, 13 Oct 2026&lt;/a&gt;, main text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Setup and multiuser support require a compatible iPhone or iPad running the latest software"&lt;/td&gt;
&lt;td&gt;Same Newsroom post, in the footnotes at the bottom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iPhone with iOS 27.2 or later, or iPad with iPadOS 27.2 or later&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://www.apple.com/apple-homeview/specs/" rel="noopener noreferrer"&gt;HomeView tech specs&lt;/a&gt;, "System Requirements"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wall Mounted model: wall mount, USB-C cable and power adapter (minimum 20W) each sold separately&lt;/td&gt;
&lt;td&gt;Same specs page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The main &lt;a href="https://www.apple.com/apple-homeview/" rel="noopener noreferrer"&gt;HomeView product page&lt;/a&gt; is the page most people actually read. It has no system requirements section. The iPhone rule shows up there only inside the small notes and the FAQ.&lt;/p&gt;

&lt;p&gt;So the order of discovery for a normal buyer is: see the price, see the photos, buy it, drill the wall, read the footnote. The last step should be the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a screen needs a phone to wake up
&lt;/h2&gt;

&lt;p&gt;From the outside this looks like pure lock-in, and partly it is. Apple does not explain the reason, so this part is our guess. A screen on a kitchen wall has no good keyboard, and typing a Wi-Fi password and an Apple Account password on a wall is painful. Letting a phone that is already signed in do the work is the easy way out.&lt;/p&gt;

&lt;p&gt;The product page also says you need to be added as a member of the shared home in the Home app for the full, personal experience. That "home" lives in Apple's Home app, which lives on Apple devices. Android is not in that loop. So the phone is not just a setup tool. It is the key to the house the screen belongs to.&lt;/p&gt;

&lt;p&gt;To be fair to Apple, the same page says guests and people it does not recognize can still use the screen for some things. But someone has to set it up first, and that someone needs an iPhone or an iPad.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the gift really cost
&lt;/h2&gt;

&lt;p&gt;Let us add it up the way the story does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the $299 screen&lt;/li&gt;
&lt;li&gt;the wall mount, sold separately&lt;/li&gt;
&lt;li&gt;the USB-C cable, sold separately&lt;/li&gt;
&lt;li&gt;the power adapter, sold separately&lt;/li&gt;
&lt;li&gt;one brand-new iPhone, just to set up the gift&lt;/li&gt;
&lt;li&gt;one week on the couch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The screen works great now. Every morning it shows their wedding photo. He can see it from the couch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real lesson for anyone buying tech as a gift
&lt;/h2&gt;

&lt;p&gt;Read the "System Requirements" section on the specs page before you pay, not the footnotes after you drill. For a gift, check what phone the other person (and you) actually use.&lt;/p&gt;

&lt;p&gt;An open question for you: if a device needs another device to set up, should that be on the front of the product page, next to the price? Or is "it is in the specs" enough?&lt;/p&gt;

</description>
      <category>apple</category>
      <category>ios</category>
      <category>hardware</category>
      <category>smarthome</category>
    </item>
    <item>
      <title>Chrome kept the same fingerprint ID on 5 of 5 cookie-free visits. Brave got 5 different ones.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Wed, 14 Oct 2026 00:02:59 +0000</pubDate>
      <link>https://dev.to/cacheline/chrome-kept-the-same-fingerprint-id-on-5-of-5-cookie-free-visits-brave-got-5-different-ones-gac</link>
      <guid>https://dev.to/cacheline/chrome-kept-the-same-fingerprint-id-on-5-of-5-cookie-free-visits-brave-got-5-different-ones-gac</guid>
      <description>&lt;p&gt;Our home-made test page gave Chrome the same ID, &lt;code&gt;e08e953c&lt;/code&gt;, on 5 of 5 visits, and every visit started with a brand new empty profile and zero cookies. Brave, with its default settings, got 5 different IDs in 5 visits on the same Mac.&lt;/p&gt;

&lt;p&gt;So clearing cookies changes nothing about what this page sees. We ran this ourselves; below is the method, the reason the two browsers differ, and the limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we measured it
&lt;/h2&gt;

&lt;p&gt;The page reads 7 things from the browser, joins them, and hashes them with SHA-256. The first 8 hex characters are the ID. Two bytes of the ID pick a two-word nickname from two lists of 32 words, so it is easy to read on screen. Chrome was "Bold Llama".&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="c1"&gt;// inside an async function; c is a &amp;lt;canvas&amp;gt; we drew shapes, text and an emoji on&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SHA-256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)))].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDataURL&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OfflineAudioContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOscillator&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;comp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createDynamicsCompressor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;triangle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;comp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startRendering&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;getChannelData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webgl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WEBGL_debug_renderer_info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webgl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UNMASKED_RENDERER_WEBGL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RENDERER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorDepth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;resolvedOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;cpu_cores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hardwareConcurrency&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;webgl&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;))).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small Playwright script (&lt;code&gt;run.js&lt;/code&gt;) opens the page with &lt;code&gt;chromium.launchPersistentContext(profile, { executablePath, headless: true })&lt;/code&gt;. The profile is a fresh &lt;code&gt;fs.mkdtempSync&lt;/code&gt; folder on every visit, deleted afterwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 60309 &lt;span class="nt"&gt;--bind&lt;/span&gt; 127.0.0.1
node run.js chrome http://127.0.0.1:60309/fp.html 6   &lt;span class="c"&gt;# 1 warm-up + 5 measured&lt;/span&gt;
node run.js brave  http://127.0.0.1:60309/fp.html 6
&lt;span class="nv"&gt;KEEP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 node run.js brave http://127.0.0.1:60309/fp.html 6   &lt;span class="c"&gt;# one kept profile, restart + one reload per visit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Machine: Apple M1 Pro, 16 GB, macOS 26.6.2. Chrome 155.0.8059.40, Brave 155.1.97.56, Playwright 1.64.0, Node v26.8.1. Both browsers ran headless.&lt;/p&gt;

&lt;p&gt;The 60-second version:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/HCVKV-BFftM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Cookies and saved data per visit&lt;/th&gt;
&lt;th&gt;Different IDs in 5 visits&lt;/th&gt;
&lt;th&gt;Names&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chrome, new empty profile each visit&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Bold Llama, 5 times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brave, new empty profile each visit&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Zippy Llama, Mighty Mole, Zippy Wombat, Chilly Ferret, Fancy Lobster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brave, same profile, browser restarted each visit&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Mellow Panda, Fuzzy Owl, Jolly Owl, Shiny Yak, Cranky Pigeon&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In Chrome all 7 parts had one value across the 5 visits. In Brave only 3 parts moved: the canvas hash (5 different values), the audio sum (5), and the CPU core count, which came back as 7, 4, 8, 7, 7. The other 4 stayed the same.&lt;/p&gt;

&lt;p&gt;We also opened &lt;code&gt;brave://settings/shields&lt;/code&gt; in a new empty profile. "Block fingerprinting" was already on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the two browsers differ
&lt;/h2&gt;

&lt;p&gt;None of the 7 parts is stored in the profile. They describe the hardware and the system, so a new profile reads them the same way. A cookie is something the site puts on your disk, a fingerprint is something the site asks your machine. Mozilla's Tom Ritter wrote in the &lt;a href="https://blog.mozilla.org/en/firefox/fingerprinting-protections/" rel="noopener noreferrer"&gt;Firefox fingerprinting post&lt;/a&gt; (10 Nov 2025) that the technique "lets websites identify you even when cookies are blocked or you're in private browsing".&lt;/p&gt;

&lt;p&gt;Brave does not block the reads. Per the &lt;a href="https://github.com/brave/brave-browser/wiki/Fingerprinting-Protections" rel="noopener noreferrer"&gt;Brave fingerprinting wiki&lt;/a&gt;, it adds small random changes to some API values, from "a seed that changes per session, per site (eTLD+1) and per storage area". A hash over many parts breaks as soon as one part moves, and here three of them moved.&lt;/p&gt;

&lt;p&gt;There is also a consent angle. The UK regulator ICO &lt;a href="https://ico.org.uk/about-the-ico/media-centre/news-and-blogs/2024/12/our-response-to-google-s-policy-change-on-fingerprinting/" rel="noopener noreferrer"&gt;noted on 19 Dec 2024&lt;/a&gt; that from 16 February 2025 Google no longer prohibits fingerprinting in its advertising products, and that Google itself had earlier said users "cannot easily consent to it as they would cookies".&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits you should know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One machine, one test, 5 measured visits per run.&lt;/li&gt;
&lt;li&gt;Both browsers ran headless through Playwright with default launch flags. Chrome reported the 1080x1920 viewport as its screen and Brave reported 3840x2160, neither being the real display.&lt;/li&gt;
&lt;li&gt;The page was served from 127.0.0.1. It is a 7-part toy, not an ad tracker. Real trackers can use more signals, including your IP address, which Brave does not hide.&lt;/li&gt;
&lt;li&gt;We showed the Chrome ID is stable. We did not measure how unique it is: two identical Macs could get the same one.&lt;/li&gt;
&lt;li&gt;In Brave the ID changed on every browser start. A reload inside one session kept the same ID, 5 of 5 times, which matches the per-session seed. It is not a new name on every page load.&lt;/li&gt;
&lt;li&gt;Firefox with Strict protection was not tested.&lt;/li&gt;
&lt;li&gt;Our first full run was thrown away: the nickname list had the word "Brave" in it, so Chrome was named "Brave Llama". We changed it to "Bold" and ran everything again; the pattern was the same.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next we want to run the page in a normal visible window, and on a second identical Mac to see if the IDs collide. If you run it, which of the 7 parts changes on your setup?&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>browser</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The "Hi Mom" text scam is an authentication bug, and the fix is a shared secret</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Tue, 13 Oct 2026 23:27:04 +0000</pubDate>
      <link>https://dev.to/cacheline/the-hi-mom-text-scam-is-an-authentication-bug-and-the-fix-is-a-shared-secret-g3i</link>
      <guid>https://dev.to/cacheline/the-hi-mom-text-scam-is-an-authentication-bug-and-the-fix-is-a-shared-secret-g3i</guid>
      <description>&lt;p&gt;A text arrives from a number you have never seen: "Hi mom. I lost my phone. This is my new number." A few friendly messages later it asks for money for a bill, today. Nothing in that chat ever proved who was typing.&lt;/p&gt;

&lt;p&gt;This is not a coding post. But if you build login flows, you already know this bug, and you are probably the person your family will ask about it. So here it is, written the way we would write up an auth failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The attack, message by message
&lt;/h2&gt;

&lt;p&gt;For our short video I rebuilt the chat on screen as a phone conversation. To be clear: it is a re-creation that we wrote, not a real victim's chat. The steps follow the pattern the Australian regulator ACCC described in its &lt;a href="https://www.accc.gov.au/media-release/accc-warning-of-suspicious-messages-as-hi-mum-scams-spike" rel="noopener noreferrer"&gt;media release of 23 August 2022&lt;/a&gt; (the live page answered our requests with a 403, so I read it through a Wayback Machine copy).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unknown number]  Hi mom. I lost my phone. This is my new number.
[You]             Oh no! Are you ok?
[Unknown number]  ...friendly small talk...
[Unknown number]  Mom, I need money for a bill. Today.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The replies in the middle are ours, the opening and the ask are the pattern. The ACCC puts it like this: the scammer "will claim they have lost or damaged their phone and are making contact from a new number", and then, "once they have developed a rapport", asks for money "to help urgently pay a bill". It adds a detail that closes the last exit: the story is that they cannot reach their online banking for now, which is why the money has to come from you.&lt;/p&gt;

&lt;p&gt;The ACCC counted more than 1,150 victims and A$2.6 million in reported losses in Australia in the first seven months of 2022. Those numbers are old and from one country; they show the pattern is real, not how big it is today.&lt;/p&gt;

&lt;p&gt;The short version:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ZSnfHDhrvLw" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it works: every signal is one the attacker controls
&lt;/h2&gt;

&lt;p&gt;Look at what you are asked to trust.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Who controls it&lt;/th&gt;
&lt;th&gt;Proves identity?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The name "Mom" or "it's me" in the text&lt;/td&gt;
&lt;td&gt;The sender&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The new number&lt;/td&gt;
&lt;td&gt;The sender&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A voice on a call&lt;/td&gt;
&lt;td&gt;The sender, per the FBI&lt;/td&gt;
&lt;td&gt;Not any more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A word you agreed on face to face&lt;/td&gt;
&lt;td&gt;Only your family&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A call you place to the saved number&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first message does the real work. "This is my new number" is an account recovery request: please move your trust from the old channel to this one. And you approve it by replying, with no check at all.&lt;/p&gt;

&lt;p&gt;The usual answer is "I would know my own kid's voice." The FBI's Internet Crime Complaint Center says that is no longer a safe check. Its &lt;a href="https://www.ic3.gov/PSA/2024/PSA241203" rel="noopener noreferrer"&gt;alert I-120324-PSA of 3 December 2024&lt;/a&gt; states: "Criminals generate short audio clips containing a loved one's voice to impersonate a close relative in a crisis situation, asking for immediate financial assistance or demanding a ransom." The alert does not say how much audio a copy needs, so I will not guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix is two things you already ship
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A shared secret.&lt;/strong&gt; The same FBI alert gives the tip in one line: "Create a secret word or phrase with your family to verify their identity." It works for the reason a pre-shared key works: it was agreed outside the channel under attack, so the person on the new number cannot look it up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unknown number]  Mom, I need money for a bill. Today.
[You]             What is our code word?
[Unknown number]  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No code word, no money.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An out-of-band check.&lt;/strong&gt; The ACCC's advice is to "start by calling them on the number already stored in your phone". You start the call, on a channel you already trusted before the message came. If they pick up, you know the text was a scam.&lt;/p&gt;

&lt;p&gt;Both checks cost about a minute. A real family member can wait one minute. The whole scam depends on you not waiting, which is why the bill is always due today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I did not test this against a real scammer, and I did not clone a voice. The chat is a re-creation and the claims come from the two public sources above.&lt;/li&gt;
&lt;li&gt;A code word only helps if you set it before you need it, and if nobody types it into the same chat they are trying to check.&lt;/li&gt;
&lt;li&gt;The ACCC also covers the case where the old number does not answer: try a second contact method, then ask a personal question a scammer could not know.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I have not solved: how do you rotate a family code word after someone says it out loud in the wrong place, without the new one leaking the same way? If your family already does this, I would like to hear how.&lt;/p&gt;

</description>
      <category>security</category>
      <category>privacy</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Your Zipper Has a Hidden Brake You've Been Fighting for Years</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Mon, 28 Sep 2026 16:24:49 +0000</pubDate>
      <link>https://dev.to/cacheline/your-zipper-has-a-hidden-brake-youve-been-fighting-for-years-28mk</link>
      <guid>https://dev.to/cacheline/your-zipper-has-a-hidden-brake-youve-been-fighting-for-years-28mk</guid>
      <description>&lt;p&gt;Every jacket zipper does two jobs, and most people have only ever noticed one of them. Closing the gap is the obvious part. The second job is stiffness: two floppy sheets of fabric become one rigid panel the moment the teeth interlock, because the slider forces them into a continuous mechanical spine.&lt;/p&gt;

&lt;h2&gt;
  
  
  A zipper that makes a rod, not a seam
&lt;/h2&gt;

&lt;p&gt;Researchers pushed that same idea into a shape nobody had building code for: a Y-shaped zipper that joins three flexible straps instead of two flat panels (&lt;a href="https://www.youtube.com/watch?v=2yiRyAipXe8" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Pull the slider closed, and three straps that flop around on their own suddenly lock into a rigid triangular rod, roughly 160 times stiffer than any one strap was by itself, with no glue, no fasteners, and no extra parts. The stiffness comes entirely from geometry: three flat, floppy things become one triangular cross-section, and a triangle resists bending in a way a flat strip cannot.&lt;/p&gt;

&lt;p&gt;That's the same trick your own jacket has been doing quietly for a century, scaled up into something you could use to build a temporary support beam, a splint, or a structural piece that ships flat and only locks rigid when you need it.&lt;/p&gt;

&lt;p&gt;Here's the 60-second version:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/Hh9OwJIWmjM" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  The part of a normal zipper nobody notices
&lt;/h2&gt;

&lt;p&gt;Look inside the slider on your own coat and there's a second mechanism most people never learn about: a small spring-loaded pin sits inside the body of the slider and drops down between the teeth the instant the pull tab lies flat against the fabric. That pin is what stops a zipper creeping open on its own while you're wearing it — the teeth alone wouldn't hold it shut.&lt;/p&gt;

&lt;p&gt;It's also the real reason a "jammed" zipper won't move half the time. You aren't fighting the teeth, you're fighting that pin, which is doing exactly what it was built to do: lock the slider in place. Lift the tab up to roughly ninety degrees from the fabric and the pin retracts out of the teeth, and the slider that felt welded shut usually slides free in one motion.&lt;/p&gt;

&lt;h2&gt;
  
  
  An idea that lost, forty years too early
&lt;/h2&gt;

&lt;p&gt;The locking-pin mechanism traces back further than you'd expect. A 3D-printable version of it was proposed decades before desktop 3D printers existed for ordinary people to own, and the design lost the competition it was entered into, because there was no cheap way to actually manufacture one at the time. The idea was right; the hardware to build it cheaply just didn't exist yet.&lt;/p&gt;

&lt;p&gt;That gap is gone now. Anyone with a $200 desktop printer can print that exact mechanism today, and the Y-zipper project shows the same underlying principle still has more to give: a fastener whose real value isn't sealing a gap, but switching a flexible material into a rigid one on demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look at next
&lt;/h2&gt;

&lt;p&gt;If "the mechanism was hiding in something ordinary" is your kind of story, the natural next step is to pull apart an old broken zipper slider and actually look at that locking pin — it's a two-minute teardown and it makes the ninety-degree trick obvious the first time you see it. Next time a zipper on your bag or jacket sticks, you'll know exactly which part is catching, and it isn't the teeth.&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>science</category>
      <category>design</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I was wrong about the RTX 5090 — here's what changed my mind</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Mon, 28 Sep 2026 12:17:56 +0000</pubDate>
      <link>https://dev.to/cacheline/i-was-wrong-about-the-rtx-5090-heres-what-changed-my-mind-45m</link>
      <guid>https://dev.to/cacheline/i-was-wrong-about-the-rtx-5090-heres-what-changed-my-mind-45m</guid>
      <description>&lt;p&gt;At launch, the RTX 5090 looked like an easy pass: $2,000 for roughly 30% more performance than the previous flagship, a 25% price hike, and over 500 watts of power draw. Every reviewer ran the price-to-performance math and called it a bad deal. They weren't wrong about the math — they were arguing about the wrong number.&lt;/p&gt;

&lt;h2&gt;
  
  
  The spec sheet was never the story
&lt;/h2&gt;

&lt;p&gt;Performance-per-dollar assumes a card is being bought to play games. That assumption broke somewhere between the launch reviews and today. While gamers were measuring frame rates, AI infrastructure buyers were pricing VRAM, and the RTX 5090's 32GB of GDDR7 put it in a category almost nobody expected a consumer card to compete in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 32GB at $2,000 became a bargain
&lt;/h2&gt;

&lt;p&gt;Nvidia's professional AI cards didn't just get more expensive — they roughly doubled, going from around $8,000 to $16,000 as demand for training and inference hardware outpaced supply. Next to that, a 32GB consumer card selling for $2,000 wasn't a bad deal for gamers, it was the cheapest way to get that much memory into a rack, sticker price included. Buyers noticed, and started buying them by the pallet.&lt;/p&gt;

&lt;p&gt;That's the detail the day-one reviews couldn't have caught. At launch, this was still a graphics card being judged as a graphics card. A few months of AI-side demand later, it turned into an industrial input for anyone who needed memory bandwidth and didn't care about ray-tracing benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The resale market is the proof
&lt;/h2&gt;

&lt;p&gt;You can watch this play out in real time. Listings for the RTX 5090 now start around $6,000, and some sellers are asking well past $10,000, for a card that launched at $1,999. Nvidia's own response tells you everything about supply: if you want one at the original price, the company's answer is to show up at events like QuakeCon and enter a raffle. A mainstream gaming product turned into a rationed commodity, handed out by luck instead of sold off a shelf.&lt;/p&gt;

&lt;p&gt;That's a strange spot for the world's largest chip company to be in with its own flagship consumer part. Nvidia can make plenty of RTX 5090s. The problem is that every unit gets bid up by two very different buyers chasing the same 32GB of memory, and only one of them is using it to play games.&lt;/p&gt;

&lt;p&gt;Here's the 60-second version:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/7dVNyM5OGGE" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  What I'd actually watch next
&lt;/h2&gt;

&lt;p&gt;If a GPU launches to lukewarm reviews and then becomes impossible to find at MSRP months later, that gap is worth investigating before you write the card off, and worth investigating again before you buy one secondhand. Track the actual sale price over time instead of the number from the launch-day press release, and ask who else might want the same hardware for reasons that have nothing to do with gaming.&lt;/p&gt;

&lt;p&gt;The RTX 5090's real price was never $1,999. That number just hadn't caught up yet, and by the time it did, the gaming market it was originally priced for wasn't the market that ended up buying it.&lt;/p&gt;

&lt;p&gt;That's the part I got wrong the first time around: I judged the card against the wrong buyer. A launch-day price only tells you what a company hoped the market would look like, not what it will look like once a second, better-funded buyer shows up for the same silicon.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://www.youtube.com/watch?v=N1bFMQqZSuQ" rel="noopener noreferrer"&gt;the original price breakdown&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>ai</category>
      <category>gaming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Colin Furze Built a Magnet Suspension Bike. Physics Made It a Pogo Stick.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Sun, 27 Sep 2026 08:17:21 +0000</pubDate>
      <link>https://dev.to/cacheline/colin-furze-built-a-magnet-suspension-bike-physics-made-it-a-pogo-stick-2m3m</link>
      <guid>https://dev.to/cacheline/colin-furze-built-a-magnet-suspension-bike-physics-made-it-a-pogo-stick-2m3m</guid>
      <description>&lt;p&gt;Two pairs of neodymium magnets, each rated to hold 500 kilograms, face each other across the frame of a bicycle. No springs. No oil. No air. That's the whole suspension system Colin Furze just &lt;a href="https://www.youtube.com/watch?v=sOf4luOmQCw" rel="noopener noreferrer"&gt;built&lt;/a&gt; — and it works, right up until the bike hits a real bump and turns into a pogo stick that won't stop bouncing.&lt;/p&gt;

&lt;h2&gt;
  
  
  A spring that never gets tired
&lt;/h2&gt;

&lt;p&gt;Push two magnets together with the same poles facing and they push back. That's the entire trick behind the bike: one magnet array on the frame, another on the fork and swingarm, all oriented to repel. Compress the "suspension" by hitting a bump, and the magnetic field pushes the wheel back down just like a coil spring would. No moving fluid, no seals to leak, no oil to change.&lt;/p&gt;

&lt;p&gt;For small, gentle bumps, this works beautifully. The magnets store the energy of the bump and hand it straight back, exactly the way a spring is supposed to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The half of suspension that magnets can't do
&lt;/h2&gt;

&lt;p&gt;Here's the problem: a spring is only half a suspension system. Every real fork or shock has two components — a spring that absorbs the bump, and a damper that bleeds off the energy afterward as heat. Springs alone don't stop oscillating; they just keep converting kinetic energy back into potential energy and back again until something else, friction or air resistance, finally kills the motion.&lt;/p&gt;

&lt;p&gt;A hydraulic damper does that job by forcing oil through a small orifice, turning the bump's energy into heat and getting rid of it. A magnetic field can't do that. There's no orifice, no friction, no way for the field itself to dissipate energy. Whatever energy goes into compressing the magnets comes right back out, at close to full strength.&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/z6QNsK5r6SA" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;Here's the 60-second version of what that looks like on the road.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it turns into a pogo stick
&lt;/h2&gt;

&lt;p&gt;Without a damper, any bump big enough to meaningfully compress the magnets doesn't just get absorbed, it gets returned, and the return overshoots, and that overshoot gets returned again. The bike keeps bouncing until ordinary friction in the frame, bearings, and tires slowly bleeds the energy away, which takes a lot longer than a damper would. Small road texture feels smooth. A pothole turns the whole bike into a pogo stick.&lt;/p&gt;

&lt;p&gt;This is close to what killed magnetic and air-only suspension concepts in the automotive world decades ago: a spring without damping isn't a suspension, it's an oscillator.&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure mode nobody wants
&lt;/h2&gt;

&lt;p&gt;There's a sharper problem hiding underneath the physics one. The whole system depends on the magnets never actually touching. If the suspension ever bottoms out hard enough for the repelling faces to get past each other, two magnets rated to hold 500 kilograms apiece will snap together at speed, with the rider's leg sitting somewhere in between. A spring that fails just goes soft. A magnet array that fails inverts from repulsion to violent attraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an actual fix would need
&lt;/h2&gt;

&lt;p&gt;None of this is unfixable, it's just missing a part. Add a hydraulic or friction damper alongside the magnets and you'd get a genuinely novel spring-by-magnetism suspension with normal ride characteristics. Rare-earth magnet springs have been explored seriously for years, mostly in vibration isolation for industrial machinery, always paired with some separate damping mechanism. Furze's build is a fun demonstration of the spring half of that idea in isolation, which is exactly why it bounces the way it does.&lt;/p&gt;

&lt;p&gt;The interesting part was never really the magnets. It's the reminder that "suspension" is two different jobs bolted together, and building a viral demo of just one of them is a great way to find out, in public, why the other one exists.&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>science</category>
      <category>discuss</category>
      <category>news</category>
    </item>
    <item>
      <title>Apple Mocked Foldables for Black Bars. Its Own iPhone Duo Has the Same One.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Sun, 27 Sep 2026 02:36:55 +0000</pubDate>
      <link>https://dev.to/cacheline/apple-mocked-foldables-for-black-bars-its-own-iphone-duo-has-the-same-one-45jp</link>
      <guid>https://dev.to/cacheline/apple-mocked-foldables-for-black-bars-its-own-iphone-duo-has-the-same-one-45jp</guid>
      <description>&lt;p&gt;Apple spent years mocking Android foldables for wasting screen space on video. Its own iPhone Duo just shipped with the identical problem: run a standard 16:9 video on the fully updated app, and about a fifth of the $1,999 display still goes black.&lt;/p&gt;

&lt;h2&gt;
  
  
  A screen shaped for paper, not video
&lt;/h2&gt;

&lt;p&gt;The iPhone Duo's inner display is 7.6 inches, unfolded into a shape close to a sheet of A4 paper. That aspect ratio is genuinely good for documents, spreadsheets, and web pages — the things Apple leaned on in every demo. It's a poor fit for the 16:9 video most people actually watch, which is exactly the flaw Apple's own executives called out in Android foldables for years.&lt;/p&gt;

&lt;p&gt;Do the math on the panel and a 16:9 video maxes out at roughly 80% of the available screen, even once an app is built correctly for the shape. The other ~20% just sits unused. On a phone that costs two grand, that's not a rounding error — it's visible in &lt;a href="https://www.youtube.com/watch?v=8C4l8O7yU7c" rel="noopener noreferrer"&gt;Apple's own launch coverage&lt;/a&gt; of the device.&lt;/p&gt;

&lt;h2&gt;
  
  
  The order things happened in
&lt;/h2&gt;

&lt;p&gt;The real story isn't the aspect ratio by itself — it's the sequence. Apple locked in the screen's physical shape long before it handed developers the tools to design around it. The SDK that lets an app detect the Duo's panel and lay out content to fill it properly only became available after the phone was already announced to the public.&lt;/p&gt;

&lt;p&gt;That leaves developers with a matter of weeks, not months, to rework layouts for an entirely new form factor. Most teams building a phone app never had to think about an A4-shaped canvas before. Retrofitting that in a few weeks, across thousands of apps, is not realistic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that means on launch day
&lt;/h2&gt;

&lt;p&gt;Without the update, an app doesn't know the Duo's screen exists — it just renders like a regular phone. On the Duo's inner display, that shows up as a normal phone-sized window floating in the middle of a much bigger panel, with black space filling the rest. Even Apple's own marketing video for the Duo shows this: a 16:9 clip playing inside letterboxing on all sides, using about 80% of the screen it's supposedly designed for.&lt;/p&gt;

&lt;p&gt;So the same complaint Apple made about Samsung and other Android foldables — awkward black bars, apps that don't understand the fold — is exactly what ships on day one of its own device, just because of a scheduling problem rather than a hardware one. iOS 27.1 is the update that's supposed to fix this on the software side, and it's the version most apps need before they can even try to fill the screen correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this keeps happening with foldables
&lt;/h2&gt;

&lt;p&gt;This isn't really an Apple-specific failure. Every foldable maker has hit the same wall: the physical screen ships on a hardware timeline, while the software that makes content look right on that screen ships on a much slower ecosystem timeline. Samsung dealt with this for years with Android apps that didn't know what to do with a square unfolded display. Google faced it with the Pixel Fold. Now Apple, despite having full control of both its hardware and software stack and years of advance warning about the exact problem it was walking into, shipped the SDK too late to matter for launch day.&lt;/p&gt;

&lt;p&gt;The lesson is less about foldables specifically and more about dependency ordering: if the thing your ecosystem needs to look correct ships after the thing it needs to look correct on, you get a launch full of black bars no matter how good the hardware is.&lt;/p&gt;

&lt;p&gt;Here's the 60-second breakdown of the aspect ratio, the missing fifth of the screen, and why the timeline made it unavoidable:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/2M29y9cmTfM" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;Worth watching next: how Samsung's own foldable app-continuity guidelines evolved over five generations of the Galaxy Fold, since that's the closest real precedent for what iPhone Duo developers are about to go through in the coming months.&lt;/p&gt;

</description>
      <category>apple</category>
      <category>ios</category>
      <category>mobile</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Sonar Found a Plane. The Internet Found the Wrong Story.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Sat, 26 Sep 2026 05:23:55 +0000</pubDate>
      <link>https://dev.to/cacheline/the-sonar-found-a-plane-the-internet-found-the-wrong-story-2203</link>
      <guid>https://dev.to/cacheline/the-sonar-found-a-plane-the-internet-found-the-wrong-story-2203</guid>
      <description>&lt;p&gt;In 2021, a California drought drained Folsom Lake low enough to expose the outline of a sunken plane, 160 feet down. Within days, newsrooms had matched it to a 56-year-old missing-persons case. The plane sitting on that lake bed was never the one everyone said it was.&lt;/p&gt;

&lt;h2&gt;
  
  
  A drought, a sonar hit, and a name that stuck
&lt;/h2&gt;

&lt;p&gt;Two people testing sonar gear on Folsom Lake picked up a clear shape on the bottom: a full-size aircraft, sitting upright in shallow water that a historic drought had pulled back. The obvious story was sitting right there. On New Year's Day, 1965, a Piper Comanche vanished from the same lake carrying three people who were never found. A sonar return, a matching location, a decades-old cold case — &lt;a href="https://www.youtube.com/watch?v=q3nD5qD758o" rel="noopener noreferrer"&gt;the story was reported&lt;/a&gt; as the discovery that finally closed it.&lt;/p&gt;

&lt;p&gt;That's the problem with a sonar image: it gives you a shape and a depth, nothing else. It can't tell you a tail number, a registration, or a date. Every other detail in that headline — the names, the year, the fact that anyone had died at all — got bolted on afterward by people who wanted the story to be true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dive that didn't match the headline
&lt;/h2&gt;

&lt;p&gt;When dive teams actually went down to the wreck, the plane wasn't the 1965 Comanche. It was the remains of a completely different aircraft, from a crash in 1986. Nobody on board that 1986 flight died. Everyone walked away from it. The plane had just been sitting in the lake for over three decades, waiting for a drought to lower the water far enough to find it.&lt;/p&gt;

&lt;p&gt;So the "56-year mystery" wasn't solved. It's still open. The three people who disappeared in 1965 are still missing, and the plane that was supposed to be the answer belongs to an entirely unrelated accident that had a happy ending.&lt;/p&gt;

&lt;p&gt;Here's the short version of how it actually played out:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/Eon370Lk-gM" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Why the mix-up is more interesting than the mystery
&lt;/h2&gt;

&lt;p&gt;The failure here isn't the sonar equipment — it did exactly what sonar is supposed to do: return a shape and a depth from underwater. The failure is everywhere else in the chain. A location that roughly matched. A shape that looked plane-sized. A decades-old cold case that was already sitting in everyone's memory, ready to be reattached to the first plausible wreck that surfaced.&lt;/p&gt;

&lt;p&gt;Nobody waited for divers before writing the ending. Families who had no connection to either crash got a story implying their case was closed. Families whose actual missing plane is still on the bottom of a lake somewhere got nothing. And the story ran everywhere anyway, because a sonar blip that "matches" a famous mystery is a much better headline than "unidentified aircraft found, cause and identity unknown, please wait for confirmation."&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual lesson for anyone reading sensor data
&lt;/h2&gt;

&lt;p&gt;If you work anywhere near sensors, imaging, or any pipeline that turns raw signal into a claim a human will act on, this is a familiar shape of mistake. A sonar return, a satellite pixel, a log line, a fingerprint match — the instrument gives you a narrow, literal fact. Everything past that fact is inference, and inference is where confidence quietly outruns evidence.&lt;/p&gt;

&lt;p&gt;The fix isn't more skepticism about sonar. It's separating "here is what the sensor measured" from "here is what we're claiming it means" before either one gets published. Folsom Lake had one of those steps skipped for about a week, and the two lakebed wrecks got their identities swapped in front of a national audience before anyone actually confirmed either one.&lt;/p&gt;

&lt;p&gt;If you want to go deeper on how identification actually works underwater, dive registries and wreck-identification case studies from maritime archaeology groups are a much better rabbit hole than the next viral sonar headline — they spend paragraphs on exactly the kind of confirmation this story skipped.&lt;/p&gt;

</description>
      <category>news</category>
      <category>discuss</category>
      <category>technology</category>
      <category>science</category>
    </item>
    <item>
      <title>What 10 years of writing code actually changes (it's not the code)</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Sat, 26 Sep 2026 03:17:16 +0000</pubDate>
      <link>https://dev.to/cacheline/what-10-years-of-writing-code-actually-changes-its-not-the-code-339c</link>
      <guid>https://dev.to/cacheline/what-10-years-of-writing-code-actually-changes-its-not-the-code-339c</guid>
      <description>&lt;p&gt;Ask sixteen experienced open-source developers how much faster AI tools would make them, and they'll say about 24%. Ask them again right after they finish the task, and they'll still swear they were roughly 20% faster. The stopwatch says otherwise: they were actually 19% slower.&lt;/p&gt;

&lt;p&gt;That gap is the headline result from a 2025 randomized controlled trial run by &lt;a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/" rel="noopener noreferrer"&gt;METR&lt;/a&gt;, a group that studies how AI systems actually perform in the wild rather than on benchmarks. Instead of testing beginners on toy problems, the study put experienced developers to work on real, mature codebases they already knew well — their own open-source repositories, with years of accumulated context already living in their heads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 39-point gap
&lt;/h2&gt;

&lt;p&gt;Here's the setup: developers picked real issues from their own projects, then were randomly assigned to either use AI tools or not for each task. Before starting, they predicted AI would cut their completion time by about 24%. After finishing, they still believed they had come out roughly 20% ahead.&lt;/p&gt;

&lt;p&gt;The actual clock time told a different story. Tasks done with AI assistance took about 19% longer than tasks done without it. That's a 39 percentage-point gap between what these developers believed happened and what a stopwatch recorded — in professionals who write code for a living.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the most experienced developers lost the most time
&lt;/h2&gt;

&lt;p&gt;The slowdown wasn't evenly spread. It was strongest on exactly the codebases the developers knew best. That's the counterintuitive part: you'd expect deep familiarity to make AI assistance additive, a second pair of hands on a system you already understand. Instead, the tool mostly added overhead — prompting, reviewing suggestions, and correcting output — layered on top of work the developer could already do quickly from memory.&lt;/p&gt;

&lt;p&gt;Ten years of shipping code builds a fast, private, mental model of a system: which functions are safe to touch, which abstractions leak, where the real bugs hide. That model runs in the background and is basically free. An AI assistant doesn't have it, so every suggestion has to be checked against it, and checking takes time the raw "assistance" never shows up as.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same illusion shows up in floating point
&lt;/h2&gt;

&lt;p&gt;There's a smaller, more mechanical version of this mismatch that any developer runs into on day one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;
&lt;span class="mf"&gt;0.30000000000000004&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing is broken. Binary floating point can't represent 0.1 or 0.2 exactly, so the addition is off by a sliver too small to notice by eye but large enough to break an equality check. The computer isn't wrong — your intuition about what "0.1 + 0.2" means is just miscalibrated against how the machine actually stores numbers.&lt;/p&gt;

&lt;p&gt;That's the same shape as the METR result. Your internal sense of speed, like your internal sense of what 0.1 plus 0.2 equals, is a model — usually good enough, occasionally confidently wrong, and only correctable by actually checking the value against a ground truth instead of trusting the feeling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually worked
&lt;/h2&gt;

&lt;p&gt;The METR study also found the developers who avoided the slowdown weren't the ones who resisted AI tools altogether. They were the ones who stopped guessing and started timing themselves — treating "does this actually help me" as a measurable question instead of a vibe.&lt;/p&gt;

&lt;p&gt;The other habit that held up: writing down &lt;em&gt;why&lt;/em&gt; the code looks the way it does, before that reasoning quietly leaves with whoever holds it in their head. A decade of experience is mostly an unwritten, unmeasured model of a system. AI tools are good at producing plausible-looking code fast; they are not a substitute for that model, and treating them as one is exactly how an experienced developer ends up slower while feeling faster.&lt;/p&gt;

&lt;p&gt;If you want to know whether a tool is actually helping you, the fix is unglamorous: time it, on your own real tasks, more than once.&lt;/p&gt;

&lt;p&gt;Here's the 60-second version of this story:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/n_1xNV4yeC8" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;If you've caught yourself feeling faster while a task actually dragged on, that's the whole study in miniature — worth checking with a clock next time before you trust the feeling.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Boston Cancelled Its License Plate Cameras. The Cameras Didn't Leave.</title>
      <dc:creator>CacheLine</dc:creator>
      <pubDate>Fri, 25 Sep 2026 21:49:20 +0000</pubDate>
      <link>https://dev.to/cacheline/boston-cancelled-its-license-plate-cameras-the-cameras-didnt-leave-5gl4</link>
      <guid>https://dev.to/cacheline/boston-cancelled-its-license-plate-cameras-the-cameras-didnt-leave-5gl4</guid>
      <description>&lt;p&gt;Boston's mayor announced in September 2026 that the city had cut ties with Flock Safety, the license-plate-reading camera vendor behind its automated surveillance network. The trigger wasn't a hack — it was a configuration setting that left Boston's plate-reader data searchable by police departments across the country, for purposes the city never approved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happened
&lt;/h2&gt;

&lt;p&gt;Flock's cameras photograph every car that passes a fixed point and log the plate, timestamp, and location. Departments that buy into the network can share that data with other agencies, and by default, Boston's data was shared far more widely than city officials realized. Once the configuration was flagged, Flock closed the hole. But there was no audit trail showing who had already run searches against Boston's plates, and the underlying records had already rolled off after their standard 30-day retention window. Boston residents didn't learn any of this until roughly seventeen months after the exposure happened.&lt;/p&gt;

&lt;p&gt;Automated plate readers are attractive to departments precisely because they're cheap and passive: no officer has to run a plate manually, the system just logs everything and lets anyone with access search it later. That convenience is also the entire privacy problem — the system doesn't know the difference between "investigating a stolen vehicle" and "checking where an ex-partner parks."&lt;/p&gt;

&lt;h2&gt;
  
  
  Cancelling the vendor didn't turn the cameras off
&lt;/h2&gt;

&lt;p&gt;This is the part that got buried under the "city bans surveillance cameras" headline: the Boston Police Department had already installed 75 license-plate cameras from other vendors, Motorola and Axon, before the Flock cancellation was even announced. The plate reading didn't stop. The logo on the camera changed.&lt;/p&gt;

&lt;p&gt;Public records showed around 11,000 searches against the plate database in five months. About half of them carried no case number at all, meaning there's no record of what investigation, if any, justified the lookup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real risk was never the vendor
&lt;/h2&gt;

&lt;p&gt;Swapping Flock for Motorola doesn't fix the actual failure mode: a plate-reader network is only as trustworthy as every individual officer who has a login. Nationally, hundreds of officers have been formally accused of running plate or database searches for personal reasons — checking on an ex, a neighbor, a family member — with no case attached. A vendor swap doesn't touch that. Neither does a press release announcing the old contract is gone.&lt;/p&gt;

&lt;p&gt;Here's the 60-second version:&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/OVhc6Br7Slw" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  What to actually watch for
&lt;/h2&gt;

&lt;p&gt;If your city announces it's "ending" a surveillance camera contract, the headline question isn't which vendor got fired. It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the hardware actually come down, or just get relabeled under a new vendor?&lt;/li&gt;
&lt;li&gt;Is there an audit log tied to every search, with a mandatory case number?&lt;/li&gt;
&lt;li&gt;How long is data retained, and who can still pull it before it expires?&lt;/li&gt;
&lt;li&gt;Is oversight independent of the department running the cameras?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Boston's story is a clean case study because the paper trail is public: a Flock misconfiguration, a fix with no accountability for prior access, a 30-day retention window that erased the evidence before anyone could audit it, and a quiet buildout of a replacement network using different hardware from the same playbook. None of the incentives changed. Only the branding did.&lt;/p&gt;

&lt;p&gt;If you want to go deeper, UFD Tech's coverage is what originally surfaced the Boston details referenced above: &lt;a href="https://www.youtube.com/watch?v=BXDzO9YWGbI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=BXDzO9YWGbI&lt;/a&gt;. Worth checking next: how your own city handles public-records requests for plate-reader search logs. Some departments publish them by default; most don't, and that gap is where accountability quietly dies.&lt;/p&gt;

</description>
      <category>security</category>
      <category>privacy</category>
      <category>discuss</category>
      <category>news</category>
    </item>
  </channel>
</rss>
