<?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: frank chu</title>
    <description>The latest articles on DEV Community by frank chu (@frankchu).</description>
    <link>https://dev.to/frankchu</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%2F4039145%2F88cac5e7-d445-4b8b-b95a-9c9131ec6eb8.png</url>
      <title>DEV Community: frank chu</title>
      <link>https://dev.to/frankchu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/frankchu"/>
    <language>en</language>
    <item>
      <title>malloc did 1,000 allocations with 1 syscall</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Tue, 10 Nov 2026 00:44:08 +0000</pubDate>
      <link>https://dev.to/frankchu/malloc-did-1000-allocations-with-1-syscall-5e42</link>
      <guid>https://dev.to/frankchu/malloc-did-1000-allocations-with-1-syscall-5e42</guid>
      <description>&lt;h1&gt;
  
  
  malloc did 1,000 allocations with 1 syscall
&lt;/h1&gt;

&lt;p&gt;One &lt;code&gt;brk&lt;/code&gt; syscall grew my heap by 132 KiB and served all 1,000 &lt;code&gt;malloc(16)&lt;/code&gt; calls. The same program, compiled the way I first wrote it, made zero heap syscalls at all — because GCC deleted every allocation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The re-run
&lt;/h2&gt;

&lt;p&gt;Ben Andrew's "What is malloc doing, anyway?" hit Hacker News today (213 points), and it is a beautiful piece of measurement: &lt;code&gt;strace&lt;/code&gt; the syscalls, read the chunk headers, time the calls, build a toy allocator stage by stage. I re-ran his numbers on my own machine — Ubuntu, glibc 2.39, 4 vCPUs — to see which of them are universal and which are his machine. Most of them held exactly. One of them did not, and the reason is the most interesting part.&lt;/p&gt;

&lt;h2&gt;
  
  
  1,000 mallocs, 1 syscall
&lt;/h2&gt;

&lt;p&gt;His program: &lt;code&gt;malloc(16)&lt;/code&gt; a thousand times into a static array. His &lt;code&gt;strace&lt;/code&gt; showed two &lt;code&gt;brk&lt;/code&gt; calls — one to ask where the break is, one to grow the heap by 132 KiB. Mine showed the same shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brk(NULL)                 = 0x59362db06000
brk(0x59362db27000)       = 0x59362db27000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The growth is &lt;code&gt;0x21000&lt;/code&gt; bytes — 135,168, exactly 132 KiB. Same number, different machine, different glibc. The other 999 allocations never touch the kernel; they carve slices out of that one block. That is the whole point of a userspace allocator, and it is reassuring that the number is stable across machines: glibc's main arena grabs 132 KiB on first use and deals from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The chunk headers match to the byte
&lt;/h2&gt;

&lt;p&gt;Reading the size word stored just before each returned pointer, glibc's chunk layout is identical on my build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  request    chunk
        1       32
       24       32
       25       48
     1000     1008
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request plus 8 bytes of header, rounded up to a multiple of 16, minimum 32. His table is byte-for-byte the same. This is the part of malloc that never changes: the rounding rule is load-bearing for alignment, and every glibc you meet will print this table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where my numbers diverge: the syscall cost
&lt;/h2&gt;

&lt;p&gt;Timed over a million calls each:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syscall(getppid)    496.0 ns    (his: 575.2 ns)
sbrk(16)            517.6 ns    (his: 610.1 ns)
malloc(16)           58.9 ns    (his:  26.9 ns)
sbrk/malloc           8.8x       (his:  22.7x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The syscalls are cheaper on my VM than on his machine; &lt;code&gt;malloc&lt;/code&gt; is more than twice as &lt;em&gt;slow&lt;/em&gt; — 58.9 ns against his 26.9. So the ratio collapses from 22.7x to 8.8x. The lesson is not that one of us is wrong: syscall latency and allocator latency move independently with CPU, virtualization, and spectre mitigations. The ratio is a property of a machine, not of malloc. If you quote "malloc is 20x cheaper than a syscall," quote the machine it was measured on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mmap threshold is exactly 128 KiB
&lt;/h2&gt;

&lt;p&gt;Allocations above glibc's &lt;code&gt;mmap&lt;/code&gt; threshold bypass the heap and get their own mapping. I probed either side of the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;120 KiB malloc -&amp;gt; no mmap; served from the brk heap
132 KiB malloc -&amp;gt; mmap(NULL, 139264, ...)   (132 KiB + overhead)
  1 MiB malloc -&amp;gt; mmap(NULL, 1052672, ...)  (1 MiB + overhead)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;120 KiB stays on the heap; 132 KiB gets its own anonymous mapping, which is also why freeing a large block returns memory to the kernel immediately while freeing a small one does not. The default threshold is 128 KiB and it is a live, observable boundary, not folklore.&lt;/p&gt;

&lt;h2&gt;
  
  
  The compiler deleted my benchmark
&lt;/h2&gt;

&lt;p&gt;Here is the part I did not expect. My first build of the 1,000-malloc program showed &lt;em&gt;one&lt;/em&gt; &lt;code&gt;brk&lt;/code&gt; call — a query, no growth — and the 1 MB program showed no large &lt;code&gt;mmap&lt;/code&gt; at all. &lt;code&gt;objdump&lt;/code&gt; explained it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ objdump -d m1m | grep -c "call.*malloc"
0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GCC at &lt;code&gt;-O2&lt;/code&gt; had removed every &lt;code&gt;malloc&lt;/code&gt; call. The pointers went into a static array that nothing ever read, so the compiler proved the allocations unobservable and deleted them — &lt;code&gt;malloc&lt;/code&gt; is annotated in a way that permits this. The fix was to make the pointers escape: store them in a global array, touch a byte in each block, print a checksum. Only then did the syscalls appear. If you have ever benchmarked an allocator and gotten suspiciously fast numbers, check whether the compiler ran your benchmark at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  One thing he didn't measure: thread contention
&lt;/h2&gt;

&lt;p&gt;The post is single-threaded throughout. glibc's answer to multithreaded malloc is per-thread arenas, so I measured 2M &lt;code&gt;malloc(16)&lt;/code&gt;/&lt;code&gt;free&lt;/code&gt; pairs per thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;threads   aggregate throughput
1         60.2 Mops/s  (16.6 ns/op)
2        113.3 Mops/s   (8.8 ns/op)
3        169.0 Mops/s   (5.9 ns/op)
4         91.6 Mops/s  (10.9 ns/op)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scaling is nearly linear to 3 threads — the arenas are doing their job, and the per-op cost here is the tcache fast path, which is why single-threaded numbers look absurdly small. At 4 threads throughput falls off a cliff, from 169 to 92 Mops/s. That is 4 workers plus the main thread on 4 vCPUs: the moment threads outnumber cores, arena isolation stops helping and scheduling takes over. The allocator scales until the machine doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scoreboard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;claim&lt;/th&gt;
&lt;th&gt;his machine&lt;/th&gt;
&lt;th&gt;my machine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;heap growth for 1,000 x malloc(16)&lt;/td&gt;
&lt;td&gt;132 KiB, 2 brk calls&lt;/td&gt;
&lt;td&gt;132 KiB, 2 brk calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chunk for request 1 / 24 / 25 / 1000&lt;/td&gt;
&lt;td&gt;32 / 32 / 48 / 1008&lt;/td&gt;
&lt;td&gt;32 / 32 / 48 / 1008&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;empty syscall&lt;/td&gt;
&lt;td&gt;575.2 ns&lt;/td&gt;
&lt;td&gt;496.0 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sbrk(16)&lt;/td&gt;
&lt;td&gt;610.1 ns&lt;/td&gt;
&lt;td&gt;517.6 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;malloc(16)&lt;/td&gt;
&lt;td&gt;26.9 ns&lt;/td&gt;
&lt;td&gt;58.9 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sbrk / malloc&lt;/td&gt;
&lt;td&gt;22.7x&lt;/td&gt;
&lt;td&gt;8.8x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mmap threshold&lt;/td&gt;
&lt;td&gt;(not measured)&lt;/td&gt;
&lt;td&gt;128 KiB, confirmed at 120 vs 132 KiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The structural numbers — the 132 KiB grab, the chunk rounding, the 128 KiB threshold — reproduce exactly. The timing numbers don't, and they shouldn't: those belong to the machine. Re-running someone else's measurement is worth doing precisely because it tells you which half is which.&lt;/p&gt;

&lt;p&gt;Sources: Ben M. Andrew, "What is malloc doing, anyway?", benmandrew.com (Hacker News, November 9, 2026, 213 points). All "my machine" numbers measured on this VM: Ubuntu, glibc 2.39, 4 vCPUs, GCC 12+ at -O2. &lt;code&gt;strace&lt;/code&gt; traces and C sources are mine; the demand-paging and toy-allocator sections of the original post were not re-run.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>c</category>
      <category>performance</category>
      <category>discuss</category>
    </item>
    <item>
      <title>10x faster k-means? I re-ran it and got 1.5x</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Tue, 10 Nov 2026 00:43:03 +0000</pubDate>
      <link>https://dev.to/frankchu/10x-faster-k-means-i-re-ran-it-and-got-15x-24bb</link>
      <guid>https://dev.to/frankchu/10x-faster-k-means-i-re-ran-it-and-got-15x-24bb</guid>
      <description>&lt;h1&gt;
  
  
  10x faster k-means? I re-ran it and got 1.5x
&lt;/h1&gt;

&lt;p&gt;e-means promises 10x faster k-means at equal loss. My reimplementation, built from their published update rule, got 1.5x faster and 1.4% worse loss — and the code their blog links to returns a 404.&lt;/p&gt;

&lt;h2&gt;
  
  
  What e-means claims
&lt;/h2&gt;

&lt;p&gt;The post went up on Hacker News today (251 points): e-means, from Meta FAIR researchers, replaces Lloyd's full-batch updates with mini-batch exponential moving averages. The headline numbers are big: 10–45x wall-clock reduction on GPU against Flash-KMeans, 8–15x on CPU against Faiss, and 1.6 to 2.4 epochs to reach the test loss Lloyd's algorithm reaches in 25. The paper is arXiv:2611.09501, and the blog is unusually specific about the method — it prints the exact update rule and the fitted scaling laws for batch size and step size. That specificity is what made it testable.&lt;/p&gt;

&lt;p&gt;One problem first: the blog's code link points to &lt;code&gt;faiss/contrib/e_means&lt;/code&gt;. As of today that path 404s on GitHub, and &lt;code&gt;faiss-cpu 1.15.1&lt;/code&gt; — the latest pip release — has no &lt;code&gt;e_means&lt;/code&gt; module. The code is not shippable yet. So I reimplemented the published rule myself in NumPy, using their scaling-law constants verbatim:&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="c1"&gt;# the e-means update, from the blog&lt;/span&gt;
&lt;span class="nc"&gt;S_j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;S_j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_j&lt;/span&gt;
&lt;span class="nc"&gt;N_j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;N_j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n_j&lt;/span&gt;
&lt;span class="n"&gt;c_j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;S_j&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;N_j&lt;/span&gt;

&lt;span class="c1"&gt;# scaling laws, default law (blog table)&lt;/span&gt;
&lt;span class="no"&gt;B&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.035&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mf"&gt;0.13&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mf"&gt;0.88&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mf"&gt;0.81&lt;/span&gt;
&lt;span class="n"&gt;a0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.824&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;**-&lt;/span&gt;&lt;span class="mf"&gt;0.46&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mf"&gt;0.90&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;**-&lt;/span&gt;&lt;span class="mf"&gt;0.45&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;**-&lt;/span&gt;&lt;span class="mf"&gt;0.11&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus cosine decay of &lt;code&gt;a&lt;/code&gt; from &lt;code&gt;a0&lt;/code&gt; down to &lt;code&gt;0.1*a0&lt;/code&gt;, and the finalization step the blog describes: end on each cluster's exact last-epoch mean. That is the whole algorithm as published. The baseline is Faiss &lt;code&gt;Kmeans&lt;/code&gt; (Lloyd), 25 iterations, same data, same random-point initialization, same machine: a 4-vCPU VM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiment 1: 100,000 points, 128 dims, 1,024 clusters
&lt;/h2&gt;

&lt;p&gt;Synthetic Gaussian blobs — 64 clusters of structure, the kind of data where Lloyd converges fast and there is little room to beat it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lloyd 25 iters: 18.7s  final MSE=121.7232
e-means (my impl) 5 epochs: 12.4s  B=7972 a0=0.5197
  per-epoch MSE: [124.6628, 124.4564, 123.9563, 123.604, 123.5087, 123.4541]
  final MSE=123.4541  vs Lloyd 121.7232 (+1.42%)
  wall-clock speedup vs Lloyd-25: 1.51x
  e-means did NOT beat Lloyd-25 MSE within 5 epochs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.5x, not 10x — and 1.4% worse loss, not equal. Two things cut against the headline here. First, my data is Lloyd-friendly: well-separated blobs, where 25 full Lloyd passes are cheap (Faiss does them in 18.7 seconds). The paper's 8–15x CPU number is measured on real embedding datasets (DEEP, SIFT, VIBE) at 1M–100M points with k up to 65,536, where a full Lloyd pass is the expensive part. Second, my implementation is NumPy plus a Faiss index rebuilt per mini-batch — no fused kernels, which is where the paper says the epoch savings turn into wall-clock savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiment 2: structureless embeddings, where Lloyd should suffer
&lt;/h2&gt;

&lt;p&gt;Random normalized vectors, n=50,000, d=256, k=1,024 — no cluster structure at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lloyd 25 iters: 10.7s  MSE=0.9248
e-means T=5: 10.4s B=4331 a0=0.410
  per-epoch MSE=[0.9396, 0.9417, 0.9387, 0.936, 0.9352, 0.9347]
  final 0.9347 vs Lloyd 0.9248 (+1.07%)  speedup 1.03x
e-means T=10: 16.8s B=7594 a0=0.630
  final 0.9380 vs Lloyd 0.9248 (+1.43%)  speedup 0.64x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No structure, no win: 1.03x at 5 epochs, and giving it 10 epochs made it &lt;em&gt;slower and worse&lt;/em&gt; (0.64x, +1.43%). The scaling law grows the batch with T, so the 10-epoch run takes fewer, larger steps — and on structureless data the EMA just smears. This is the regime the paper never claims: its datasets are real embeddings with real cluster structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiment 3: the toy local-minima test — where I first got it wrong
&lt;/h2&gt;

&lt;p&gt;The blog's most checkable claim is a toy: two blobs of very different sizes (900 vs 100 points), k=8, 200 random starts. Lloyd stays stuck in the pathological configuration — two centroids on the small blob, the large blob short — on 26% of starts; e-means on 3.5%.&lt;/p&gt;

&lt;p&gt;My first attempt reproduced nothing: Lloyd stuck 0%, e-means stuck 72%. The bug was mine, twice over. I had initialized from random &lt;em&gt;data points&lt;/em&gt; (which puts every centroid on a real blob, so Lloyd almost never gets trapped) and I had skipped the dead-cluster revival the paper explicitly calls out. Fixing both — random-vector initialization, as the paper's figures use, plus revival by proportional split (sample a live cluster with probability proportional to its size, split it in two) — flipped the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;revive=False: Lloyd stuck 12.0%, e-means stuck 49.0%,
              mean MSE Lloyd 0.5934 vs e-means 0.6271 (+5.68%)
revive=True:  Lloyd stuck 25.5%, e-means stuck 14.0%,
              mean MSE Lloyd 0.5934 vs e-means 0.5909 (-0.43%)
blog claimed: Lloyd stuck 26%, e-means 3.5%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lloyd's 25.5% against the claimed 26% is a clean reproduction. My e-means stuck rate (14.0%) is the same direction as the claimed 3.5% but weaker — fair warning on my side: my revival is a rough approximation of theirs, and my "stuck" is a proxy (more than 1% worse than the better of the two runs for that seed), not their exact pathological-configuration definition. Even so, the mean MSE flips sign once revival is in: e-means goes from +5.68% worse to -0.43% better.&lt;/p&gt;

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

&lt;p&gt;The headline 10x is a regime claim, not a universal one. It holds where Lloyd's full passes are the bottleneck — large k, real embeddings, GPU kernels — and it depends on the components the paper flags as essential. The toy experiment is the proof of that dependence: the same EMA update rule, without dead-cluster revival, is &lt;em&gt;worse&lt;/em&gt; than Lloyd on the authors' own toy (49% stuck vs 12%). With revival, it beats Lloyd. The update rule is not the algorithm. The initialization, the revival, and the finalization are load-bearing, and a reimplementation that skips them measures a different method.&lt;/p&gt;

&lt;p&gt;Two honest caveats. First, this is my reimplementation of a published rule, not the authors' code — which is not publicly available yet, despite the blog's link. Second, my datasets are synthetic and small; the paper's numbers come from 24 datasets up to 100M points. The 10x may well be real at that scale. But at the scale most of us actually cluster at — 100k points, k in the low thousands, on a CPU — what I measured is 1.5x and slightly worse loss, and the toy result only reproduces once you implement the parts that are easy to skip.&lt;/p&gt;

&lt;p&gt;Sources: e-means blog, e-means.github.io (Hacker News, November 9, 2026); arXiv:2611.09501, "e-means: outperforming k-means (in one-tenth the epochs)"; GitHub API check on facebookresearch/faiss &lt;code&gt;faiss/contrib/e_means&lt;/code&gt; (404, November 9, 2026); faiss-cpu 1.15.1. All timings measured on this machine (4 vCPU VM): Faiss Kmeans vs my NumPy reimplementation, same initialization, same data.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>machinelearning</category>
      <category>clustering</category>
      <category>discuss</category>
    </item>
    <item>
      <title>$3.4B bought Anthropic 1.7 GW of gas turbines</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 17:59:27 +0000</pubDate>
      <link>https://dev.to/frankchu/34b-bought-anthropic-17-gw-of-gas-turbines-2ce2</link>
      <guid>https://dev.to/frankchu/34b-bought-anthropic-17-gw-of-gas-turbines-2ce2</guid>
      <description>&lt;h1&gt;
  
  
  $3.4B bought Anthropic 1.7 GW of gas turbines
&lt;/h1&gt;

&lt;p&gt;Anthropic just spent $3.4 billion on natural gas turbines — $2,000 per kilowatt for 1.7 gigawatts of generation it will own outright. For a company that has always rented its compute, that is not a power purchase. It is a confession that renting stopped working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was reported
&lt;/h2&gt;

&lt;p&gt;The Financial Times reported on November 8 that Anthropic agreed in late September to pay about $3.4 billion for 1.7 gigawatts of heavy-duty gas-fired generators from OnePWR Solutions, a San Antonio equipment supplier. The FT called it the largest known single purchase of power-generation equipment by an AI lab.&lt;/p&gt;

&lt;p&gt;The mechanics matter more than the headline. OnePWR ordered the Caterpillar generators about two years ago but could not find financing to complete the purchase. Anthropic originally planned to be OnePWR's customer and buy the electricity. Instead it took over the equipment orders directly — plus the engineering and construction capability to install them. It did not buy OnePWR itself, and none of OnePWR's employees moved over.&lt;/p&gt;

&lt;p&gt;Two honesty notes before the math. First, neither Anthropic nor OnePWR commented, and Reuters said it could not independently verify the FT report. Second, there is one independent anchor: investment bank Piper Sandler, which advised OnePWR, lists the transaction on its own site as a $3.4 billion sell-side deal — the sale of OnePWR's "power generation platform to a frontier AI lab." That corroborates the price and the shape of the deal, if not every detail of the FT's account.&lt;/p&gt;

&lt;h2&gt;
  
  
  The arithmetic
&lt;/h2&gt;

&lt;p&gt;I ran the numbers against Anthropic's own filings, and the purchase looks small until you compare it to the right denominator:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;$2,000 per kilowatt.&lt;/strong&gt; $3.4 billion divided by 1.7 gigawatts. That is the price of a delivery slot in a supply book that is already sold out — the backlog for gas turbines stretches into the early 2030s, and grid-connection queues run just as long.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.72 months of rent.&lt;/strong&gt; Anthropic disclosed in its S-1 that it pays xAI $1.25 billion per month through May 2029 for compute. This purchase costs less than three months of that rent — and buys hardware it owns instead of hours it borrows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;20% of a quarter's revenue, 34.5% of a quarter's compute.&lt;/strong&gt; Q3 revenue was $17.0 billion; Q3 compute and infrastructure spend was about $9.86 billion, 58% of revenue. The turbines are one-third of a single quarter's compute bill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0.38% of the commitments.&lt;/strong&gt; Anthropic's amended S-1, filed November 2, disclosed about $895.4 billion in total purchase and lease commitments, with roughly $69.8 billion due in the next twelve months. The $3.4 billion is 4.9% of that twelve-month slice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.7x a nuclear reactor.&lt;/strong&gt; A typical large nuclear reactor produces about 1 gigawatt. Anthropic just bought the generating capacity of nearly two of them, in gas form.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is not that $3.4 billion is large. Against $895.4 billion of commitments, it is a rounding error. The point is what it buys: queue position. Anthropic did not buy electricity. It bought factory-order slots placed two years ago, because ordering today means waiting until the early 2030s.&lt;/p&gt;

&lt;h2&gt;
  
  
  The S-1 warned about exactly this — last week
&lt;/h2&gt;

&lt;p&gt;Here is the detail that makes the story stick. Anthropic's amended S-1, filed November 2, added a specific warning for prospective shareholders: its third-party infrastructure partners depend on outside financing to build the facilities Anthropic has contracted to rent, and if those partners fail to raise the money, the capacity could be delayed, repriced, reduced, or never delivered.&lt;/p&gt;

&lt;p&gt;Within a week, that risk factor showed up on a flatbed truck. OnePWR — a third-party infrastructure partner — could not raise the financing. Anthropic's answer was to stop being a customer and become the owner, putting up $3.4 billion in cash commitments to rescue the delivery schedule.&lt;/p&gt;

&lt;p&gt;That is a flip of the company's entire posture. The same S-1 says Anthropic expects "to enter into additional similar services contracts" — more renting. Now it is buying generation hardware outright. When your risk factor materializes in seven days, the strategy changes in seven days.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gas bet has two edges
&lt;/h2&gt;

&lt;p&gt;Anthropic is not alone in this. Google, Amazon, Microsoft, and Meta have all announced plans to build massive on-site gas plants rather than draw from the public grid. The industry has decided that waiting for the grid is the bigger risk.&lt;/p&gt;

&lt;p&gt;But gas has its own price. TechCrunch notes one analyst expects gas prices could more than triple by the end of the decade in some markets. And the permitting fight is already here: on October 30, a federal judge ruled xAI's 35 gas turbines at its Memphis-area site are not "mobile sources" under Mississippi's clean-air rules — the trailer loophole is dead, and I wrote about that ruling last week. Anthropic's 1.7 gigawatts will need permits too, and nobody has said where the generators will go or when they will run.&lt;/p&gt;

&lt;p&gt;So the honest read is this: Anthropic paid $3.4 billion to convert a financing risk into a fuel-price risk and a permitting risk. That is still a good trade when the alternative is no power at all. But it is a trade, not a solution — and the company that just told IPO investors its suppliers might not be able to finance their promises is now the one writing the checks.&lt;/p&gt;

&lt;p&gt;Sources: Financial Times, November 8, 2026 (via TechCrunch, "Anthropic joins AI's natural gas frenzy, buys $3.4B worth of turbines," November 9, 2026; Reuters, November 8, 2026; CNBC); Piper Sandler transaction listing (OnePWR power generation platform sale, $3.4 billion); Anthropic amended Form S-1/A, filed November 2, 2026 (Q3 revenue $17.0 billion, Q3 compute spend ~$9.86 billion, $895.4 billion total commitments, $69.8 billion due within twelve months, $1.25 billion/month xAI agreement through May 2029). The FT report has not been independently verified by Reuters; Anthropic and OnePWR declined to comment. Deployment locations and operating schedules are undisclosed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>anthropic</category>
      <category>datacenters</category>
      <category>discuss</category>
    </item>
    <item>
      <title>NHTSA: most Waymo school-bus passes came after the fix</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 15:30:18 +0000</pubDate>
      <link>https://dev.to/frankchu/nhtsa-most-waymo-school-bus-passes-came-after-the-fix-8d</link>
      <guid>https://dev.to/frankchu/nhtsa-most-waymo-school-bus-passes-came-after-the-fix-8d</guid>
      <description>&lt;h1&gt;
  
  
  NHTSA: most Waymo school-bus passes came after the fix
&lt;/h1&gt;

&lt;p&gt;NHTSA opened a recall query covering 2,895 Waymo vehicles on November 6. A majority of the reported school-bus passes happened after Waymo said its software fix was fully deployed on November 17, 2025.&lt;/p&gt;

&lt;p&gt;That is the whole story in two sentences, and it is worse than it sounds. The fix was the recall. The recall was supposed to be the end of it. Eleven months later, the federal regulator is formally asking whether the fix did anything at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What NHTSA actually filed
&lt;/h2&gt;

&lt;p&gt;I read the primary document, not just the coverage. NHTSA's Office of Defects Investigation published the resume for investigation RQ26006 on November 6, 2026. The facts, straight from it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Population:&lt;/strong&gt; 2,895 vehicles running Waymo's 5th-generation automated driving system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The original recall:&lt;/strong&gt; Waymo filed recall 25E084 on December 10, 2025, for a defect that could cause its vehicles to pass a stopped school bus with flashing red lights or an extended stop arm, after initially slowing or stopping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The remedy:&lt;/strong&gt; a software update that Waymo said was completed for all affected vehicles on November 17, 2025.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The problem:&lt;/strong&gt; "Of the total reported incidents identified during PE25013, a majority of the incidents occurred after the November 17, 2025 remedy date."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The action:&lt;/strong&gt; NHTSA opened the recall query "to assess the adequacy of the remedy for Recall 25E084 and to identify the cause(s) of the conditions leading to the post-remedy reports."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reuters first reported the filing on Monday, November 9. TechCrunch, Morningstar/Dow Jones, and Seeking Alpha all confirmed the same day. The story checks out.&lt;/p&gt;

&lt;p&gt;A recall query is not a recall. It is the step before one — the regulator saying, in effect, "you told us this was fixed, and our data says otherwise, so prove it." It can lead to a second recall.&lt;/p&gt;

&lt;h2&gt;
  
  
  The timeline is the indictment
&lt;/h2&gt;

&lt;p&gt;Run the dates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;October 2025:&lt;/strong&gt; NHTSA opens preliminary investigation PE25013 after footage shows a Waymo robotaxi maneuvering around a stopped school bus in Atlanta — crossing perpendicularly in front of the bus, then turning left around it, while the bus was unloading children with its stop sign extended and lights flashing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 17, 2025:&lt;/strong&gt; Waymo says the software remedy is complete on all affected vehicles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;December 10, 2025:&lt;/strong&gt; Waymo formally files recall 25E084 — 23 days &lt;em&gt;after&lt;/em&gt; it says the fix was already deployed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 6, 2026:&lt;/strong&gt; NHTSA opens RQ26006 — 354 days after the fix was declared complete — because most of the violations happened after that date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That 23-day inversion is the detail that sticks with me. The fix went out before the recall was filed. The recall, in other words, was paperwork ratifying a software push that had already happened. And the software push, per NHTSA's own count, did not stop the behavior it was meant to stop.&lt;/p&gt;

&lt;p&gt;Austin Independent School District reported at least five such incidents at the time, according to a letter filed with NHTSA. The National Transportation Safety Board separately documented a January 12 incident in Austin in which a Waymo vehicle initially stopped for a school bus, then proceeded while the stop arms were still extended — six vehicles passed the bus; no crash occurred. NHTSA's resume lists 8 incident reports in its summary, with crash and injury counts marked confidential.&lt;/p&gt;

&lt;p&gt;There is also a separate, still-open probe from January, after one of Waymo's vehicles struck a child near an elementary school in Santa Monica. That is a different investigation, but it is the same file drawer: children, school zones, and a system that was supposed to have learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verification problem with software recalls
&lt;/h2&gt;

&lt;p&gt;Here is the engineering question this story actually raises, and it is not "are robotaxis safe." It is: &lt;strong&gt;how does anyone verify a software fix for a behavior that only shows up at the edge?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A school bus with flashing red lights and an extended stop arm is a rare, high-stakes, highly specific scene. It is exactly the kind of scenario a fleet validates in simulation and in staged testing — and exactly the kind where simulation and the street diverge. Waymo's fix presumably passed whatever validation gate Waymo set for it. Then the fleet kept doing the thing, in Austin and Atlanta, in front of school districts that count violations and file letters.&lt;/p&gt;

&lt;p&gt;This is the structural weakness of the software-update-as-recall model. With a hardware recall, the remedy is observable: a part is replaced, a dealer stamps a form. With a software recall, the remedy is a claim — "deployed to all affected vehicles on November 17" — and the only independent check is waiting to see whether the behavior recurs. NHTSA waited. It recurred. That is what a recall query is: the regulator discovering, a year later, that the verification loop was "ship it and watch."&lt;/p&gt;

&lt;p&gt;The honest gap in the data is worth stating plainly. NHTSA says "a majority" of incidents came after the fix, but the resume does not publish the total incident count. "Majority" could mean 6 of 11 or 60 of 100, and those are very different fleets. The regulator knows the denominator; it has not shared it. Until it does, the precise failure rate is unconfirmed — but the direction is not. A fix that worked would produce zero post-remedy incidents, not a majority.&lt;/p&gt;

&lt;p&gt;One more number for scale: the query covers 2,895 vehicles out of the 3,067 in the original recall — 94.4% of the recalled fleet is back under investigation. Waymo was valued at $126 billion in February. The company has not yet responded to TechCrunch's request for comment, and neither has Austin ISD.&lt;/p&gt;

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

&lt;p&gt;The query has two stated jobs: assess whether the remedy was adequate, and identify what caused the post-remedy reports. The second one is the interesting one. If the cause is a perception miss — the system not reliably detecting a stop arm — that is one kind of fix. If the cause is a planning decision — the system detecting the bus and choosing to proceed anyway — that is a much more serious one, because it means the "fix" tuned a behavior the stack still considers acceptable in some conditions.&lt;/p&gt;

&lt;p&gt;Either way, the precedent matters beyond Waymo. Every AV operator now recalls by software push. If the first major test of that model ends with the regulator reopening the case a year later because the fix did not take, the next software recall will not be taken on the manufacturer's word. Expect NHTSA to start asking for the validation evidence up front — the test matrix, the pass criteria, the field monitoring plan — before accepting "deployed to all vehicles" as a remedy.&lt;/p&gt;

&lt;p&gt;The fix was the fix. It did not fix it. That is the story.&lt;/p&gt;

&lt;p&gt;Sources: NHTSA ODI Resume, Investigation RQ26006, opened November 6, 2026 (static.nhtsa.gov); TechCrunch, "Waymo robotaxis kept illegally passing school buses after software fix, feds say," November 9, 2026; Reuters, "US opens probe into Waymo vehicles over school bus safety violations," November 9, 2026; Morningstar/Dow Jones, November 9, 2026. The NTSB Austin incident and Austin ISD figures are as reported by TechCrunch and secondary coverage. Waymo and Austin ISD had not responded to TechCrunch's comment request at publication time. A recall query is an investigation into a prior remedy, not a new recall or a final finding of defect.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>waymo</category>
      <category>robotics</category>
      <category>discuss</category>
    </item>
    <item>
      <title>12,000 engineers kept Claude Code. Bankers lost it</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 15:06:15 +0000</pubDate>
      <link>https://dev.to/frankchu/12000-engineers-kept-claude-code-bankers-lost-it-2ala</link>
      <guid>https://dev.to/frankchu/12000-engineers-kept-claude-code-bankers-lost-it-2ala</guid>
      <description>&lt;h1&gt;
  
  
  12,000 engineers kept Claude Code. Bankers lost it
&lt;/h1&gt;

&lt;p&gt;Goldman Sachs restricted Claude Code and GitHub Copilot to its roughly 12,000 engineers in October, ending months of banker and trader "vibe coding" — and the bank announced it four days after a backdoored Claude Code extension reached up to 5,000 Cursor users. The bank's stated reason was "productivity and risk management." The calendar says which half did the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goldman actually did
&lt;/h2&gt;

&lt;p&gt;Bloomberg reported on November 2, 2026 that internal guidance updated in October limits Anthropic's Claude Code and Microsoft's GitHub coding tools to Goldman's engineers. Traders, bankers, and most other staff lost access to tools they'd been using for months — to monitor client trading flows, build analytical material, and model changes in markets and positions. One group kept access besides the engineers: the "strats," Goldman's hybrid quant-researchers who write production code as part of the job.&lt;/p&gt;

&lt;p&gt;Goldman spokesperson Nick Carcaterra framed it as the end of an experiment, not a retreat: "After a period of experimentation where we assess a variety of factors including productivity and risk management, we put them in the hands of those who are best suited to leverage them for the long term."&lt;/p&gt;

&lt;p&gt;That is a careful sentence, and the careful word is "experimentation." In July 2026, Goldman CIO Marco Argenti was publicly praising the opposite arrangement — a trader or asset manager gets an idea, builds a quick prototype with AI, and hands it to one of the bank's engineers to scale for production. Three months later, the prototype stage itself was restricted to engineers. The bank didn't say the tools failed. It said the wrong people were holding them.&lt;/p&gt;

&lt;p&gt;This wasn't Goldman's first AI restriction of the year, either. In April, it removed Claude from its internal AI platform for bankers in Hong Kong, after determining its agreement with Anthropic didn't cover use in the territory. The April restriction was about location and contract terms. The October one is about role: who is allowed to produce code, not where they sit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four days earlier, the same tool was poisoned
&lt;/h2&gt;

&lt;p&gt;On October 29, 2026, tampered builds of Anthropic's Claude Code extension — versions 2.1.312 and 2.1.313 for Windows and macOS — sat in Cursor's extension marketplace for about 11 hours, from roughly 2:27am to 1:35pm PT. Cursor says at most 5,000 users received them. The payload appended an attacker SSH key labeled &lt;code&gt;svc-telemetry&lt;/code&gt; to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;, installed persistence that survives uninstalling the extension, and tried to open a reverse SSH tunnel to 134.209.82.225. A clean 2.1.314 shipped on October 30. Anthropic says it neither built nor published the tampered versions; Cursor took the marketplace offline, rotated keys, and rebuilt it.&lt;/p&gt;

&lt;p&gt;I am not claiming the incident caused Goldman's decision — the guidance was updated in October, and Bloomberg reported it on November 2, four days after the incident. But put the two events side by side and the bank's phrase "risk management" stops sounding abstract. The concrete version of that risk is: the tool your traders use to write code can itself be replaced, at the marketplace, with a version that plants an SSH key on their laptops — and uninstalling it doesn't remove the key. Goldman has 12,000 engineers to hand the tools to. It does not have 12,000 bankers it can ask to audit their &lt;code&gt;authorized_keys&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The underwriting irony
&lt;/h2&gt;

&lt;p&gt;There is one more detail in the reporting, and it's the one that makes the story stick. Goldman Sachs and Morgan Stanley are lead underwriters on Anthropic's IPO — the S-1 was filed October 26, 2026, with Anthropic expected to list on Nasdaq under the ticker ANT before the end of November. So the bank that is taking Anthropic public is, in the same month, telling its own bankers they may no longer use Anthropic's coding tool. That is not a contradiction. It is the whole point: Goldman is happy to sell you the company, and it is also happy to tell you that inside a bank, the question isn't whether the tool is good. It's who is allowed to produce code that touches client money.&lt;/p&gt;

&lt;h2&gt;
  
  
  The line Goldman drew
&lt;/h2&gt;

&lt;p&gt;Every enterprise AI policy eventually draws this line, and Goldman's is unusually legible. It isn't "AI is banned" — the engineers kept everything, and the strats kept everything. It isn't "AI is safe" — the bankers lost the tools they'd been using for months. The line is: &lt;strong&gt;the person who produces the code has to be the person whose job it is to own it.&lt;/strong&gt; A trader's prototype that monitors client flows is code that touches client data whether or not anyone calls it production. A banker building market models in an agent is writing software that influences decisions, and when that software is wrong, "the AI wrote it" is not an owner.&lt;/p&gt;

&lt;p&gt;That's a defensible line, and it's also a narrow one. It holds exactly as long as the engineers stay the bottleneck — 12,000 of them, in Goldman's case, which is a luxury most companies don't have. For a firm with 200 engineers and 2,000 everyone-elses, the same policy is just a ban with better PR. And the policy says nothing about the supply chain underneath: the engineers still install the same extensions from the same marketplaces. The October 29 incident hit engineers too — the 5,000 users who got the tampered build were developers. Restricting the tool to engineers doesn't fix a poisoned marketplace. It just makes sure the people holding the poisoned tool are the ones who know what &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; is.&lt;/p&gt;

&lt;p&gt;Sources: Bloomberg, November 2, 2026 (via FinanceFeeds, Meridian Report, AI Tool Briefing); Cursor security notice on the Claude Code extension, October 29–30, 2026; StepSecurity, "Trojanized Claude Code Extension Delivered Persistent SSH Backdoor to Developer Machines," October 30, 2026; Phorion teardown, October 2026. The Goldman quotes are the spokesperson's words as reported by Bloomberg. The Anthropic IPO underwriting detail is per the S-1 filed October 26, 2026, as reported. I did not independently verify the internal guidance — Bloomberg's reporting is the source.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>governance</category>
      <category>discuss</category>
    </item>
    <item>
      <title>8 hops from a license plate to an unlocked car door</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 15:05:59 +0000</pubDate>
      <link>https://dev.to/frankchu/8-hops-from-a-license-plate-to-an-unlocked-car-door-3075</link>
      <guid>https://dev.to/frankchu/8-hops-from-a-license-plate-to-an-unlocked-car-door-3075</guid>
      <description>&lt;h1&gt;
  
  
  8 hops from a license plate to an unlocked car door
&lt;/h1&gt;

&lt;p&gt;Two researchers turned a license plate into a working door-unlock command for any connected car from two automakers — and both vendors fixed it within about two hours of disclosure. The whole chain is 8 hops long, and the only hop that needed real cleverness was a URL the WAF and the backend read differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The chain
&lt;/h2&gt;

&lt;p&gt;Shubham Shah and Sam Curry published the writeups on November 7, 2026 — Shah covering the Australian leg, Curry the US, Canadian, and European leg. Same ForgeRock identity platform underneath, same disclosure, two posts. The Australian chain, start to finish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;license plate -&amp;gt; VIN -&amp;gt; subscriber GUID -&amp;gt; OpenIDM admin creds
  -&amp;gt; WAF bypass -&amp;gt; MFA bypass -&amp;gt; app token -&amp;gt; door-unlock command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Plate → VIN.&lt;/strong&gt; Australian state registration lookups hand out a VIN for a plate. Not a vulnerability — that's a public lookup by design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VIN → subscriber GUID.&lt;/strong&gt; The admin tool's API mapped a VIN to the subscriber record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subscriber GUID → account PII.&lt;/strong&gt; The &lt;code&gt;/v1/account&lt;/code&gt; endpoint returned the full account, including the email registered on the ForgeRock identity platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin credentials in a JavaScript bundle.&lt;/strong&gt; A vendor JS bundle shipped with the admin tool embedded OpenIDM admin credentials. Meant for staging, worked in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WAF bypass.&lt;/strong&gt; The edge blocked &lt;code&gt;/openidm/*&lt;/code&gt; outright — but a traversal hidden behind encoded slashes got through.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MFA bypass.&lt;/strong&gt; The Australian environment's multi-factor step could be skipped entirely via a Resource Owner Password Credentials grant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mint an app token.&lt;/strong&gt; Password reset via &lt;code&gt;PATCH /openidm/managed/user/&amp;lt;id&amp;gt;&lt;/code&gt;, then the ROPC flow, then a token exchange for a mobile-app access token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send the command.&lt;/strong&gt; &lt;code&gt;POST /v1/remote/route/command&lt;/code&gt; with &lt;code&gt;{"command": "door-unlock"}&lt;/code&gt;. The doors unlocked — on cars they owned or had permission to touch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Curry's companion post is the wilder half: the same ForgeRock deployment also gave them &lt;strong&gt;remote code execution on the production identity servers&lt;/strong&gt; — via the Felix OSGi console at &lt;code&gt;/system/console&lt;/code&gt;, default credentials &lt;code&gt;admin:admin&lt;/code&gt;, and a Groovy script smuggled in through the OpenIDM scheduler. From there they could create a valid session for any customer account, which meant location, telemetry, lock/unlock, and remote engine start/stop for any connected vehicle on those deployments. Both automakers fixed it within about two hours and rotated the credentials. The researchers tested the full chain only on US accounts and vehicles they had permission for, and the automakers asked not to be named.&lt;/p&gt;

&lt;h2&gt;
  
  
  I re-ran the encoding trick locally
&lt;/h2&gt;

&lt;p&gt;I couldn't test the automakers' edge — and wouldn't. But the core mechanism is a parser differential, and that I can measure. The writeups say the edge "decided whether to allow the incoming path" while "the servlet container decoded another form of it to select a servlet." So I fed the exact strings from the posts to two real parsers on my machine:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;posixpath&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unquote&lt;/span&gt;

&lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/openidm/endpoint/aaa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/XUI/..%2fopenidm/managed/user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/XUI%2f..%2fopenidm/managed/user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/static%2f..%2fopenidm/managed/user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posixpath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'/openidm/endpoint/aaa'                    -&amp;gt; '/openidm/endpoint/aaa'
'/XUI/..%2fopenidm/managed/user'            -&amp;gt; '/openidm/managed/user'
'/XUI%2f..%2fopenidm/managed/user'          -&amp;gt; '/openidm/managed/user'
'/static%2f..%2fopenidm/managed/user'       -&amp;gt; '/openidm/managed/user'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A layer that decodes &lt;code&gt;%2f&lt;/code&gt; and normalizes &lt;code&gt;..&lt;/code&gt; sees the admin route in all three traversal strings. Now the same strings through Node's WHATWG URL parser, which keeps &lt;code&gt;%2f&lt;/code&gt; encoded in &lt;code&gt;pathname&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'/openidm/endpoint/aaa'                    -&amp;gt; '/openidm/endpoint/aaa'
'/XUI/..%2fopenidm/managed/user'            -&amp;gt; '/XUI/..%2fopenidm/managed/user'
'/XUI%2f..%2fopenidm/managed/user'          -&amp;gt; '/XUI%2f..%2fopenidm/managed/user'
'/static%2f..%2fopenidm/managed/user'       -&amp;gt; '/static%2f..%2fopenidm/managed/user'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A layer that reads the path the WHATWG way sees an app page under &lt;code&gt;/XUI/&lt;/code&gt; or a static asset — never the admin route. Same bytes, two different routes. That is the whole vulnerability: not a bug in either parser, but the fact that the filter and the backend disagreed about what the URL meant.&lt;/p&gt;

&lt;p&gt;Then I built the two layers for real: a toy WAF proxy on port 18080 that blocks the literal prefixes &lt;code&gt;/openidm/&lt;/code&gt; and &lt;code&gt;/system/console&lt;/code&gt; on the raw request target, forwarding everything else to a backend on 18081 that decodes percent-encoding and normalizes dot segments before routing. Real HTTP, real status codes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;403  /openidm/managed/user                       -&amp;gt; WAF: blocked
403  /system/console/bundles                     -&amp;gt; WAF: blocked
200  /XUI/..%2fopenidm/managed/user              -&amp;gt; OPENIDM ADMIN API
200  /XUI%2f..%2fopenidm/managed/user            -&amp;gt; OPENIDM ADMIN API
200  /static%2f..%2fopenidm/managed/user         -&amp;gt; OPENIDM ADMIN API
200  /static%2f..;/openidm/info/ping            -&amp;gt; static asset (no ;param handling)
200  /static%2f..;/system%2fconsole;/bundles/.json -&amp;gt; static asset (no ;param handling)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three of the five encoded variants reached the admin handler past my naive prefix-checking WAF. The real edge did better than my toy — it hard-403'd the &lt;code&gt;/XUI%2f..%2f&lt;/code&gt; form — and still missed the &lt;code&gt;/static%2f..%2f&lt;/code&gt; form, which is the one that mattered. The semicolon forms are the interesting miss in my model: the real Jetty stripped &lt;code&gt;;&lt;/code&gt; path parameters before servlet mapping, which is how &lt;code&gt;/static%2f..;/system%2fconsole;/bundles/.json&lt;/code&gt; reached the Felix console in the US chain. My backend doesn't implement that, so it served a static asset. The lesson survives the mismatch: every layer in the stack — edge, servlet container, application router — decodes the URL on its own schedule, and the attacker only needs one variant where the edge's reading is benign and the backend's reading is the admin route.&lt;/p&gt;

&lt;h2&gt;
  
  
  The password hash didn't matter
&lt;/h2&gt;

&lt;p&gt;One detail from the Australian writeup deserves a pause. The &lt;code&gt;getUser&lt;/code&gt; endpoint handed back password hashes — PBKDF2-SHA512. That sounds like a cracking problem. I measured my own box's rate at a few iteration counts, single-threaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iters=   1000:  1095.4 hashes/s  | 26^6 candidates:   78.3 h (  3.3 d)
iters=  10000:   117.0 hashes/s  | 26^6 candidates:  733.1 h ( 30.5 d)
iters= 100000:    11.9 hashes/s  | 26^6 candidates: 7202.4 h (300.1 d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The writeup doesn't give the iteration count, so I measured three. A 6-character lowercase password is 26^6 = 308,915,776 candidates.)&lt;/p&gt;

&lt;p&gt;But the hash was never the obstacle. The same admin access that returned the hash also allowed &lt;code&gt;PATCH /openidm/managed/user/&amp;lt;id&amp;gt;&lt;/code&gt; with &lt;code&gt;{"operation": "replace", "field": "/password", "value": "Testing123!"}&lt;/code&gt; — a 200 OK, and the password was simply theirs now. The PBKDF2-SHA512 hash was a souvenir, not a barrier. That's the pattern across the whole chain: every defensive layer was real — the WAF blocked the obvious paths, the passwords were properly hashed, MFA existed — and every one of them had a second door that was simply open. The WAF blocked &lt;code&gt;/openidm/&lt;/code&gt; but not &lt;code&gt;/static%2f..%2fopenidm/&lt;/code&gt;. MFA existed but the ROPC flow skipped it. The hash was strong but the password was replaceable.&lt;/p&gt;

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

&lt;p&gt;Count the distinct failures and notice what kind they are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Admin credentials embedded in a shipped JS bundle ............ 1
Admin tool + identity platform reachable from the internet ... 1
WAF that reads URLs differently from the backend ............. 1
MFA step skippable via an alternate grant .................... 1
Felix console exposed with default admin:admin ............... 1
Scheduler that runs inline Groovy as the identity process .... 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of these is a zero-day. The traversal is a 25-year-old technique, default credentials are the oldest finding in the book, and shipping secrets in a JS bundle is a mistake every web team has made once. What made the chain work was that six ordinary mistakes were stacked in one deployment, and the outermost layer — the WAF — was the one the team had invested in most heavily. The writeups are explicit that the edge had serious WAF rules; the researchers spent days on the bypass. The WAF wasn't absent. It was the last line, and it was also the first thing that failed, because it was guarding a door the backend didn't think was a door.&lt;/p&gt;

&lt;p&gt;The fix, per Curry's post, took about two hours. That's the other number worth sitting with. Not two weeks of re-architecture — two hours to close the exposure and rotate the credentials. The vulnerability wasn't hard to fix. It was hard to see, because each layer looked secure from its own side of the glass.&lt;/p&gt;

&lt;p&gt;Sources: Shubham Shah, "Unlocking any car from X brand in most of the world," shubs.io, November 7, 2026; Sam Curry, "Hacking Two Automakers: ForgeRock Path Confusion, RCE, and Remote Vehicle Access," samcurry.net, November 2026. The parser table, the WAF-proxy results, and the PBKDF2 rates are my own measurements on this machine (4-core VM, Python 3.12, Node WHATWG URL). The automakers are unnamed at their request; the researchers tested only on vehicles they owned or had permission to access.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>security</category>
      <category>cars</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Sequoia's $20B SpaceX stake met one board-seat wall</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 02:06:20 +0000</pubDate>
      <link>https://dev.to/frankchu/sequoias-20b-spacex-stake-met-one-board-seat-wall-ebb</link>
      <guid>https://dev.to/frankchu/sequoias-20b-spacex-stake-met-one-board-seat-wall-ebb</guid>
      <description>&lt;h1&gt;
  
  
  Sequoia's $20B SpaceX stake met one board-seat wall
&lt;/h1&gt;

&lt;p&gt;Sequoia holds roughly $20 billion of SpaceX, and the man who used to run Sequoia now sits on SpaceX's board — audit committee included — without ever asking his old firm for permission. That one skipped compliance check may have walled the whole partnership off from trading its biggest win.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the FT reported today
&lt;/h2&gt;

&lt;p&gt;The Financial Times reported on November 8 that Sequoia's partners were "blindsided" when former leader Roelof Botha joined SpaceX's board this summer. The quote, from an unnamed source: Botha "didn't ask compliance, he didn't get sign off from the partnership" — even though the role could complicate the firm's ability to trade its roughly $20 billion stake.&lt;/p&gt;

&lt;p&gt;The verified timeline underneath the gossip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;June 12, 2026:&lt;/strong&gt; SpaceX lists on the Nasdaq (ticker SPCX) at a $1.77 trillion valuation — the largest IPO on record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;June 16, 2026:&lt;/strong&gt; Botha joins SpaceX's board as an independent director, and per June coverage, a member of its audit committee. Botha and Musk previously worked together at PayPal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 2025:&lt;/strong&gt; Botha stepped down as Sequoia's senior steward. &lt;strong&gt;July 2026:&lt;/strong&gt; he fully left the firm. So the June board appointment happened while he was still a Sequoia partner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 4, 2026:&lt;/strong&gt; Sequoia circulates a memo, "The Sequoia of Tomorrow," announcing a restructuring — closing the London office, merging the early-stage and growth teams, ending the Scouts program (and the Arc accelerator), and cutting the general-partner count roughly in half to seven partners who now own and operate the firm.&lt;/li&gt;
&lt;li&gt;A Sequoia spokesperson said the firm continues to "collaborate closely" with Botha. Botha declined to comment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I did the stake math, and the FT's number doesn't match June's
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ipo_val&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.77e12&lt;/span&gt;            &lt;span class="c1"&gt;# SpaceX IPO valuation, June 12 2026
&lt;/span&gt;&lt;span class="n"&gt;shares&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;13_581_063_709&lt;/span&gt;     &lt;span class="c1"&gt;# shares outstanding, Oct 15 (10-Q)
&lt;/span&gt;&lt;span class="n"&gt;nov6_close&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;134.27&lt;/span&gt;            &lt;span class="c1"&gt;# Nasdaq close, Friday Nov 6
&lt;/span&gt;&lt;span class="n"&gt;nov6_mcap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shares&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;nov6_close&lt;/span&gt;
&lt;span class="n"&gt;stake&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.015&lt;/span&gt;              &lt;span class="c1"&gt;# Sequoia's reported ~1.5% holding
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.5% x IPO $1.77T        = $26.6B
1.5% x Nov-6 mcap       = $27.4B
Nov-6 mcap              = $1.82T
$20B implies stake pct at Nov-6 mcap = 1.10%
$20B implies valuation at 1.5%       = $1.33T
Gap 26.6 vs 20          = $6.5B (24.7% lower)
Return on &amp;gt;$1B invested at $20B   = 20x+
Return on &amp;gt;$1B invested at $26.6B = 26.6x
1.5% of 13.58B shares   = 204M shares
1.3B lock-up shares     = 9.6% of shares outstanding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The FT's $20 billion is $6.5 billion — 24.7% — below what the reported 1.5% stake is worth at either the IPO valuation or Friday's close. $20 billion implies either a ~1.10% stake at today's market cap, or a $1.33 trillion valuation at 1.5% — and neither matches the filings. Two live explanations: Sequoia may have sold some shares (the first big lock-up tranche — up to 1.3 billion shares — became eligible after September-quarter results, and about a third of SpaceX shares now trade publicly, up from 5% at debut), or the FT's figure is rounded or stale. I can't resolve it from public filings, so I'm flagging the gap rather than picking a side. Either way, Sequoia invested a little over $1 billion starting in 2019 and has never sold — so this is a 20x-plus position, on any version of the numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one board seat can freeze a $20 billion position
&lt;/h2&gt;

&lt;p&gt;This is the part that isn't gossip. In a partnership, one partner's access to material nonpublic information can restrict the entire firm's trading — that's what compliance sign-off on outside board seats exists to prevent. An audit committee seat is the sharpest version of the problem: audit committee members see the financials before the market does.&lt;/p&gt;

&lt;p&gt;The timing makes it worse. Only about 5% of SpaceX shares traded publicly at debut; now about a third do, and the first lock-up tranche has already freed up. The window to sell is opening just as the wall goes up. One caveat: "could complicate" is the FT's wording. No filing or statement confirms Sequoia is actually restricted from trading today — but the restriction, if it exists, would be invisible by design. You don't announce a trading wall; you just don't trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is claim, what is confirmed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confirmed:&lt;/strong&gt; the June 16 board appointment (SEC filing), the November 2025 steward step-down, the July 2026 exit, the November 4 restructuring memo, the ~$20 billion stake figure per the FT, and the spokesperson's "collaborate closely."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Characterization, not fact:&lt;/strong&gt; "blindsided" is one unnamed FT source's word. The "erasing Botha's legacy" framing is the FT's interpretation — and another source in the same piece pushes back, calling it "erasure of Sequoia's heritage, not Roelof's legacy." Botha hasn't given his side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unresolved:&lt;/strong&gt; the $20B vs $26.6B stake gap.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The take
&lt;/h2&gt;

&lt;p&gt;The irony is the point. Botha "loved process and hierarchy," per the FT's source — and the process he allegedly skipped is the one that exists precisely for a $20 billion position in a newly public company. Sequoia spent seven years building a position worth 20 times its money. The governance question now is whether the firm can realize any of it on its own timetable, or whether its former leader's new seat decides that for them.&lt;/p&gt;

&lt;p&gt;And the restructuring is the other half of the story: the same week Sequoia shrinks to seven partners and closes its London office, its biggest holding gets harder to trade. That's the story — not the gossip. A venture firm is a governance machine before it is a checkbook, and this week both halves of that machine got tested at once.&lt;/p&gt;

&lt;p&gt;Sources: TechCrunch, November 8, 2026; Financial Times, November 8, 2026 (via TechCrunch and independent write-ups); SpaceX prospectus, June 12, 2026; SpaceX 10-Q (13.58B shares outstanding, October 15); Nasdaq close, November 6, 2026 ($134.27). All ratios are my own computations from those figures. The $20 billion stake figure and the "blindsided" characterization are the FT's, as reported by TechCrunch.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>spacex</category>
      <category>governance</category>
      <category>discuss</category>
    </item>
    <item>
      <title>1,600x is arithmetic, not an attack: I checked DeepMind RSA</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 00:36:52 +0000</pubDate>
      <link>https://dev.to/frankchu/1600x-is-arithmetic-not-an-attack-i-checked-deepmind-rsa-12di</link>
      <guid>https://dev.to/frankchu/1600x-is-arithmetic-not-an-attack-i-checked-deepmind-rsa-12di</guid>
      <description>&lt;h1&gt;
  
  
  1,600x is arithmetic, not an attack: I checked DeepMind RSA
&lt;/h1&gt;

&lt;p&gt;My calculator says 1,645.7. DeepMind says "about 1,600x." The two numbers agree — and that agreement is the least interesting thing about this story, because the 1,600x was never run. What was actually run is smaller, stranger, and more important: two AI agents reproduced a 1,380-CPU-core-year attack in 391 core-years, debugging it in under four days, on about twenty short messages from a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  What DeepMind actually announced
&lt;/h2&gt;

&lt;p&gt;On November 6, 2026, Google DeepMind's Pushmeet Kohli posted "Advancing the frontier of cryptanalysis," describing two working papers from a team led by Dj Dvijotham and Abhradeep Thakurta, with cryptographers Nadia Heninger (UC San Diego / Inria) and Emmanuel Thomé (Inria). The target is 1024-bit RSA — a key size NIST stopped accepting for new signatures in 2013. The papers themselves say it in bold: nothing here threatens deployed cryptosystems using 2048-bit and larger RSA. Keep that sentence in mind; every number below lives inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two columns: measured vs. estimated
&lt;/h2&gt;

&lt;p&gt;The announcement mixes two kinds of numbers, and the papers keep them in separate columns. Here they are, separated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEASURED (ran in a sandbox, on a solved benchmark key):
  Original attack, Sep 2026 (Shea/Haller/Suhl/Heninger/Thomé): 1,380 CPU core-years
  Agents' reproduction, same algorithm/polynomials/bounds:        391 CPU core-years
  Ratio: 1380 / 391 = 3.53x less CPU time
  Oracle queries before target selection: ~4.06 billion (original: 2^32 = 4.29B)
  Debugging time: under 4 days, ~20 short messages from a human researcher
  Cost vs. factoring the key outright: &amp;lt; 1/1000

ESTIMATED (theoretical, not run at cryptographic size):
  Signature forgery, 32-byte fingerprint: ~1,600x faster than previous best
  Batch factoring, each extra 1024-bit key: ~30x cheaper than previous batch method
  Fan-factory precomputation: each further key at ~1/58 the cost of plain NFS
  Algebraic identities behind both: machine-checked in Lean 4
  Fan factories built: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The measured column is a 3.5x engineering saving on a reproduction. The estimated column is where the 1,600x lives. Both columns are real work; they are not the same kind of claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  I re-ran the 1,600x with a pocket calculator
&lt;/h2&gt;

&lt;p&gt;The 1,600x comes from the L-notation constants in the affine-roots paper: the old algorithm costs L_N[1/3, 1.8171], the new one L_N[1/3, 1.5803], where L_N[1/3, c] = exp(c · (ln N)^(1/3) · (ln ln N)^(2/3)). For N = 2^1024, that exponent base is 31.275. So the ratio is just exp(31.275 × (1.8171 − 1.5803)):&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;
&lt;span class="n"&gt;lnN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lnN&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lnN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# 31.275
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;old/new  :&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.8171&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5803&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="c1"&gt;# 1645.7
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GNFS/new :&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.923&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5803&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="c1"&gt;# 45158.0
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFS/fan  :&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.923&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.793&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="c1"&gt;# 58.3
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MNFS/fan :&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.902&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.793&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="c1"&gt;# 30.2
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1380/391 :&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1380&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;391&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;              &lt;span class="c1"&gt;# 3.529
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;old/new  : 1645.7
GNFS/new : 45158.0
NFS/fan  : 58.3
MNFS/fan : 30.2
1380/391 : 3.529
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1645.7 against a claimed ~1,600; 58.3 against ~1/58; 30.2 against ~30x. The arithmetic behind all three headline multipliers reproduces from the papers' own constants, using the standard GNFS constant 1.923 and the standard multiple-NFS constant 1.902. That is a genuine check — it means the big numbers are not typos or marketing rounding. But it is also all it is: L-notation is asymptotic. It says what the cost would be at the limit, with the constants doing the talking and the implementation doing none of it. The 1,600x algorithm was not run at 1024 bits. The fan factory was not built at all — the paper's own analysis notes the shared table would be enormous, roughly 275 pairs at leading order for 1024-bit targets, and the batch variant without that stored precomputation has a much smaller gain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part nobody headlined
&lt;/h2&gt;

&lt;p&gt;The most consequential sentence in this story is not DeepMind's. It is from the September paper the agents reproduced — Shea, Haller, Suhl, Heninger and Thomé, "Forging 1024-bit RSA signatures in nearly SNFS time," IACR ePrint 2026/2131, September 20, 2026. I fetched it and checked the claims against the text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ePrint 2026/2131 — verified from the paper itself:
  Title: "Forging 1024-bit RSA signatures in nearly SNFS time"
  Cost of the original attack: 1,380 CPU core-years over 5 months, 2^32 oracle queries
  Conclusion: RSA's concrete security is "15 to 30 bits lower than
              factoring-based estimates" for keys from 1024 to 4096 bits
              "in this attack model" — i.e., with a signing oracle.
  Sharpest line: "Even 4096-bit RSA does not appear to meet a 128-bit
              security level in this attack model."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that again: the September paper already concluded that &lt;em&gt;4096-bit&lt;/em&gt; RSA falls short of 128-bit security once the attacker gets a signing oracle — a hardware security module, a signing API, anything that signs attacker-influenced data and returns the signature. DeepMind's agents then made the forgery cheaper (3.5x measured, 1,600x projected) and the batch case cheaper (30x projected). The agents did not discover that the oracle model is dangerous. The humans did, in September. The agents made an existing warning louder, faster, and cheaper to act on.&lt;/p&gt;

&lt;p&gt;That reframes the "weeks, not decades" line, too. What took weeks was the agents' run through a problem cryptographers had already framed, with the polynomials and bounds handed to them from the September paper. The human contribution is visible in the paper trail: Heninger and Thomé co-authored both the September attack and the November follow-ups. "Two agents, ~20 messages, under four days" is a real measurement of implementation speed. It is not a measurement of autonomous discovery.&lt;/p&gt;

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

&lt;p&gt;Three things, in order of how much I trust them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The measured 3.5x is real and it is the story.&lt;/strong&gt; Reproducing a 1,380-core-year computation in 391 core-years, in under four days of debugging, means the iteration loop on cryptanalysis just got dramatically shorter. The next attack idea gets tested in weeks instead of years — and the testing is what produces the next theoretical jump.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 1,600x and 30x are sound arithmetic on unbuilt machines.&lt;/strong&gt; My re-derivation matches DeepMind's constants to within rounding. But asymptotic estimates have a history of shrinking on contact with implementation — the fan factory's own paper says as much about its stored table — so treat them as directions, not arrival times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The oracle model is the actual vulnerability, and it predates the agents.&lt;/strong&gt; Padding was supposed to stop forgery; the papers show that once an attacker controls about half the signed block, padding buys almost nothing, and a 32-byte digest is a genuinely hard case that just got 1,600x cheaper on paper. If your threat model includes a signing oracle — an HSM, a cloud signing API, a blind-signature flow — the September paper's "15 to 30 bits lower" is the number to carry, not the 1,600x.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RSA-2048 is untouched by these specific results, and nobody involved claims otherwise. What moved is the speed at which the safety margins get re-measured — and the uncomfortable fact that the margins were already thinner than the textbooks said, before any agent got involved.&lt;/p&gt;

&lt;p&gt;Sources: Pushmeet Kohli, "Advancing the frontier of cryptanalysis," Google DeepMind, Nov 6, 2026; "Modular Roots from a Restricted Oracle: Faster Affine Roots and a 1024-bit Computation" and "Fan Factories: Multiple Number Fields in Factorization Factories and Batch NFS," Google DeepMind working papers, Nov 5–6, 2026; Shea, Haller, Suhl, Heninger, Thomé, "Forging 1024-bit RSA signatures in nearly SNFS time," IACR ePrint 2026/2131, Sep 20, 2026 (fetched and checked Nov 8, 2026). All L-notation ratios and the 1380/391 division are my own computations from the papers' published constants; the 1,600x and 30x figures are DeepMind's theoretical estimates, not measured results, and the papers are working papers, not yet peer-reviewed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rsa</category>
      <category>cryptography</category>
      <category>discuss</category>
    </item>
    <item>
      <title>56.6 GiB holds a 284B model: I audited the 64GB CPU claim</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Mon, 09 Nov 2026 00:36:40 +0000</pubDate>
      <link>https://dev.to/frankchu/566-gib-holds-a-284b-model-i-audited-the-64gb-cpu-claim-4oh6</link>
      <guid>https://dev.to/frankchu/566-gib-holds-a-284b-model-i-audited-the-64gb-cpu-claim-4oh6</guid>
      <description>&lt;h1&gt;
  
  
  56.6 GiB holds a 284B model: I audited the 64GB CPU claim
&lt;/h1&gt;

&lt;p&gt;The file on Hugging Face is 60,772,069,110 bytes — 56.60 GiB, matching the claim to two decimal places. The lossless decode speed is 9.06 tokens per second, not the 14.7 in the headline. Everything else in the llama-modchip README sits somewhere between those two poles, so I checked each number against the repo, the model files, and the binary itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The claim
&lt;/h2&gt;

&lt;p&gt;llama-modchip is a set of llama.cpp kernel patches and quantization transcoders from a solo author (Paolo Colombo, repo created October 29, 481 stars as of today). The headline: run DeepSeek-V4-Flash — 284.33 billion total parameters, 13.17 billion active — in under 59 GiB of RAM on a plain 64 GB CPU machine, no GPU, at 44.4 tok/s prefill and 9.1–14.7 tok/s decode, with a 256K context window. A 284-billion-parameter model on a desktop CPU sounds like the kind of thing that should fail on arithmetic alone, so I started with arithmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 1: the file size is real
&lt;/h2&gt;

&lt;p&gt;The model lives at &lt;code&gt;Synchopate/DeepSeek-V4-Flash-0731-Fractal-64GB-CPU-GGUF&lt;/code&gt; on Hugging Face. I pulled the file list from the HF API and added it up:&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="c1"&gt;# sizes from huggingface.co/api/models/...?blobs=true
&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...-00001-of-00003.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5_257_664&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...-00002-of-00003.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;36_472_476_064&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...-00003-of-00003.gguf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24_261_609_024&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;30&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GiB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60772069110 = 56.6 GiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;56.60 GiB against a claimed 56.56. And the bits-per-weight math behind it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;284.33e9 params × 1.71 bits / 8 / 2**30 = 56.6 GiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The base model exists, too: &lt;code&gt;deepseek-ai/DeepSeek-V4-Flash-0731&lt;/code&gt; is a real repo (2.7M downloads), config confirms 256 routed experts, 1 shared expert, hidden size 4096, MoE intermediate size 2048. The 1.71 bpw figure is only reachable because most of those 284B parameters are routed experts quantized to ~1.56 bits (IQ1_S) while the shared experts and attention stay at higher precision — the README's own layer table says exactly that, and the numbers are consistent with it.&lt;/p&gt;

&lt;p&gt;One baseline I could not verify: the README says the stock Unsloth &lt;code&gt;UD-IQ1_S&lt;/code&gt; build of the same model is 76.87 GiB. The Unsloth repo on HF returned 401 to an unauthenticated API call, so the "we saved 20.3 GiB" delta rests on a number I couldn't independently read. The 56.6 GiB side of the subtraction is verified; the 76.87 side is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 2: the binary is real and the patches are code, not vibes
&lt;/h2&gt;

&lt;p&gt;The repo ships a precompiled &lt;code&gt;llama-server-modchip-linux-x86_64&lt;/code&gt;. I downloaded it (15.8 MB) and ran it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./llama-server-modchip-linux-x86_64 --version
[RouteCrack+Stockfish-PVS] Initialized: 0 cascade tables, 0 hot rules,
  0 macro entries, 1 warm trie nodes, 192KB L2 Zobrist TT
version: 1 (d2f8305)
built with GNU 13.3.0 for Linux x86_64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It starts, it prints its own drafter state, it identifies as a real llama.cpp fork. The patches are substantial: the DeepSeek patch touches 18 files with 5,814 added lines, including a full rewrite of &lt;code&gt;ngram-map.cpp&lt;/code&gt; (536 → 974 lines) for the Stockfish-PVS speculative drafter. There is also a 46 KB LaTeX paper (&lt;code&gt;paper/main.tex&lt;/code&gt;, PDF built November 4) and a &lt;code&gt;transcode_dsv4.c&lt;/code&gt; transcoder for producing the Fractal-64 checkpoint. Whatever you think of the speed claims, this is a real codebase, not a README with a download link.&lt;/p&gt;

&lt;p&gt;I could not run the model itself: the smallest checkpoint in the family is 14.35 GiB and this VM has ~6 GB of RAM. The speed numbers below are therefore the author's measurements, checked for internal consistency — not my own runs. I am saying so plainly because the whole point of this exercise is knowing which column each number belongs in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 3: the speed numbers, and what the headline leaves out
&lt;/h2&gt;

&lt;p&gt;The docs give the full table, and the full table is more honest than the README banner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prefill, agentic turn 1 (cache_prompt=True, 339 new / 403 total KV):
    baseline 25.12 tok/s  -&amp;gt;  patched 44.36 tok/s  (+76.6%)
Lossless decode, Top-6 all layers (N=1, no speculation):
    5.91 tok/s  -&amp;gt;  9.06 tok/s  (+53.3%, 110.33 ms/token)
Top-4 + L2 pruning:                                  10.12-10.74 tok/s
With Stockfish-PVS speculative drafting:              11.5-14.7  tok/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three asterisks the headline doesn't carry:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;44.36 tok/s is a cached-prompt turn&lt;/strong&gt;, not a cold prefill. 339 of the 403 KV tokens were already cached. The cold baseline was 25.05 tok/s. The +77% is real, but it is a +77% on a warm cache, on a 16-core Zen 5 (Ryzen 9 9955HX).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;14.7 tok/s is speculative decode.&lt;/strong&gt; The lossless, no-drafting number is 9.06. The headline range "9.1–14.7" quietly spans two different modes: raw decode at the bottom, draft-assisted at the top. Both are in the docs; only the blend is in the banner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 100/100 quality gate can't discriminate.&lt;/strong&gt; The repo's own benchmark (&lt;code&gt;benchmarks/eval_quality_and_tools.py&lt;/code&gt;, results JSON timestamped November 2) scores three models — the Q4_0 baseline, Fractal-MXFP4, and Fractal-64 — at 100.0/100.0 on an 80-point tool-use/code/needle rubric. When the baseline also gets a perfect score, "100% quality retention" is a true statement about a test that nothing fails. The telemetry inside the same JSONs is more useful: decode 19.54 → 25.02 tok/s and RSS 21.71 → 17.27 GiB on the 30B Nemotron, which is a real, measured, narrower win than the headline suggests.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What survives
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claim                              Status
284B model file is 56.56 GiB      VERIFIED (HF API: 56.60 GiB)
1.71 bpw arithmetic                VERIFIED (284.33e9 x 1.71 / 8)
Base model exists on HF            VERIFIED (DeepSeek-V4-Flash-0731)
Binary runs                        VERIFIED (downloaded, --version works)
Patches are real code              VERIFIED (18 files, 5,814 added lines)
44.36 tok/s prefill                NARROWER: cached-prompt agentic turn
9.1-14.7 tok/s decode              MIXED: 9.06 lossless, 14.7 speculative
100/100 quality retention          TRUE BUT VACUOUS: baseline scores 100 too
76.87 GiB Unsloth baseline         UNVERIFIED (HF API returned 401)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core claim — a 284-billion-parameter MoE fits in 64 GB of RAM and runs on a CPU with no GPU — checks out on the arithmetic, the files, and the code. A 1.71-bits-per-weight average only works because MoE means most of the weights are cold experts that sit in RAM while 13.17B active parameters do the work; at 9 tok/s, each token still has to stream ~57 GB of weights through memory, which is why the number is 9 and not 90. The speedups are real but smaller and more conditional than the banner: warm cache, speculative drafting, and a self-authored quality rubric that hands out perfect scores to everyone including the baseline.&lt;/p&gt;

&lt;p&gt;If you have a 64 GB machine and a weekend, the download is real and the binary runs. Just read the docs table, not the README banner — the author buried the honest numbers one click down, and they are worth the click.&lt;/p&gt;

&lt;p&gt;Sources: synchopate/llama-modchip (README, docs/DEEPSEEK_V4_OPTIMIZATIONS.md, RELEASE_NOTES.md v2.4.0, benchmarks/FRACTAL_MOE_QUALITY_GATE.md, benchmarks/results/eval_*.json); Hugging Face API — Synchopate/DeepSeek-V4-Flash-0731-Fractal-64GB-CPU-GGUF (file sizes, Nov 8, 2026) and deepseek-ai/DeepSeek-V4-Flash-0731 (config.json); llama-server-modchip-linux-x86_64 downloaded and run Nov 8, 2026. All byte counts and ratios above are my own computations; the 44.36/9.06 tok/s figures are the author's measurements, which I could not re-run on a 6 GB VM.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>llm</category>
      <category>cpu</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Nvidia cleared its CEO before the probe even started</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Sun, 08 Nov 2026 21:05:10 +0000</pubDate>
      <link>https://dev.to/frankchu/nvidia-cleared-its-ceo-before-the-probe-even-started-5a3</link>
      <guid>https://dev.to/frankchu/nvidia-cleared-its-ceo-before-the-probe-even-started-5a3</guid>
      <description>&lt;h1&gt;
  
  
  Nvidia cleared its CEO before the probe even started
&lt;/h1&gt;

&lt;p&gt;Nvidia's board opened an independent investigation into whether CEO Jensen Huang was targeted by a Chinese intelligence operation — and in the same statement said it has "no reason to believe" any secrets were compromised. The verdict arrived before the inquiry: no committee members named, no outside counsel named, no timetable — and the board has already declared its confidence in Huang's leadership.&lt;/p&gt;

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

&lt;p&gt;On Sunday, November 8, Nvidia's board announced it is initiating an independent investigation "in light of recent reporting that founder and CEO Jensen Huang has been the target of a foreign intelligence effort." A committee of independent directors, assisted by outside independent counsel, will oversee it. I read the statement on Nvidia's own newsroom — it is five short paragraphs, and two of them are doing the reassuring:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"While the Board has no reason to believe that either national security or NVIDIA secrets were compromised, the Board's inquiry will examine all available information."&lt;/p&gt;

&lt;p&gt;"The Board has confidence in Jensen and his leadership team."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same day, Huang told employees in a memo that he was unfaithful to his wife: "I was unfaithful to my wife. My actions hurt her and our children. There is no excuse for what I did. I am deeply sorry." Bloomberg reported the memo, and TechCrunch and other outlets link it to the relationship with Alice Huang, a senior executive at Singapore-based Nvidia customer Megaspeed. One careful distinction, because it matters: as reported, the memo does not name Alice Huang, and it does not concede that any information changed hands. The infidelity admission and the espionage allegation are two different claims, and only the first is now confirmed by Huang himself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The split: verified vs. alleged
&lt;/h2&gt;

&lt;p&gt;This is the same split I drew ten days ago, and the two sides have moved in opposite directions since.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verified since then:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The board investigation exists. It is a primary-source fact, on Nvidia's newsroom, dated November 8.&lt;/li&gt;
&lt;li&gt;Huang admitted infidelity in an internal memo. Confirmed by his own words.&lt;/li&gt;
&lt;li&gt;Three House committee chairs — Brian Mast (Foreign Affairs), John Moolenaar (Select Committee on China), and Rick Crawford (Intelligence) — wrote to Huang on November 4 requesting a joint closed-door briefing on November 18, and asked him to respond by November 11. Their letter describes Alice Huang as a "publicly reported PRC intelligence asset" — the lawmakers' characterization, based on public reporting.&lt;/li&gt;
&lt;li&gt;The one checkable number in this whole story is unchanged: a Megaspeed-linked company in Malaysia bought at least $4.8 billion in AI hardware including Nvidia chips between June 2024 and February 2026 — about $240 million a month. That trail is documented; it is not an allegation about what anyone said to anyone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Still alleged, not established:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That Alice Huang was recruited by China's Ministry of State Security. This comes from a U.S. intelligence memo that circulated among policymakers earlier this year and has never been made public. The New York Times reported U.S. intelligence believes she was sharing information with Beijing; the Financial Times reported the memo also described a romantic relationship. Nvidia denies the pair's interactions were anything but normal business contacts. China denies the spying claims. Nobody has been charged with anything.&lt;/li&gt;
&lt;li&gt;That the operation's goal was to push Huang to lobby Washington for looser restrictions on exporting Nvidia's most advanced AI chips to China. That is the reported objective — and it is also, awkwardly, a position Huang has publicly and repeatedly argued for on the record. Which is exactly what makes the "was he influenced?" question so hard to answer from the outside: the alleged target behavior and the CEO's stated public position point in the same direction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three dates decide this story
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;November 11:&lt;/strong&gt; Huang must tell the three House chairs whether he will attend the briefing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 17:&lt;/strong&gt; Nvidia reports Q3 fiscal 2027 results — guided revenue of $108.0 billion, plus or minus 2% — with the call at 2 p.m. PT. The Q&amp;amp;A is limited to financial analysts and institutional investors, but the spy probe will be the question in the room whether anyone asks it or not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;November 18:&lt;/strong&gt; the proposed closed-door briefing, the day after earnings. The stock's first full session on the earnings print is the same day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ten days, three fixed dates, and one investigation with no announced timetable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a board investigation can — and can't — check
&lt;/h2&gt;

&lt;p&gt;Here is the part I keep coming back to. A board committee with outside counsel can audit real things: export-control compliance records, communications logs, the $4.8 billion equipment trail, who approved which shipments and when. Those are documents. They exist or they don't.&lt;/p&gt;

&lt;p&gt;What it cannot audit is the central allegation. Whether a foreign intelligence service obtained anything from a CEO's personal relationship is an intelligence question, not a governance question. The board has no access to the surveillance that reportedly traced the relationship back to at least June 2024 — a photo at a Taipei bar during Computex, another outing in 2025. It can examine "all available information," as its statement says, but the information that would settle this was never Nvidia's to have.&lt;/p&gt;

&lt;p&gt;So read the board's sentence again: "no reason to believe" secrets were compromised. That is not a finding. It is a statement made before the inquiry it announces has examined anything. And there is a second, quieter fact in the background: the Wall Street Journal notes Nvidia has no public succession plan and no obvious heir apparent to the 63-year-old Huang. A board that cannot name a successor has every incentive to clear its founder quickly — which is precisely why the clearance arriving in the same paragraph as the investigation should be read as the board's position, not as evidence.&lt;/p&gt;

&lt;p&gt;Nvidia's spokesman put it plainly: "Today's news will not slow NVIDIA. Jensen is committed to continuing to lead NVIDIA as CEO without interruption." That is the message. The investigation is the process. Whether the two stay aligned depends on what November 11, 17, and 18 actually produce — and on whether anyone, in Congress or on the board, is willing to say out loud that a probe that announces its conclusion on day one is not a probe at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Statement from NVIDIA Board of Directors (November 8, 2026) — &lt;a href="https://nvidianews.nvidia.com/news/statement-from-nvidia-board-of-directors" rel="noopener noreferrer"&gt;https://nvidianews.nvidia.com/news/statement-from-nvidia-board-of-directors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TechCrunch, "Nvidia says it's investigating CEO Jensen Huang's relationship with possible Chinese spy" (November 8, 2026) — &lt;a href="https://techcrunch.com/2026/11/08/nvidia-says-its-investigating-ceo-jensen-huangs-relationship-with-possible-chinese-spy/" rel="noopener noreferrer"&gt;https://techcrunch.com/2026/11/08/nvidia-says-its-investigating-ceo-jensen-huangs-relationship-with-possible-chinese-spy/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Wall Street Journal, "Nvidia's Board to Investigate Reports That Jensen Huang Was Spying Target" (November 8, 2026) — &lt;a href="https://www.wsj.com/tech/ai/nvidias-board-to-investigate-reports-that-jensen-huang-was-spying-target-c630325e" rel="noopener noreferrer"&gt;https://www.wsj.com/tech/ai/nvidias-board-to-investigate-reports-that-jensen-huang-was-spying-target-c630325e&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NVIDIA, "Sets Conference Call for Third-Quarter Financial Results" (October 28, 2026) — &lt;a href="https://investor.nvidia.com/news/press-release-details/2026/NVIDIA-Sets-Conference-Call-for-Third-Quarter-Financial-Results/default.aspx" rel="noopener noreferrer"&gt;https://investor.nvidia.com/news/press-release-details/2026/NVIDIA-Sets-Conference-Call-for-Third-Quarter-Financial-Results/default.aspx&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The $4.8B Megaspeed equipment trail, as verified in my October 29 piece — &lt;a href="https://dev.to/frankchu/the-nvidia-spy-story-split-in-two-a-verified-48b-equipment-trail-and-an-unverified-allegation-19ac"&gt;https://dev.to/frankchu/the-nvidia-spy-story-split-in-two-a-verified-48b-equipment-trail-and-an-unverified-allegation-19ac&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The House chairs' letter (November 4, 2026) and the November 11 / November 18 dates, as reported by multiple outlets; the espionage claims themselves remain unconfirmed allegations from an unpublished intelligence memo.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>nvidia</category>
      <category>security</category>
      <category>discuss</category>
    </item>
    <item>
      <title>0 fixes for 61,747 stars: AutoGen after AI Frontiers died</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Sun, 08 Nov 2026 15:05:36 +0000</pubDate>
      <link>https://dev.to/frankchu/0-fixes-for-61747-stars-autogen-after-ai-frontiers-died-ai8</link>
      <guid>https://dev.to/frankchu/0-fixes-for-61747-stars-autogen-after-ai-frontiers-died-ai8</guid>
      <description>&lt;h1&gt;
  
  
  0 fixes for 61,747 stars: AutoGen after AI Frontiers died
&lt;/h1&gt;

&lt;p&gt;AutoGen has 61,747 stars and 1,171 open issues. Its README now says Microsoft provides no bug fixes, no security fixes, no new features, and no support. Its last PyPI release is 404 days old. The research group that built it is over — and I checked the repos to see what "over" actually means, because the group died twice, and the two deaths are six months apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  The announcement
&lt;/h2&gt;

&lt;p&gt;John Langford, who helped create AI Frontiers inside Microsoft Research in 2023, published "The End of AI Frontiers" on his hunch.net blog on November 6. The facts in it are plain: the group was about 50 people; most of its work was figuring out how to make agents work — the AutoGen orchestration framework and the Fara computer-use agent — plus fundamental work like the Full Bandwidth Transformer, the Next Latent objective, and Dion3. In early September it was reorganised into Microsoft AI. Langford calls the ex-Inflection leadership's philosophy "scaling, and aggressively not research", says every other founding leader reached a similar conclusion about leaving, and writes that there will be no internships with the group next year.&lt;/p&gt;

&lt;p&gt;One distinction matters: Langford declared the group over. Microsoft has published no formal closure announcement. That is his account, and I am treating it as such — but the repos back up the substance of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The repos died first
&lt;/h2&gt;

&lt;p&gt;Here is AutoGen's commit history, from the GitHub API, most recent first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-10-28  d07c667  docs: add archive caution to landing page (#8393)
2026-10-16  004749e  docs: clarify AutoGen is archived and no longer maintained (#8366)
2026-04-06  027ecf0  Update maintenance mode banner in readme (#7521)
2026-03-26  8544314  fix: restrict importlib provider loading to trusted namespaces (#7463)
2026-03-11  b047730  fix: Improve AutoGen Studio: deprecate FunctionTool, harden MCP WebSocket endpoint
2025-10-04  13e144e  fix: order by clause (#7051)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that list again. The last code change landed March 26 — 227 days ago. Between April 6 and October 16 there were zero commits of any kind. The only activity in the second half of 2026 is two documentation commits that say the project is archived. And the PyPI package tells the same story: &lt;code&gt;autogen-agentchat&lt;/code&gt; 0.7.5, uploaded September 30, 2025 — 404 days ago, with nothing since.&lt;/p&gt;

&lt;p&gt;So the timeline is: the code stopped in March, the releases stopped in September 2025, the archive banner went up October 16, and the founder said the group is over on November 6. The announcement is the last event in the sequence, not the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The README contradicts itself
&lt;/h2&gt;

&lt;p&gt;The current README, fetched live today, opens with an "Archived" badge and a caution block: "This project has been archived and is no longer actively maintained by Microsoft. Microsoft is not providing bug fixes, security fixes, new features, or support for this project." But the GitHub API still reports &lt;code&gt;archived: false&lt;/code&gt; — the repo carries the word "archived" as prose, not as a platform state. And further down the same README, the contributing section still reads: "As AutoGen is in maintenance mode, contributions are limited to bug fixes, security patches, and documentation improvements."&lt;/p&gt;

&lt;p&gt;Both cannot be true. Either the project takes bug fixes or it does not; the banner says it does not, a stale paragraph says it does, and 1,171 open issues sit between the two claims. If you depend on AutoGen, the operative sentence is the banner, not the paragraph — but the fact that nobody has cleaned up the contradiction tells you how much attention the repo gets now. None.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Fara?
&lt;/h2&gt;

&lt;p&gt;Fara, the other named product of the group, is in a different state: 6,251 stars, MIT-licensed, created October 29, 2025, last push September 22, 2026, 44 open issues. Its README leads with Fara1.5, released July 22, 2026 — a family of computer-use agent models in 4B, 9B, and 27B sizes, with weights on Hugging Face and two benchmark datasets. No archive notice anywhere in it. Fara is quiet, not dead: a model family with a July release and a September push is a finished artifact more than an abandoned one. The group is over; the models are still downloadable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The successor is shipping weekly
&lt;/h2&gt;

&lt;p&gt;Microsoft's answer to "what replaces AutoGen" is Agent Framework, which hit 1.0.0 for Python and .NET on April 2–3, 2026. Its release cadence is the mirror image of AutoGen's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AutoGen:            last code commit Mar 26, 2026; last PyPI release Sep 30, 2025
Agent Framework:    python-1.25.0 released Nov 7, 2026 (yesterday)
                    dotnet-1.28.0 released Nov 6, 2026
                    1.0.0 shipped Apr 2-3, 2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The README points existing users at a migration guide. The handover happened in April; the archive notice in October just made it official.&lt;/p&gt;

&lt;h2&gt;
  
  
  The argument underneath
&lt;/h2&gt;

&lt;p&gt;Langford's post is not really about a reorg. It is about a bet: "returns to scale are far more predictable than returns to research." He answers with the ByteDance experiments suggesting a Full Bandwidth Transformer variant might match a model twice its size — halve the training and inference cost, on an industry investing something approaching a trillion dollars. Do the math, he says. He is right that the math is the argument: if research halves cost, it is worth more than another scale-up. And Microsoft's revealed preference is the opposite: the scaling organisation absorbed the research group, the research group's founders left, and the framework the researchers built now tells you to go use the scaling organisation's framework instead.&lt;/p&gt;

&lt;p&gt;That is what "over" means here. Not that the code vanished — 61,747 stars do not vanish, and the repo is still readable. It means the institution that would have answered the next question about agents is gone, the people who would have answered it work elsewhere, and the only maintenance AutoGen will ever get is a banner telling you to migrate.&lt;/p&gt;

&lt;p&gt;Sources: John Langford, "The End of AI Frontiers", hunch.net (Nov 6, 2026, read in full); microsoft/autogen — GitHub API (stars, forks, archived flag, commits, open issues) and README fetched Nov 8, 2026; PyPI autogen-agentchat release history; microsoft/Fara — GitHub API and README; microsoft/agent-framework releases. All counts and dates above are my own reads of those sources; the claim that the group is over is Langford's, and Microsoft has not published a formal closure statement.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>autogen</category>
      <category>agents</category>
      <category>discuss</category>
    </item>
    <item>
      <title>181 classes, 278 predicates: I counted Apple's family graph</title>
      <dc:creator>frank chu</dc:creator>
      <pubDate>Sun, 08 Nov 2026 15:05:24 +0000</pubDate>
      <link>https://dev.to/frankchu/181-classes-278-predicates-i-counted-apples-family-graph-38jd</link>
      <guid>https://dev.to/frankchu/181-classes-278-predicates-i-counted-apples-family-graph-38jd</guid>
      <description>&lt;h1&gt;
  
  
  181 classes, 278 predicates: I counted Apple's family graph
&lt;/h1&gt;

&lt;p&gt;Apple's on-device knowledge graph speaks in 181 entity classes and 278 predicates. I counted every row of the tables in the 8rank teardown that hit Hacker News today — 181, 278, and 144 features, all exact. The count the post buries is the one that matters most: 75 of those 181 classes have no mechanism the authors could find.&lt;/p&gt;

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

&lt;p&gt;The post publishes its ontology as three tables. I downloaded the page and counted the rows myself instead of trusting the headline numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Table                    Rows claimed   Rows counted   Match
Entity classes           181            181            yes
Predicates               278            278            yes
Kinship model features   144            144            yes
Feature indices          0-143          0-143          contiguous, no gaps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The feature groups split exactly as claimed: 20 identity, 40 communication, 84 photos. The tidy story — same surname, same home address, an iCloud Family flag — is 20 of 144 inputs. The bulk of the model is who you message and who appears in your photographs, conditioned on the day of the week, the time of day, and then both at once. &lt;code&gt;photosPersonPosteriorProbabilityGivenSaturdayNight&lt;/code&gt; is a shipped feature name in a shipped classifier whose job is deciding whether someone is family.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mechanism tally is the real story
&lt;/h2&gt;

&lt;p&gt;Every class and predicate row carries a "how it gets there" label. The totals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classes (181):     implemented 90 | no mechanism found 75 | unverified 16
Predicates (278):  copied 161 | Apple-shipped world knowledge 40
                   rule 20 | joined 18 | not established 11
                   unknown model 7 | scored model 6 | embedding model 4
                   XGBoost-flavoured 6 | local LLM 3 | face clustering 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things fall out. First, 41% of the classes — 75 of 181 — are vocabulary the authors could not trace to any mechanism that fills them. The ontology declares far more than the daemons demonstrably populate. Second, most of the graph is not inferred at all: 161 of 278 predicates are straight copies from Contacts, Calendar, Photos, Mail, and the rest. The graph is largely a join of things you already typed, re-expressed as triples with a confidence number attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  The family classifier itself
&lt;/h2&gt;

&lt;p&gt;Two CoreML models ship next to the ontology, &lt;code&gt;EntityTagging_Family.mlmodelc&lt;/code&gt; and &lt;code&gt;EntityTagging_FamilyAndFriends.mlmodelc&lt;/code&gt;: binary XGBoost classifiers over those same 144 features. Their scores land in &lt;code&gt;entityTagging.db&lt;/code&gt;, one row per person, seventeen relationship columns — mother, father, parent, sister, brother, sibling, family, friend, familyAndFriends, partner, coworker, alumni, child, son, daughter, myself, unknown.&lt;/p&gt;

&lt;p&gt;Only two of the seventeen columns have a shipped model behind them. The iKnow manual, which ships with the open-source dashboard the post's authors released, says so plainly: "No shipped model produces the other fifteen columns; the likely source is a separate heuristics service." The scores take a handful of quantised values — 0.125, 0.25, 0.5, 0.96 — and two columns, &lt;code&gt;alumni&lt;/code&gt; and &lt;code&gt;unknown&lt;/code&gt;, are never used at all.&lt;/p&gt;

&lt;p&gt;The manual adds the detail that should worry you more than any single inference. Decoded offline, the Family model gives a saved contact with every feature at zero about 0.84. Scores cluster high, and organisations can score as family. A high &lt;code&gt;family&lt;/code&gt; score is weak evidence on its own — which is exactly the opposite of how a "family" label reads when it shows up in a dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  I checked the tool, too
&lt;/h2&gt;

&lt;p&gt;The post's authors ship iKnow, a local dashboard for reading your own graph. I cloned it and audited what it is, since the post asks you to run it against your most private data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repo:        8rank/iKnow, created 2026-09-15, 2 commits, Apache-2.0
Stars:       316 (as of today)
Server:      server.py, Python standard library only, no npm, no CDN
Network:     binds 127.0.0.1 only, no flag to change that
Auth:        random token per start, swapped for a cookie
Writes:      every database handle opened read-only (mode=ro)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That checks out, including the part the README admits in its last line: "iKnow is fully LLM-generated and may not be 100% accurate." The kinship module is genuinely careful code — it tests whether columns are dead, duplicated, or exact sums of each other by comparing column vectors at runtime instead of asserting it. The manual's ontology figures (181 classes, 278 predicates, 144 features, 17 columns) all reproduce from the post's own tables.&lt;/p&gt;

&lt;p&gt;The one prior official source the post cites also checks out: Apple's own researchers published the techniques in 2023 (arXiv:2305.09464, "Growing and Serving Large Open-domain Knowledge Graphs", SIGMOD Companion '23), including a section on constructing private personal knowledge on-device. It describes the platform, not the macOS integration — which is the gap this post fills.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I could not verify
&lt;/h2&gt;

&lt;p&gt;I have no Mac here, so three claims stay unchecked, and I am not going to launder them as verified. "Every Mac since 2022" appears only in the lede; nothing else in the post dates the daemons. The &lt;code&gt;man 8 knowledgeconstructiond&lt;/code&gt; quote and the fifty-one databases under &lt;code&gt;~/Library/IntelligencePlatform&lt;/code&gt; are things I cannot touch from a Linux VM. And the scorecard screenshots in the post use invented data — the authors say so, and add that on the real Mac they took apart, only &lt;code&gt;mother&lt;/code&gt; reached the top of the ladder.&lt;/p&gt;

&lt;p&gt;One claim I can repeat because the post documents it precisely: withdrawing a fact does not delete it. The row moves to &lt;code&gt;expired_stable_graph&lt;/code&gt; and keeps its confidence and its sources; the authors saw records there older than the ~48 hours the prune watermark suggests.&lt;/p&gt;

&lt;p&gt;The uncomfortable part is not that any one inference is wrong. It is that the store is built to be joined: a household entity, a Family Sharing circle, a face cluster, a year of contact metadata with no message text — and from that alone, the authors reconstruct that there is a child in the household, roughly how old, which daycare they go to, and where the family will be on which days. Nobody typed a family tree. The tree is a consequence of everything else that was already there.&lt;/p&gt;

&lt;p&gt;Sources: 8rank, "Anatomy of Apple's Personal Knowledge Graph" (Nov 2026, tables counted from the page HTML); 8rank/iKnow (cloned Nov 8, 2026 — README, MANUAL_FOR_YOUR_AGENT.md, api/kinship.py); Ilyas et al., arXiv:2305.09464 (May 2023). All counts above are my own; the "since 2022", man-page, and 51-database claims are the post's, not mine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>apple</category>
      <category>privacy</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
