<?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: Renat</title>
    <description>The latest articles on DEV Community by Renat (@mennanov).</description>
    <link>https://dev.to/mennanov</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3819040%2F9471b1c4-0f8f-4201-9c59-7ba6ef2b4545.png</url>
      <title>DEV Community: Renat</title>
      <link>https://dev.to/mennanov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mennanov"/>
    <language>en</language>
    <item>
      <title>Your Docs Are Likely Obsolete</title>
      <dc:creator>Renat</dc:creator>
      <pubDate>Wed, 11 Mar 2026 21:42:55 +0000</pubDate>
      <link>https://dev.to/mennanov/your-docs-are-likely-obsolete-a17</link>
      <guid>https://dev.to/mennanov/your-docs-are-likely-obsolete-a17</guid>
      <description>&lt;p&gt;Every codebase I've worked on has had the same problem: documentation that was accurate when it was written but slowly drifted out of sync with the code.&lt;br&gt;
Someone adds a new enum variant or config option, the PR gets reviewed, tests pass, it ships - and nobody remembers to update the README. Three months later a new hire follows the docs and nothing works.&lt;/p&gt;

&lt;p&gt;Code reviews are supposed to catch this, but in practice "did you update the docs?" is one of the first things to slip through. It's tedious to check, easy to forget, and there's no tooling to enforce it.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://github.com/mennanov/blockwatch" rel="noopener noreferrer"&gt;&lt;strong&gt;BlockWatch&lt;/strong&gt;&lt;/a&gt; — a linter that creates explicit, machine-enforced links between code and its documentation.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;BlockWatch uses HTML-like tags inside your existing comments to define "blocks" with validation rules. The most useful rule is &lt;code&gt;affects&lt;/code&gt;: it creates a dependency between two blocks across files, so changing one will fail the linter until you update the other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawgxxruw64y5xa1p5r9s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawgxxruw64y5xa1p5r9s.gif" alt=" " width="900" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice. Say you have a Python config and a README:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;config.py:&lt;/strong&gt;&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="n"&gt;SUPPORTED_FORMATS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# &amp;lt;block affects="README.md:formats" keep-sorted&amp;gt;
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&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;toml&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;yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# &amp;lt;/block&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;README.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Supported Formats&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- &amp;lt;block name="formats" keep-sorted keep-unique&amp;gt;&lt;/span&gt; --&amp;gt;
&lt;span class="p"&gt;-&lt;/span&gt; JSON
&lt;span class="p"&gt;-&lt;/span&gt; TOML
&lt;span class="p"&gt;-&lt;/span&gt; YAML
&lt;span class="c"&gt;&amp;lt;!-- &amp;lt;/block&amp;gt;&lt;/span&gt; --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone adds &lt;code&gt;"xml"&lt;/code&gt; to the Python list and opens a PR without touching the README, CI fails with an error pointing to the exact block that needs updating.&lt;/p&gt;

&lt;p&gt;The dependency is directional: changes to the code block trigger a check on the docs block, but not the other way around. Fixing a typo in the docs won't cause a failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other validators
&lt;/h2&gt;

&lt;p&gt;Once I had the block-tagging infrastructure, other things fell out naturally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorted lists
&lt;/h3&gt;

&lt;p&gt;If you've ever spent a code review round on "please keep this list alphabetized", &lt;code&gt;keep-sorted&lt;/code&gt; automates that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;allowed_origins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# &amp;lt;block keep-sorted&amp;gt;&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;api.example.com&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app.example.com&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docs.example.com&lt;/span&gt;
  &lt;span class="c1"&gt;# &amp;lt;/block&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also sort by a regex capture group if the sort key isn't the full line:&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="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# &amp;lt;block keep-sorted="asc" keep-sorted-pattern="id: (?P&amp;lt;value&amp;gt;\d+)"&amp;gt;
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id: 1  apple&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;id: 2  banana&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;id: 10 orange&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# &amp;lt;/block&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unique entries
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;keep-unique&lt;/code&gt; prevents duplicates in lists. Like sorting, uniqueness can be scoped to a regex match — useful when you want to enforce unique IDs but the rest of the line may differ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regex validation and line counts
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;line-pattern&lt;/code&gt; checks that every line matches a pattern. &lt;code&gt;line-count&lt;/code&gt; enforces size limits (&lt;code&gt;&amp;lt;=5&lt;/code&gt;, &lt;code&gt;&amp;gt;=2&lt;/code&gt;, &lt;code&gt;==10&lt;/code&gt;, etc.). These are simple but I've found them surprisingly useful for things like slug formats and keeping generated blocks from growing unbounded.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;BlockWatch doesn't use regex to find comments — that approach breaks down quickly across 20+ languages. Instead it uses &lt;a href="https://tree-sitter.github.io/tree-sitter/" rel="noopener noreferrer"&gt;Tree-sitter&lt;/a&gt; grammars to parse source files and extract comments with actual knowledge of each language's syntax.&lt;/p&gt;

&lt;p&gt;Once comments are extracted, a &lt;a href="https://github.com/winnow-rs/winnow" rel="noopener noreferrer"&gt;winnow&lt;/a&gt;-based parser reads the block definitions. This two-stage design means adding support for a new language is mostly just wiring up its Tree-sitter grammar. Currently supported: Bash, C, C++, C#, CSS, Go (including go.mod/go.sum/go.work), HTML, Java, JavaScript, Kotlin, Makefile, Markdown, PHP, Python, Ruby, Rust, SQL, Swift, TOML, TypeScript, XML, and YAML.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;affects&lt;/code&gt; validator builds a dependency graph across files. In diff mode, it checks whether any modified block's dependents were also touched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it out
&lt;/h2&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS/Linux&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;mennanov/blockwatch/blockwatch

&lt;span class="c"&gt;# or via Cargo&lt;/span&gt;
cargo &lt;span class="nb"&gt;install &lt;/span&gt;blockwatch

&lt;span class="c"&gt;# or grab a prebuilt binary from GitHub Releases&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop a &lt;code&gt;&amp;lt;block keep-sorted&amp;gt;&lt;/code&gt; tag into any comment in your codebase and run &lt;code&gt;blockwatch&lt;/code&gt;. No config files needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diff mode
&lt;/h3&gt;

&lt;p&gt;For pre-commit hooks you probably don't want to validate the entire repo every time. You can pipe a git diff to only check blocks you actually touched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Unstaged changes&lt;/span&gt;
git diff &lt;span class="nt"&gt;--patch&lt;/span&gt; | blockwatch

&lt;span class="c"&gt;# Staged changes&lt;/span&gt;
git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--patch&lt;/span&gt; | blockwatch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also makes adoption incremental — you don't have to fix every existing issue to start using it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-commit hook
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .pre-commit-config.yaml&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blockwatch&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blockwatch&lt;/span&gt;
      &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash -c 'git diff --patch --cached --unified=0 | blockwatch'&lt;/span&gt;
      &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system&lt;/span&gt;
      &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pre-commit&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;pass_filenames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GitHub Actions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mennanov/blockwatch-action@v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparison with alternatives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Google's &lt;code&gt;keep-sorted&lt;/code&gt;&lt;/strong&gt; handles sorting but nothing else. BlockWatch covers sorting, uniqueness, drift detection, regex validation, and line count limits with a single tag syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom CI scripts&lt;/strong&gt; can do some of this but tend to be fragile and project-specific. You won't get diff-mode, Tree-sitter parsing, or cross-file dependency tracking without significant effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PR review discipline&lt;/strong&gt; is the status quo, and it works until it doesn't. The whole point of this tool is to not rely on humans remembering to do something tedious consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimental: AI validation
&lt;/h2&gt;

&lt;p&gt;There's also a &lt;code&gt;check-ai&lt;/code&gt; validator that sends block content to an LLM for validation using natural language rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- &amp;lt;block check-ai="All prices must be under $100"&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Widget A: $50&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Widget B: $150&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- &amp;lt;/block&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's optional and off by default. I wouldn't gate CI on it since LLM responses aren't deterministic, but it can be handy for local checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;The project is MIT-licensed and ships as a single binary with no runtime dependencies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/mennanov/blockwatch" rel="noopener noreferrer"&gt;github.com/mennanov/blockwatch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Action&lt;/strong&gt;: &lt;a href="https://github.com/mennanov/blockwatch-action" rel="noopener noreferrer"&gt;mennanov/blockwatch-action@v1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback and feature requests are welcome. Thanks for reading.&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
