<?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: AsiaOstrich</title>
    <description>The latest articles on DEV Community by AsiaOstrich (@asiaostrich).</description>
    <link>https://dev.to/asiaostrich</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%2F3975421%2F277bef48-d7d0-4815-b9f6-7512a713c0da.png</url>
      <title>DEV Community: AsiaOstrich</title>
      <link>https://dev.to/asiaostrich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asiaostrich"/>
    <language>en</language>
    <item>
      <title>A token-saving repo went viral. We read the source, not the README.</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Wed, 08 Jul 2026 12:00:11 +0000</pubDate>
      <link>https://dev.to/asiaostrich/a-token-saving-repo-went-viral-we-read-the-source-not-the-readme-9bn</link>
      <guid>https://dev.to/asiaostrich/a-token-saving-repo-went-viral-we-read-the-source-not-the-readme-9bn</guid>
      <description>&lt;p&gt;Our daily scout surfaces AI-tooling repos every morning. Most of them you should &lt;em&gt;not&lt;/em&gt; adopt — and the engineering is in deciding &lt;em&gt;which parts&lt;/em&gt;, if any, are actually load-bearing for your problem. Here's one worked example.&lt;/p&gt;

&lt;p&gt;A context-compression project — &lt;strong&gt;Headroom&lt;/strong&gt; (&lt;code&gt;headroomlabs-ai/headroom&lt;/code&gt;, Apache-2.0) — made the rounds with a great pitch: cut 60–95% of your LLM context tokens with "zero degradation." For an agent that streams huge tool logs into a model, that's the dream. The reflex it triggers in most teams: &lt;em&gt;vendor the whole thing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We did the slower thing first. We opened the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  The README names and the real names disagree
&lt;/h2&gt;

&lt;p&gt;Headroom's README sells three components — CodeCompressor, SmartCrusher, CacheAligner. Open &lt;code&gt;src/&lt;/code&gt; and the actual classes are &lt;code&gt;CodeStructureHandler&lt;/code&gt;, &lt;code&gt;JSONStructureHandler&lt;/code&gt;, and &lt;code&gt;AnthropicCacheOptimizer&lt;/code&gt; + &lt;code&gt;PrefixCacheTracker&lt;/code&gt;. Not a scandal — just a reminder that the README is marketing copy and the source is the spec. The real design is a clean three-stage pipeline: detect the content type (Magika), run a type-specific handler to extract a structural skeleton, and only then lossy-compress whatever's left.&lt;/p&gt;

&lt;p&gt;The parts worth understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt; (&lt;code&gt;handlers/code_handler.py&lt;/code&gt;): tree-sitter parses the file (regex fallback) and keeps imports, signatures, and class declarations while dropping function bodies, comments, and whitespace. "Keep the API surface, drop the implementation." Works for Python/JS/TS/Go/Rust/Java/Perl.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON&lt;/strong&gt; (&lt;code&gt;handlers/json_handler.py&lt;/code&gt;): a per-token heuristic — keep keys, syntax, booleans, short values, and high-entropy strings (entropy ≥ 0.85); compress long strings; keep the first N array items in full. No schema, no dedup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache alignment&lt;/strong&gt; (&lt;code&gt;prefix_tracker.py&lt;/code&gt;): one genuinely sharp invariant — &lt;em&gt;freeze the already-cached prefix, only compress new content&lt;/em&gt;, so your compression never rewrites the prefix and silently invalidates the provider's KV cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The benchmark, read adversarially
&lt;/h2&gt;

&lt;p&gt;This is where reading beats retweeting. The headline is "60–95% savings, zero degradation," measured with the standard lm-eval harness on a real model. Credit where due: the repo even ships its own worst-case and adversarial benchmarks and lists its failure modes — an honest signal most projects skip.&lt;/p&gt;

&lt;p&gt;But line up the claim with what was actually measured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The zero-degradation numbers come from &lt;strong&gt;GSM8K / TruthfulQA / SQuAD&lt;/strong&gt; — short-answer tasks with almost no context to compress. "Zero degradation" there is &lt;em&gt;trivially&lt;/em&gt; true; it can't support the 60–95% claim.&lt;/li&gt;
&lt;li&gt;The runs that &lt;em&gt;do&lt;/em&gt; compress heavily — agent traces — are &lt;strong&gt;n=5&lt;/strong&gt;, scored by loose keyword matching.&lt;/li&gt;
&lt;li&gt;It's all self-reported, with no third-party reproduction. One external review of prompt-heavy chat measured &lt;strong&gt;20–40% savings&lt;/strong&gt;, not 60–95%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that makes Headroom bad. It makes the headline number a &lt;em&gt;claim&lt;/em&gt;, not a result — and the difference matters when you're deciding what to build on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we borrowed — and what we left on the shelf
&lt;/h2&gt;

&lt;p&gt;We took three &lt;strong&gt;ideas&lt;/strong&gt;, each re-implemented to fit our own stack, not the package:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;tree-sitter "keep signatures, drop bodies"&lt;/strong&gt; for code blobs — a real semantic upgrade over blunt truncation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The JSON keep-keys / high-entropy heuristic&lt;/strong&gt; — cheap, deterministic, no model required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache-aware compression&lt;/strong&gt; — the "will this rewrite a cached prefix?" check, which is the highest-ROI idea in the whole repo and the one nobody talks about.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We explicitly &lt;strong&gt;declined&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The reversible-retrieve loop (CCR)&lt;/strong&gt; — it carries an extra store plus a retrieve round-trip to &lt;em&gt;recover&lt;/em&gt; what compression dropped, costs hundreds of MB of RAM, and is already known to break under streaming (issue #1450). If your compression is allowed to be lossy, you don't need it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ML text model (Kompress)&lt;/strong&gt; — small, English-biased, and when it's unavailable the whole text path silently falls back to first-2/3 + last-1/3 truncation. A dependency that decays into the thing it replaced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The proxy / MCP server / cross-agent "learn loop"&lt;/strong&gt; — orthogonal feature creep, not a compression upgrade.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The actual lesson
&lt;/h2&gt;

&lt;p&gt;A viral repo is an input to a decision, not the decision. Read the source to find the two or three load-bearing ideas, check the benchmark against what it actually measured, and write down — on the record — what you &lt;em&gt;didn't&lt;/em&gt; take and why. That discipline (read the code, not the README; borrow only what nets out positive) is exactly what we encode as a standard.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The source reading, the benchmark analysis, and the adopt/decline decisions are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Picking a code-graph memory for your AI agent? Star count is the wrong axis.</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Mon, 06 Jul 2026 12:00:11 +0000</pubDate>
      <link>https://dev.to/asiaostrich/picking-a-code-graph-memory-for-your-ai-agent-star-count-is-the-wrong-axis-2kie</link>
      <guid>https://dev.to/asiaostrich/picking-a-code-graph-memory-for-your-ai-agent-star-count-is-the-wrong-axis-2kie</guid>
      <description>&lt;p&gt;"Code memory for coding agents" is a hot lane right now. A 49k-star code-graph tool shows up, FalkorDB is pushing GraphRAG, and the reflex is the same one we apply to everything popular: &lt;em&gt;lots of stars — let's wire it in.&lt;/em&gt; We ran one through our radar instead. Here's the part worth keeping: not the verdict, but the axis we used to reach it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lane has two very different shapes
&lt;/h2&gt;

&lt;p&gt;Most "memory for your agent" is a vector database: chunk the repo, embed it, retrieve by similarity. That is genuinely good at one thing — &lt;em&gt;finding code that looks like other code&lt;/em&gt;. Paste a function, get back functions shaped like it.&lt;/p&gt;

&lt;p&gt;But the question I actually ask every day isn't "what looks similar to this." It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If I change this function, what breaks?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similarity can't answer that, and not by accident. &lt;strong&gt;The callers of a function look nothing like the function.&lt;/strong&gt; A logging wrapper, a retry decorator, a route handler three layers up — none of them are textually similar to the body you're editing. They're connected by &lt;em&gt;structure&lt;/em&gt;, not by surface. Answering "what breaks" is a graph traversal — walk the call edges — not a nearest-neighbour lookup in embedding space.&lt;/p&gt;

&lt;p&gt;That's the real divide in this lane: &lt;strong&gt;similarity retrieval vs structural (graph) retrieval.&lt;/strong&gt; Almost everything in the hype cycle is the former. The thing you reach for during a risky refactor is the latter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did with a 49k-star tool
&lt;/h2&gt;

&lt;p&gt;CodeGraph (MIT, ~49k stars, 20+ languages, auto-syncing local index, MCP server for Cursor/Claude Code/Codex) is a serious piece of work on the &lt;em&gt;structural&lt;/em&gt; side. We evaluated it properly — read the repo, mapped its capabilities against ours.&lt;/p&gt;

&lt;p&gt;And we deliberately &lt;strong&gt;did not adopt it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not out of not-invented-here. Our own engine, EngramGraph, already covers the core: a tree-sitter code graph where &lt;code&gt;callers &amp;lt;fn&amp;gt;&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; a graph walk, plus a deterministic, zero-LLM index (no embeddings to drift, cheap to rebuild, same answer every run). The decision to build rather than wire in an external daemon was already made; adopting CodeGraph wholesale would have added a dependency and an architecture conflict, not a capability.&lt;/p&gt;

&lt;p&gt;So we filed it as &lt;strong&gt;Assess&lt;/strong&gt;, and wrote down the three things it's genuinely useful &lt;em&gt;for&lt;/em&gt; — without adopting it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A language-coverage blueprint.&lt;/strong&gt; CodeGraph parses 20+ languages and recognises 17+ framework routing patterns. We don't import its code; we use its parser list as a reference map for where to extend ours next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A benchmark method.&lt;/strong&gt; Its 7-codebase, four-axis measurement (cost / tool-calls / tokens / latency) is a reusable &lt;em&gt;yardstick template&lt;/em&gt; for proving a code graph actually reduces agent exploration — not a set of numbers to copy. Their absolute figures are theirs; the method travels, the numbers don't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An interop signal.&lt;/strong&gt; It exposes its graph over MCP to several agents. That's market evidence that "cross-agent code-graph over MCP" is wanted — worth watching, not worth coupling to.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The point isn't the verdict
&lt;/h2&gt;

&lt;p&gt;A "no" with reasons is more useful six months later than a "yes" you can't reconstruct. The lesson that outlives this particular tool:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool selection in a hyped lane is not a star-count comparison.&lt;/strong&gt; It's one question — &lt;em&gt;does this solve the thing I actually ask every day?&lt;/em&gt; For code memory, that question splits cleanly along similarity-vs-structure. Once you know which side of that line your real problem lives on, half the shiny options on the radar quietly stop being relevant.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The repo reading and the adopt/decline decision are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>database</category>
      <category>rag</category>
    </item>
    <item>
      <title>Most AI-generated tests are written once and never questioned. That's the bug.</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Thu, 02 Jul 2026 12:00:25 +0000</pubDate>
      <link>https://dev.to/asiaostrich/most-ai-generated-tests-are-written-once-and-never-questioned-thats-the-bug-5e18</link>
      <guid>https://dev.to/asiaostrich/most-ai-generated-tests-are-written-once-and-never-questioned-thats-the-bug-5e18</guid>
      <description>&lt;p&gt;Our daily scout surfaces AI-tooling papers every morning. Most of them don't change how we build. This one made us look hard at a habit we'd stopped noticing — so here's the worked example.&lt;/p&gt;

&lt;p&gt;In January 2026, &lt;strong&gt;"The Rise of Agentic Testing"&lt;/strong&gt; (&lt;a href="https://arxiv.org/abs/2601.02454" rel="noopener noreferrer"&gt;arXiv:2601.02454&lt;/a&gt;) made the case that the way we generate tests with LLMs is quietly broken. Not the models — the &lt;em&gt;shape&lt;/em&gt; of the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The default loop is single-shot
&lt;/h2&gt;

&lt;p&gt;Ask an LLM for tests and you usually get them in one pass: generate once, done. The problem is that a one-shot test is written &lt;em&gt;blind&lt;/em&gt; — the model never sees the test actually run. So you get the three failure modes everyone has hit: tests that don't compile, tests that assert nothing meaningful, tests that duplicate each other. There's no execution-aware feedback closing the loop, so a test that &lt;em&gt;passes for the wrong reason&lt;/em&gt; sails straight through.&lt;/p&gt;

&lt;p&gt;The paper's proposal: make test generation a closed loop — generate, run in a sandbox, analyze the failure, then &lt;strong&gt;refine the test itself&lt;/strong&gt;, and iterate until it converges. Standard agentic-loop thinking, pointed at the test instead of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  code-centric vs test-centric — the part worth internalizing
&lt;/h2&gt;

&lt;p&gt;Here's the distinction that's actually load-bearing.&lt;/p&gt;

&lt;p&gt;When a test fails, most pipelines (ours included, historically) are &lt;strong&gt;code-centric&lt;/strong&gt;: the failure is a signal to &lt;em&gt;change the code until the test goes green&lt;/em&gt;. The test is treated as ground truth.&lt;/p&gt;

&lt;p&gt;But the test isn't always right. Sometimes the failing test is the one telling the truth and the "fix" is to weaken an assertion until it stops complaining. A &lt;strong&gt;test-centric&lt;/strong&gt; loop asks a different question first: &lt;em&gt;is this failure because the code is wrong, or because the test is imprecise / asserting the wrong thing?&lt;/em&gt; If it's the test, you fix the &lt;strong&gt;test&lt;/strong&gt; — make it a sharper check — instead of bending the code to satisfy a bad check.&lt;/p&gt;

&lt;p&gt;Why this matters beyond semantics: a test that passes for the wrong reason is worse than no test. It's a &lt;strong&gt;false green&lt;/strong&gt; — it merges, it sits in CI looking like coverage, and it gives everyone permission to stop paying attention to exactly the thing it was supposed to guard. That's not coverage. That's debt wearing a coverage badge.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest caveat (this is the discipline, not a footnote)
&lt;/h2&gt;

&lt;p&gt;We could only get the paper's &lt;strong&gt;abstract&lt;/strong&gt;. No full text on arXiv, no HTML, and &lt;strong&gt;no public repo&lt;/strong&gt; — so there was no implementation to read and no methodology to verify. The paper also headlines numbers like "−60% invalid tests / +30% coverage."&lt;/p&gt;

&lt;p&gt;We are explicitly &lt;strong&gt;not&lt;/strong&gt; adopting those numbers. They're a single-source claim, measured on one microservice app, unreproduced, and from a domain that isn't ours. Porting a benchmark figure you can't reproduce into your own targets is how you manufacture a result and call it evidence. Every threshold we'd ever set has to be a &lt;em&gt;relative&lt;/em&gt; comparison against our own baseline — not "the paper got X, so we should too."&lt;/p&gt;

&lt;p&gt;So what &lt;em&gt;did&lt;/em&gt; survive the filter? One idea: &lt;strong&gt;when a test fails, first decide whether the test or the code is wrong&lt;/strong&gt; — and if it's the test, refine the test. That's it. Not the multi-agent topology, not the numbers. The one load-bearing idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this lands for us
&lt;/h2&gt;

&lt;p&gt;A test that's allowed to refine itself into a stronger check is just the natural extension of an anti-fake test gate — the kind of gate that flags a test which asserts nothing and quietly passes. Detection is step one; turning a weak test into a real check is step two. We treat a passing test as a &lt;em&gt;check that has to keep being true&lt;/em&gt;, not a one-time green tick.&lt;/p&gt;

&lt;p&gt;Half of staying current is reading the papers. The other half is the discipline to take only the one idea that's actually load-bearing for &lt;em&gt;your&lt;/em&gt; problem — and to refuse the numbers you can't reproduce.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The paper reading and the judgement about which idea was load-bearing are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>testing</category>
    </item>
    <item>
      <title>Our graph database was abandoned upstream — here's the 6-line migration (EngramGraph 0.3.0)</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Wed, 24 Jun 2026 12:00:26 +0000</pubDate>
      <link>https://dev.to/asiaostrich/our-graph-database-was-abandoned-upstream-heres-the-6-line-migration-engramgraph-030-5h1p</link>
      <guid>https://dev.to/asiaostrich/our-graph-database-was-abandoned-upstream-heres-the-6-line-migration-engramgraph-030-5h1p</guid>
      <description>&lt;p&gt;In October 2025, Kùzu Inc. archived KuzuDB — the embedded graph database — with a one-line note: "Kuzu is working on something new." The npm package was deprecated, and its transitive dependencies (&lt;code&gt;tar@6.2.1&lt;/code&gt;, &lt;code&gt;npmlog&lt;/code&gt;, &lt;code&gt;gauge&lt;/code&gt;) carried 5 high-severity vulnerabilities with no fix coming.&lt;/p&gt;

&lt;p&gt;EngramGraph runs on an embedded graph database. That database was Kuzu.&lt;/p&gt;

&lt;p&gt;EngramGraph 0.3.0 is the migration release — and the migration turned out to be far cheaper than expected. Here's why, and what we learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: ryugraph
&lt;/h2&gt;

&lt;p&gt;The community responded to KuzuDB's abandonment with several forks. We evaluated them and picked &lt;a href="https://github.com/predictable-labs/ryugraph" rel="noopener noreferrer"&gt;ryugraph&lt;/a&gt; (Predictable Labs):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MIT licensed&lt;/strong&gt;, actively maintained, published on npm&lt;/li&gt;
&lt;li&gt;Designed as a &lt;strong&gt;drop-in Kuzu replacement&lt;/strong&gt; — and in our experience, it actually is&lt;/li&gt;
&lt;li&gt;Same storage format lineage: existing &lt;code&gt;.engram/graph.db&lt;/code&gt; files keep working&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core API — &lt;code&gt;prepare()&lt;/code&gt;, &lt;code&gt;execute()&lt;/code&gt;, &lt;code&gt;query()&lt;/code&gt;, &lt;code&gt;getAll()&lt;/code&gt; — is signature-identical to kuzu. Our entire test suite (69 tests) passed on the first run after the swap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the migration was 6 lines
&lt;/h2&gt;

&lt;p&gt;One architectural decision from day one paid for itself here: &lt;strong&gt;every raw database call goes through a single thin wrapper&lt;/strong&gt; (&lt;code&gt;GraphConnection&lt;/code&gt;, ~80 lines). The other 20+ call sites in the codebase only ever see the wrapper.&lt;/p&gt;

&lt;p&gt;So the migration was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt;: &lt;code&gt;kuzu&lt;/code&gt; → &lt;code&gt;ryugraph&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;connection.ts&lt;/code&gt;: one import line&lt;/li&gt;
&lt;li&gt;Two type-only imports (&lt;code&gt;KuzuValue&lt;/code&gt; → &lt;code&gt;RyuValue&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. If your project wraps its native dependencies behind one interface, an upstream abandonment becomes an afternoon, not a quarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The leftover CVEs (and the override trick)
&lt;/h2&gt;

&lt;p&gt;Swapping kuzu killed the deprecated-toolchain CVEs, but ryugraph itself pins &lt;code&gt;cmake-js@^7.3.0&lt;/code&gt;, whose &lt;code&gt;tar@6.2.1&lt;/code&gt; carries known path-traversal CVEs. The fix exists upstream (&lt;code&gt;cmake-js@8&lt;/code&gt; uses a patched tar) — ryugraph just hasn't bumped yet.&lt;/p&gt;

&lt;p&gt;npm &lt;code&gt;overrides&lt;/code&gt; to the rescue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"overrides"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cmake-js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^8.0.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npm audit&lt;/code&gt;: &lt;strong&gt;5 high → 0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One caveat worth knowing: &lt;strong&gt;npm overrides don't propagate to downstream consumers&lt;/strong&gt;. If you depend on &lt;code&gt;engramgraph&lt;/code&gt; (or anything that depends on ryugraph), add the same override to your own &lt;code&gt;package.json&lt;/code&gt; until ryugraph bumps cmake-js upstream.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The migration, the CVE work, and the wrapper decision that made it six lines are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>security</category>
    </item>
    <item>
      <title>Seven kinds of spec ↔ test ↔ code ↔ doc drift — and why naming them makes them checkable</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Wed, 24 Jun 2026 01:10:29 +0000</pubDate>
      <link>https://dev.to/asiaostrich/make-spec-test-code-doc-drift-visible-sdd-analyze-in-uds-5170-2kli</link>
      <guid>https://dev.to/asiaostrich/make-spec-test-code-doc-drift-visible-sdd-analyze-in-uds-5170-2kli</guid>
      <description>&lt;p&gt;Spec-driven development has a quiet failure mode: your specs, tests, &lt;code&gt;.feature&lt;/code&gt; files, source, and user docs all start aligned — and then drift apart. A test loses its spec. An acceptance criterion never gets a test. A spec is marked done but was never implemented. Nobody notices until it surfaces in review or production.&lt;/p&gt;

&lt;p&gt;The problem with "are the artifacts still consistent?" is that it isn't one question. It's several, and each has a different mechanical answer. Naming them separately is what makes the check automatable instead of a review-time judgement call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seven kinds of cross-artifact drift
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Orphan test&lt;/strong&gt; — a test with no spec behind it. Either the spec was deleted, or the test is guarding something nobody agreed to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uncovered AC&lt;/strong&gt; — an acceptance criterion with no test. The requirement exists on paper and nowhere else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;not_implemented&lt;/strong&gt; — a spec marked done but absent in code. The dangerous one, because the status field asserts the opposite of the truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-spec conflict&lt;/strong&gt; — two specs that contradict each other. Whichever one you read last wins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orphan &lt;code&gt;.feature&lt;/code&gt;&lt;/strong&gt; — a feature file with no owning spec. BDD scenarios that outlived their requirement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AC-without-scenario&lt;/strong&gt; — an acceptance criterion that no BDD scenario exercises. Possibly covered by unit tests, but never described as behaviour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;user-guide ↔ E2E drift&lt;/strong&gt; — docs and end-to-end tests out of sync. Two artifacts that both claim to describe what the user sees, disagreeing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why the enumeration is the point
&lt;/h2&gt;

&lt;p&gt;Each of the seven is a link that should resolve and doesn't: spec→test, AC→test, spec→code, spec→spec, feature→spec, AC→scenario, doc→E2E. Once you state them that way, checking is a graph walk and a report of the edges that dangle — not a reading exercise.&lt;/p&gt;

&lt;p&gt;That difference matters because a consistency check performed by reading only happens when someone remembers to read. A check expressed as dangling edges can run on every commit, and the version that runs on every commit is the only one that stays true.&lt;/p&gt;

&lt;p&gt;The list is not exhaustive. It's the set that is cheap enough to check mechanically, which is exactly what makes it worth automating rather than intending.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The drift taxonomy and the decision about which links are worth checking are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>productivity</category>
      <category>testing</category>
      <category>tooling</category>
    </item>
    <item>
      <title>A hyped memory paper dropped. We didn't adopt it — and that was the point.</title>
      <dc:creator>AsiaOstrich</dc:creator>
      <pubDate>Mon, 15 Jun 2026 12:00:25 +0000</pubDate>
      <link>https://dev.to/asiaostrich/a-hyped-memory-paper-dropped-we-didnt-adopt-it-and-that-was-the-point-4de2</link>
      <guid>https://dev.to/asiaostrich/a-hyped-memory-paper-dropped-we-didnt-adopt-it-and-that-was-the-point-4de2</guid>
      <description>&lt;p&gt;Our daily scout surfaces AI-tooling papers every morning. Most weeks the disciplined answer to a shiny new architecture is "no" — and &lt;em&gt;why&lt;/em&gt; you say no is where the engineering judgment lives. Here's one worked example.&lt;/p&gt;

&lt;p&gt;In May 2026, &lt;strong&gt;SAGE: A Self-Evolving Agentic Graph-Memory Engine&lt;/strong&gt; (&lt;a href="https://arxiv.org/abs/2605.12061" rel="noopener noreferrer"&gt;arXiv:2605.12061&lt;/a&gt;) made the rounds. The pitch is genuinely good: turn graph memory from a passive retrieval middleware into a &lt;em&gt;dynamic long-term substrate&lt;/em&gt;, via two coupled components — a &lt;strong&gt;Memory Writer&lt;/strong&gt; that incrementally builds the graph from interaction history, and a &lt;strong&gt;Memory Reader&lt;/strong&gt; that retrieves &lt;em&gt;and feeds back&lt;/em&gt; to the writer. That reader→writer feedback loop is the self-evolution engine. The paper reports strong multi-hop QA results, best after two self-evolution rounds.&lt;/p&gt;

&lt;p&gt;The reflex that paper triggers in most teams: &lt;em&gt;new SOTA memory architecture — let's rebuild on it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We did the opposite. We opened our own design doc first.&lt;/p&gt;

&lt;h2&gt;
  
  
  We already had it
&lt;/h2&gt;

&lt;p&gt;EngramGraph (our open-source code + knowledge-graph memory engine) already specifies a &lt;strong&gt;SAGE Evolution Loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;Writer&lt;/strong&gt; that updates node confidence in the graph from &lt;em&gt;feedback events&lt;/em&gt; — test pass/fail, human corrections, spec-status changes;&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;Reader&lt;/strong&gt; that returns high-confidence nodes first on query, and feeds that signal back to the Writer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Line that up against the paper:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SAGE paper&lt;/th&gt;
&lt;th&gt;EngramGraph (existing design)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory Writer, incremental build&lt;/td&gt;
&lt;td&gt;Writer: feedback event → update node confidence / edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory Reader, retrieve + feed back&lt;/td&gt;
&lt;td&gt;Reader: high-confidence-first → feeds back to Writer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downstream feedback drives evolution&lt;/td&gt;
&lt;td&gt;Signals: test pass/fail, human fix, spec-status change&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Architecturally isomorphic.&lt;/strong&gt; Adopting the paper's architecture wholesale would have added roughly nothing — except a rewrite, a migration, and the risk that comes with both.&lt;/p&gt;

&lt;h2&gt;
  
  
  So we borrowed the rigor, not the architecture
&lt;/h2&gt;

&lt;p&gt;A paper that &lt;em&gt;matches&lt;/em&gt; your design is still valuable — just not as a blueprint. It's valuable as &lt;strong&gt;backing and method&lt;/strong&gt;. We extracted exactly the three things our design was actually missing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Formalization&lt;/strong&gt; — academic grounding for &lt;em&gt;why&lt;/em&gt; a reader-writer feedback loop beats static-graph retrieval. Useful when you have to defend a design, not just ship it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A validation method&lt;/strong&gt; — the paper's benchmark thinking inspired a code-graph &lt;em&gt;memory-quality yardstick&lt;/em&gt;, which moves our loop from "designed" to "measurably verified." This is the real prize: a way to prove the thing works, not just assert it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iteration-rounds design&lt;/strong&gt; — the paper's "best after two self-evolution rounds" gave us a convergence-rounds definition our loop simply didn't have.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The honest caveat (this is the part that matters)
&lt;/h2&gt;

&lt;p&gt;Here's the line we drew, in writing, before borrowing anything:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The paper's benchmarks are multi-hop QA, Natural Questions, LongMemEval, HaluMem — &lt;strong&gt;none of which is a code-graph scenario&lt;/strong&gt;. The absolute numbers do not transfer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we explicitly &lt;strong&gt;refuse to port the paper's numbers&lt;/strong&gt; into our domain. Every threshold in our borrow record is a &lt;em&gt;relative&lt;/em&gt; comparison — confidence-weighted reader vs. our own static-MERGE baseline — not "the paper got 91.6, so we should too." Cargo-culting a benchmark from dialogue memory into a code graph is exactly how you manufacture fiction and call it a result.&lt;/p&gt;

&lt;p&gt;We also wrote down what we deliberately &lt;strong&gt;did not&lt;/strong&gt; take: the paper's agent-dialogue-memory scenario doesn't fit a code graph, so its scenario-specific mechanics stay on the shelf.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why log a "no" at all
&lt;/h2&gt;

&lt;p&gt;Because a tech radar isn't a list of things you adopted. It's a record of &lt;em&gt;judgment&lt;/em&gt;. We filed SAGE as &lt;strong&gt;Trial&lt;/strong&gt;, scoped to relative validation, with the non-adoptions named. Six months from now, that record tells us — and anyone reading — not just &lt;em&gt;what&lt;/em&gt; we believed, but &lt;em&gt;how carefully&lt;/em&gt; we believed it.&lt;/p&gt;

&lt;p&gt;Half of staying current is reading everything. The other half is the discipline to take only the part that's actually load-bearing for &lt;em&gt;your&lt;/em&gt; problem.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI disclosure: I wrote this with AI assistance for English phrasing and structure. The paper reading and the decision not to adopt are my own — the AI did not supply the technical judgement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>rag</category>
    </item>
  </channel>
</rss>
