<?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: Javier Leandro Arancibia</title>
    <description>The latest articles on DEV Community by Javier Leandro Arancibia (@javimosch).</description>
    <link>https://dev.to/javimosch</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%2F1655837%2F30baec18-fb3d-4a4b-97af-0441d12b5f28.jpg</url>
      <title>DEV Community: Javier Leandro Arancibia</title>
      <link>https://dev.to/javimosch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javimosch"/>
    <language>en</language>
    <item>
      <title>My database claimed crash-safety. `kill -9` proved nothing.</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Wed, 29 Jul 2026 18:19:04 +0000</pubDate>
      <link>https://dev.to/javimosch/my-database-claimed-crash-safety-kill-9-proved-nothing-4bp</link>
      <guid>https://dev.to/javimosch/my-database-claimed-crash-safety-kill-9-proved-nothing-4bp</guid>
      <description>&lt;p&gt;I have a small document database called &lt;a href="https://github.com/javimosch/grange" rel="noopener noreferrer"&gt;grange&lt;/a&gt;. Its README said "crash-safe by construction", and there was a harness to back it up: kill the writer with &lt;code&gt;kill -9&lt;/code&gt; mid-flight, reopen, assert the database holds exactly a committed prefix. Five rounds, every build, green.&lt;/p&gt;

&lt;p&gt;That harness proves less than it looks like it proves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;kill -9&lt;/code&gt; actually tests
&lt;/h2&gt;

&lt;p&gt;When you &lt;code&gt;kill -9&lt;/code&gt; a process, the kernel reclaims it — but everything the process wrote with &lt;code&gt;write(2)&lt;/code&gt; is already in the page cache, and the kernel flushes it to disk afterwards on its own schedule. The data survives because the &lt;em&gt;operating system&lt;/em&gt; survived.&lt;/p&gt;

&lt;p&gt;A power cut is different. So is a kernel panic. There, the page cache goes with the machine, and anything not yet on the platter is gone.&lt;/p&gt;

&lt;p&gt;My database called &lt;code&gt;write_file&lt;/code&gt; and returned success. Nothing anywhere called &lt;code&gt;fsync&lt;/code&gt;. So a commit that had been acknowledged — the client got its &lt;code&gt;{"ok":true}&lt;/code&gt; — could vanish. The harness could never have caught it, because the failure mode it simulates is the one the page cache is immune to.&lt;/p&gt;

&lt;p&gt;The README even said so, in a line I'd stopped reading:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Durability is process-crash-exact (proven by &lt;code&gt;make crash&lt;/code&gt;), OS-crash best-effort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sentence is true and completely insufficient. "Best-effort" is doing a lot of work there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two fsyncs, not one
&lt;/h2&gt;

&lt;p&gt;The fix is &lt;code&gt;fsync&lt;/code&gt;, and the part that's easy to get wrong is that one call isn't enough.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;write_file(path, data)
fsync(path)        // the file's CONTENTS are durable
fsync(dirname)     // the file's EXISTENCE is durable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating a file is a modification of its &lt;em&gt;directory&lt;/em&gt;. You can fsync a file perfectly and still lose it after a crash, because the directory entry naming it never reached the disk. The second fsync is the one people skip.&lt;/p&gt;

&lt;p&gt;A directory has to be opened &lt;code&gt;O_RDONLY&lt;/code&gt; for this — opening it for writing fails with &lt;code&gt;EISDIR&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing something invisible
&lt;/h2&gt;

&lt;p&gt;Here's the awkward part: &lt;strong&gt;fsync is invisible to behavioural tests.&lt;/strong&gt; A build that silently dropped every fsync call would pass my entire test suite. Same answers, same recovery, same everything — right up until the power goes out.&lt;/p&gt;

&lt;p&gt;So the test doesn't check behaviour. It checks syscalls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;strace &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;trace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openat,fsync ./db put ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then asserts the ordering: the chunk is fsynced, &lt;em&gt;then&lt;/em&gt; its directory. And on the disk-resident path, that every data page is fsynced &lt;em&gt;before&lt;/em&gt; the manifest that references it — because "write the manifest last" is only meaningful if that ordering is real on the platter, and the kernel is free to reorder &lt;code&gt;write()&lt;/code&gt; calls on the way there.&lt;/p&gt;

&lt;p&gt;The third check is the one I'd encourage you to steal: the opt-out (&lt;code&gt;FSYNC=0&lt;/code&gt;) must issue &lt;strong&gt;zero&lt;/strong&gt; fsyncs. That doubles as the harness's own negative control. A test that can't fail is decoration, and a test asserting the presence of something invisible needs to prove it can detect the absence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;Measured, on a commit:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;single-document commits&lt;/td&gt;
&lt;td&gt;~1.9 ms each — about 31% slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a 10,000-document batch&lt;/td&gt;
&lt;td&gt;21 ms vs 23 ms — noise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That shape is why it's on by default. A batch is one commit, so durability amortises to roughly nothing on the workload that actually moves volume. The per-commit case pays, and that's the honest price of the guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I still can't claim
&lt;/h2&gt;

&lt;p&gt;The device might be lying. Consumer drives with volatile write caches can acknowledge an &lt;code&gt;fsync&lt;/code&gt; that's still in flight, and no test running on that machine can tell. So the docs now say: fsync is called, the ordering is asserted, and whether your hardware honours it is not something this project can prove.&lt;/p&gt;

&lt;p&gt;That felt more useful than upgrading the marketing adjective.&lt;/p&gt;

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

&lt;p&gt;The harness wasn't wrong. It tested a real failure mode, correctly, and it still passes. It just wasn't testing the failure mode the word "crash-safe" makes people imagine — and the gap between those two things sat in my README for months, written down, in a sentence I'd read so many times I stopped seeing it.&lt;/p&gt;

&lt;p&gt;If you have a durability claim, go and check what your test kills. &lt;code&gt;kill -9&lt;/code&gt; and "pull the plug" are not the same experiment.&lt;/p&gt;




&lt;p&gt;grange is MIT, a single static Linux binary, and usable either as a server or compiled into your own program: &lt;a href="https://github.com/javimosch/grange" rel="noopener noreferrer"&gt;github.com/javimosch/grange&lt;/a&gt;. v0.11.0 also brings ordered queries, keyset pagination and field projection.&lt;/p&gt;

</description>
      <category>database</category>
      <category>testing</category>
      <category>go</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built a 100 KB git-like VCS that beats git on `add &amp;&amp; commit`</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sun, 26 Jul 2026 05:42:26 +0000</pubDate>
      <link>https://dev.to/javimosch/i-built-a-100-kb-git-like-vcs-that-beats-git-on-add-commit-38h8</link>
      <guid>https://dev.to/javimosch/i-built-a-100-kb-git-like-vcs-that-beats-git-on-add-commit-38h8</guid>
      <description>&lt;p&gt;I love git. I also spend a lot of time automating things, and every time a script needs to snapshot some files I end up wrapping &lt;code&gt;git&lt;/code&gt; with brittle flags and parsing porcelain output. So I wrote &lt;strong&gt;lume&lt;/strong&gt;: a tiny, content-addressed version control system in &lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin/MFL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;lume is &lt;strong&gt;git-like, not git-based&lt;/strong&gt;. It uses blobs, trees, commits, refs, and HEAD, but the storage, object format, and HTTP protocol are built from scratch. The whole thing compiles to a single &lt;strong&gt;100 KB&lt;/strong&gt; native binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benchmark that surprised me
&lt;/h2&gt;

&lt;p&gt;I compared the one workflow every developer repeats all day:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;lume add . &amp;amp;&amp;amp; lume commit -m "x"&lt;/code&gt; → &lt;strong&gt;~15 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git add . &amp;amp;&amp;amp; git commit -m "x"&lt;/code&gt; → &lt;strong&gt;~17 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On 110 small files, lume is faster. The lume binary is ~36× smaller than git (100 KB vs 3.7 MB), and the &lt;code&gt;.lume&lt;/code&gt; metadata is within 2% of &lt;code&gt;.git&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the speed comes from
&lt;/h2&gt;

&lt;p&gt;The biggest win was replacing the SQLite staging index with a line-delimited file. &lt;code&gt;lume add&lt;/code&gt; now builds a small tab-separated string and writes it once. Object subdirectories are created lazily, and blobs use a hand-rolled JSON fast path instead of generic serialization.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP push / pull / clone out of the box
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;lume serve&lt;/code&gt; starts a tiny HTTP object server. &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, and &lt;code&gt;clone&lt;/code&gt; speak plain JSON-over-HTTP. No SSH keys, no pack negotiation, no stateful transport.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Merge, rebase, and diff are still missing, and the tooling is Linux-oriented right now. But the core agent loop — init, add, commit, push, pull, clone — is fast enough to run behind automation without the automation ever knowing it is talking to a VCS.&lt;/p&gt;

&lt;p&gt;I wrote a longer post with the architecture and numbers on the &lt;a href="https://blog.intrane.fr/lume-git-like-vcs-beats-git-add-commit" rel="noopener noreferrer"&gt;Intrane blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Source, benchmarks, and build instructions are on GitHub: &lt;a href="https://github.com/javimosch/lume" rel="noopener noreferrer"&gt;github.com/javimosch/lume&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>vcs</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>rcmd now speaks MCP — your AI agent can manage your servers without SSH</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sat, 18 Jul 2026 19:28:44 +0000</pubDate>
      <link>https://dev.to/javimosch/rcmd-now-speaks-mcp-your-ai-agent-can-manage-your-servers-without-ssh-3eck</link>
      <guid>https://dev.to/javimosch/rcmd-now-speaks-mcp-your-ai-agent-can-manage-your-servers-without-ssh-3eck</guid>
      <description>&lt;p&gt;I've been building rcmd, a relay-based remote command tool. No SSH keys, no open ports — your servers connect out to a relay, and you send commands through it.&lt;/p&gt;

&lt;p&gt;Today I shipped the thing I've wanted since day one: an MCP server.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol is the standard way AI agents (Claude Code, Cursor, Windsurf, Devin) call external tools. Instead of shelling out to &lt;code&gt;ssh user@host "df -h"&lt;/code&gt; and parsing text, the agent calls a structured tool and gets JSON back.&lt;/p&gt;

&lt;h2&gt;
  
  
  What rcmd's MCP server exposes
&lt;/h2&gt;

&lt;p&gt;Four tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rcmd_list_targets&lt;/code&gt; — list your configured servers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rcmd_exec&lt;/code&gt; — run a command on a remote server, get stdout/stderr/exit code/duration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rcmd_cp&lt;/code&gt; — copy a file to a remote server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rcmd_health&lt;/code&gt; — check if a server is reachable + latency&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to set it up
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install rcmd and configure a target:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd add-target &lt;span class="nt"&gt;--name&lt;/span&gt; prod &lt;span class="nt"&gt;--token&lt;/span&gt; &amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add rcmd as an MCP server. For Claude Code (&lt;code&gt;~/.claude/mcp.json&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&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;"rcmd"&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;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rcmd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"mcp"&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same config for Cursor (&lt;code&gt;.cursor/mcp.json&lt;/code&gt;) and Windsurf (&lt;code&gt;~/.codeium/windsurf/mcp_config.json&lt;/code&gt;).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;That's it. Your AI agent can now run commands on your servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What this looks like in practice
&lt;/h2&gt;

&lt;p&gt;You ask Claude: "Check disk space on prod"&lt;/p&gt;

&lt;p&gt;Claude calls &lt;code&gt;rcmd_exec&lt;/code&gt; with &lt;code&gt;{"target": "prod", "command": "df -h"}&lt;/code&gt; and gets:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"df -h"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stdout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Filesystem      Size  Used Avail Use% Mounted on&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;/dev/vda1       40G   28G   11G  73% /"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exit_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"142ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;No SSH parsing. No "which server was that again?" No key management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;I built rcmd because SSH is friction for AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keys need to be on the right machine&lt;/li&gt;
&lt;li&gt;Firewalls block inbound ports&lt;/li&gt;
&lt;li&gt;NAT makes connecting impossible without a VPN&lt;/li&gt;
&lt;li&gt;Parsing terminal output wastes tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;rcmd's daemon connects &lt;strong&gt;out&lt;/strong&gt; to a relay. No inbound ports. No keys on the agent's machine. The MCP server reads your local rcmd config and handles the rest.&lt;/p&gt;

&lt;p&gt;The agent never sees your tokens. It only sees target names. All traffic goes through the relay with token-based auth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-host or use the hosted relay
&lt;/h2&gt;

&lt;p&gt;The relay is open source (MIT). You can self-host it in 5 minutes — one binary, one port, done. Or use the hosted one at rcmd.intrane.fr for €5/mo.&lt;/p&gt;

&lt;p&gt;Full self-hosting guide: &lt;a href="https://github.com/javimosch/remotecmd-cli/blob/main/docs/self-hosting.md" rel="noopener noreferrer"&gt;https://github.com/javimosch/remotecmd-cli/blob/main/docs/self-hosting.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MCP server docs: &lt;a href="https://github.com/javimosch/remotecmd-cli/blob/main/docs/mcp-server.md" rel="noopener noreferrer"&gt;https://github.com/javimosch/remotecmd-cli/blob/main/docs/mcp-server.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More MCP tools (cron management, tunnel setup, team operations)&lt;/li&gt;
&lt;li&gt;Resources (expose server state as MCP resources, not just tools)&lt;/li&gt;
&lt;li&gt;Streaming output for long-running commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The binary is ~6MB, single file, no dependencies. Linux + macOS, amd64 + arm64.&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;# Download from GitHub releases&lt;/span&gt;
&lt;span class="c"&gt;# Or: curl -sSL https://github.com/javimosch/remotecmd-cli/releases/latest | ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/javimosch/remotecmd-cli" rel="noopener noreferrer"&gt;https://github.com/javimosch/remotecmd-cli&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;rcmd is agent-first infrastructure. Every command returns structured JSON. Every feature is designed to be called by an AI, not just a human. The MCP server is the natural endpoint of that design.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>automation</category>
      <category>tools</category>
    </item>
    <item>
      <title>Web Analytics With No Dashboard (But There Is a 3D Globe)</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sat, 18 Jul 2026 18:27:07 +0000</pubDate>
      <link>https://dev.to/javimosch/web-analytics-with-no-dashboard-but-there-is-a-3d-globe-jn0</link>
      <guid>https://dev.to/javimosch/web-analytics-with-no-dashboard-but-there-is-a-3d-globe-jn0</guid>
      <description>&lt;p&gt;I built &lt;a href="https://github.com/javimosch/vigie" rel="noopener noreferrer"&gt;vigie&lt;/a&gt; — cookieless web analytics where the primary consumer is an AI agent, not a human staring at charts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The premise
&lt;/h2&gt;

&lt;p&gt;Every privacy-first analytics tool (Plausible, Fathom, Rybbit) assumes a human logs into a dashboard. My team is agents: they write the code, send the email, file the issues. They need analytics they can &lt;strong&gt;query and act on&lt;/strong&gt; — JSON on stdout, semantic exit codes, a machine-readable API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vigie stats overview &lt;span class="nt"&gt;--site&lt;/span&gt; example.com &lt;span class="nt"&gt;--since&lt;/span&gt; 7d
&lt;span class="c"&gt;# {"ok":true,"data":{"pageviews":1234,"visitors":410,"bounce_rate_pct":38,...}}&lt;/span&gt;
vigie stats cities &lt;span class="nt"&gt;--site&lt;/span&gt; example.com     &lt;span class="c"&gt;# geo down to city + coordinates&lt;/span&gt;
vigie stats journeys &lt;span class="nt"&gt;--site&lt;/span&gt; example.com   &lt;span class="c"&gt;# the sankey, as JSON&lt;/span&gt;
vigie stats vitals &lt;span class="nt"&gt;--site&lt;/span&gt; example.com     &lt;span class="c"&gt;# LCP/FCP/CLS/INP/TTFB p50/75/90&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When a human needs to see it
&lt;/h2&gt;

&lt;p&gt;The dashboard is an &lt;strong&gt;artifact&lt;/strong&gt;: &lt;code&gt;vigie snapshot --publish&lt;/code&gt; renders every metric (22 sections — journeys, channels, heatmap, vitals, errors, geo to city…) into one self-contained HTML page and publishes it to an artifact host. Regenerated on a timer, never stale, no frontend server to run. &lt;a href="https://hart.intrane.fr/a/vigie/report-demo" rel="noopener noreferrer"&gt;Fully-populated demo report here&lt;/a&gt; (synthetic data, labeled).&lt;/p&gt;

&lt;p&gt;And one indulgence: your traffic as a &lt;a href="https://hart.intrane.fr/a/vigie/intrane-globe" rel="noopener noreferrer"&gt;living 3D globe&lt;/a&gt; — hand-rolled canvas math, city-level dots, repaints itself from the live feed. Zero JS frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interesting constraints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cookieless by construction&lt;/strong&gt;: visitor = &lt;code&gt;sha256(secret + day + site + ip + ua)&lt;/code&gt;, daily salt rotation, raw IP never stored. Nothing to consent to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents are users too&lt;/strong&gt;: &lt;code&gt;vigie track --name deploy --actor ci&lt;/code&gt; records server-side events — your cron job is a first-class analytics stream.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One ~300 KB binary&lt;/strong&gt; (HTTP ingest + SQLite + stats engine + globe renderer + CLI), written in &lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;MFL&lt;/a&gt;, no Node/ClickHouse/Docker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo without a SaaS&lt;/strong&gt;: a MaxMind-DB (.mmdb) reader written from scratch in MFL, reading DB-IP City Lite (CC BY). ~300 lines for the binary tree walk + data-section decoder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent built the whole thing in a day, and found three compiler bugs in the process — including string literals silently corrupted by C trigraph processing (&lt;code&gt;??&lt;/code&gt; became &lt;code&gt;^&lt;/code&gt; in the globe JavaScript, surfacing as a browser SyntaxError three layers away).&lt;/p&gt;

&lt;p&gt;Full story: &lt;a href="https://blog.intrane.fr/analytics-with-no-dashboard" rel="noopener noreferrer"&gt;https://blog.intrane.fr/analytics-with-no-dashboard&lt;/a&gt;&lt;br&gt;
Repo (MIT): &lt;a href="https://github.com/javimosch/vigie" rel="noopener noreferrer"&gt;https://github.com/javimosch/vigie&lt;/a&gt;&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>I built a database my AI agent can pay for (and it beat SQLite)</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sat, 18 Jul 2026 13:03:35 +0000</pubDate>
      <link>https://dev.to/javimosch/i-built-a-database-my-ai-agent-can-pay-for-and-it-beat-sqlite-58m7</link>
      <guid>https://dev.to/javimosch/i-built-a-database-my-ai-agent-can-pay-for-and-it-beat-sqlite-58m7</guid>
      <description>&lt;p&gt;Every database assumes a human shows up eventually — to create the account, paste a card, click through a console. AI agents can't do any of that. So I built &lt;a href="https://github.com/javimosch/grange" rel="noopener noreferrer"&gt;grange&lt;/a&gt;: a document database where &lt;strong&gt;a payment wallet is the signup&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://grange.intrane.fr/tenants &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Peage-Wallet: pw_...'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name":"my agent"}'&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; {"tenant":"t...","token":"gt_..."}   your isolated, metered namespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pricing is pay-as-you-go: &lt;strong&gt;€0.15/GB/month above 50 MB free, queries free&lt;/strong&gt;, billed continuously through &lt;a href="https://peage.intrane.fr" rel="noopener noreferrer"&gt;péage&lt;/a&gt; — no subscription, no card on file, no human in the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The engine
&lt;/h2&gt;

&lt;p&gt;grange is written in &lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin&lt;/a&gt;, my language for AI agents, and two properties fell out of the language rather than being engineered in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crash-safe by construction.&lt;/strong&gt; The language has no file append or rename, so every commit is one immutable, sha256-trailered WAL chunk. &lt;code&gt;kill -9&lt;/code&gt; at any moment leaves exactly the committed prefix — the repo ships the harness that proves it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Race-free by proof.&lt;/strong&gt; The server is a single actor with zero goroutines, and machin's inferred data-race analysis verifies the whole engine on every build. No Send/Sync, no annotations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The benchmark (100k docs, both engines indexed, same box)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;workload&lt;/th&gt;
&lt;th&gt;grange&lt;/th&gt;
&lt;th&gt;SQLite&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bulk insert, 2 indexes maintained&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;278k docs/s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25k rows/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;indexed count × 1000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&amp;lt;1 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.5 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;group-by count/sum/avg × 1000&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;&amp;lt;1 ms&lt;/strong&gt; (write-time registers)&lt;/td&gt;
&lt;td&gt;49 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;range count × 1000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&amp;lt;1 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;257 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The aggregate rows aren't typos: declare &lt;code&gt;--sums&lt;/code&gt; on an index and grange maintains per-group count/sum/avg &lt;strong&gt;at write time&lt;/strong&gt; — a group-by answer costs a map lookup. The one row SQLite wins (unindexed full scan, 8ms vs 61ms) is in the README too, because a benchmark you can't lose is marketing, not measurement. &lt;code&gt;make bench&lt;/code&gt; reproduces everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dogfooding found three compiler bugs in one day
&lt;/h2&gt;

&lt;p&gt;This is why I build real things in my own language. The first bench ran 70× slow — stale compiler binary, maps were O(n). The billing math went negative — integer literals compiled to bare C constants and &lt;code&gt;30 * 86400000&lt;/code&gt; overflowed in 32-bit before widening. A WAL tombstone turned to garbage — &lt;code&gt;keys(map)&lt;/code&gt; aliased internal storage that &lt;code&gt;delete()&lt;/code&gt; freed: a use-after-free handed to me by a failing test. All three fixes went back into the language.&lt;/p&gt;

&lt;h2&gt;
  
  
  For humans: client SDKs
&lt;/h2&gt;

&lt;p&gt;Agents speak curl; humans expect drivers. So: &lt;strong&gt;Node.js&lt;/strong&gt; (&lt;code&gt;npm i grange-db&lt;/code&gt;), &lt;strong&gt;Go&lt;/strong&gt; (&lt;code&gt;go get github.com/javimosch/grange/sdk/go&lt;/code&gt;), and machin. Same surface: &lt;code&gt;db("crm").coll("leads")&lt;/code&gt;, &lt;code&gt;put/get/find/count/agg&lt;/code&gt;, bulk writes at 263k docs/s over HTTP.&lt;/p&gt;

&lt;p&gt;The full story is on my blog: &lt;a href="https://blog.intrane.fr/a-database-your-agent-can-pay-for" rel="noopener noreferrer"&gt;grange: A Database Your Agent Can Pay For&lt;/a&gt;. The contract, written for agents: &lt;a href="https://grange.intrane.fr/llms.txt" rel="noopener noreferrer"&gt;grange.intrane.fr/llms.txt&lt;/a&gt;. MIT, one binary, no lock-in.&lt;/p&gt;

</description>
      <category>database</category>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>rcmd: I replaced SSH with a relay — now my AI agents manage my servers</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sat, 18 Jul 2026 03:51:56 +0000</pubDate>
      <link>https://dev.to/javimosch/rcmd-i-replaced-ssh-with-a-relay-now-my-ai-agents-manage-my-servers-3lh4</link>
      <guid>https://dev.to/javimosch/rcmd-i-replaced-ssh-with-a-relay-now-my-ai-agents-manage-my-servers-3lh4</guid>
      <description>&lt;p&gt;I run a small infrastructure. A few VPS, some Proxmox boxes, a Raspberry Pi. Every time I needed to run a command on a remote machine, it was the same ritual: SSH key, port, firewall, VPN if the box is behind NAT. And my AI agents? They couldn't do any of it without me handing them SSH keys or setting up tunnels.&lt;/p&gt;

&lt;p&gt;So I built rcmd — a zero-config remote command execution tool. No SSH keys, no open ports, no VPN. A WebSocket relay brokers connections between your machine and remote targets. The daemon on the target connects outbound. You run the CLI. The relay routes the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You ──wss──► relay ──wss──► target daemon (runs your command, returns output)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What shipped this week
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scheduled commands (cron)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd cron add &lt;span class="nt"&gt;--target&lt;/span&gt; prod &lt;span class="nt"&gt;--schedule&lt;/span&gt; &lt;span class="s2"&gt;"0 3 * * *"&lt;/span&gt; &lt;span class="nt"&gt;--cmd&lt;/span&gt; &lt;span class="s2"&gt;"docker restart app"&lt;/span&gt;
rcmd cron list
rcmd cron logs &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;job-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relay runs a scheduler goroutine. When a job fires, it forwards the command to the target daemon. If the target is offline, the run is logged as "skipped" — no retry queue, the next tick tries again. History persists across relay restarts.&lt;/p&gt;

&lt;p&gt;This replaces the crontab + SSH + monitoring script combo with one command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Port forwarding (tunnel)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd tunnel &lt;span class="nt"&gt;--target&lt;/span&gt; db &lt;span class="nt"&gt;--local&lt;/span&gt; 5432 &lt;span class="nt"&gt;--remote&lt;/span&gt; 127.0.0.1:5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Forwards a local port to a remote address through the target daemon. Replaces &lt;code&gt;ssh -L&lt;/code&gt;. Useful for reaching a database or service that's only listening on localhost on the remote machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team access
&lt;/h3&gt;

&lt;p&gt;This is the one I'm most excited about. The problem: one token = full access to all targets. If you want a teammate or an AI agent to run commands, you either share your master token (security nightmare) or set up a separate account (no shared targets).&lt;/p&gt;

&lt;p&gt;Now you generate scoped sub-tokens:&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;# Give an operator access to prod + staging&lt;/span&gt;
rcmd team token &lt;span class="nt"&gt;--role&lt;/span&gt; operator &lt;span class="nt"&gt;--targets&lt;/span&gt; prod,staging &lt;span class="nt"&gt;--label&lt;/span&gt; &lt;span class="s2"&gt;"Bob"&lt;/span&gt; &lt;span class="nt"&gt;--expires&lt;/span&gt; 24h

&lt;span class="c"&gt;# Bob runs:&lt;/span&gt;
rcmd login tok_operator_abc123...
&lt;span class="c"&gt;# His access is scoped — he can only touch prod + staging, all audited&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three roles: &lt;strong&gt;admin&lt;/strong&gt; (everything except billing), &lt;strong&gt;operator&lt;/strong&gt; (exec, copy, tunnel, cron on assigned targets), &lt;strong&gt;viewer&lt;/strong&gt; (read-only — list targets, check health, view cron logs).&lt;/p&gt;

&lt;p&gt;Every command execution is recorded in the audit log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd team audit &lt;span class="nt"&gt;--target&lt;/span&gt; prod &lt;span class="nt"&gt;--since&lt;/span&gt; 24h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Email invites
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd team invite &lt;span class="nt"&gt;--email&lt;/span&gt; bob@company.com &lt;span class="nt"&gt;--role&lt;/span&gt; operator &lt;span class="nt"&gt;--targets&lt;/span&gt; prod,staging &lt;span class="nt"&gt;--label&lt;/span&gt; &lt;span class="s2"&gt;"Bob"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sends an HTML email with a 7-day invite code. Bob clicks the link, sees a page with the accept command and a copy-to-clipboard button, runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd team accept inv_5b97e6eeb72d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gets a scoped sub-token. Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent-first discovery
&lt;/h2&gt;

&lt;p&gt;This is the part that matters if you're building tools for AI agents. rcmd is designed to be operated by agents, not just humans. So I added three discovery surfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/llms.txt&lt;/code&gt;&lt;/strong&gt; — a short breadcrumb at &lt;code&gt;rcmd.intrane.fr/llms.txt&lt;/code&gt;. An AI assistant that only knows the domain fetches this and gets oriented.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/guide&lt;/code&gt;&lt;/strong&gt; — the full operator reference. Every command, every flag, cron scheduling, tunnels, team access, JSON output format, exit codes, gotchas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;rcmd guide&lt;/code&gt;&lt;/strong&gt; — CLI subcommand that prints the same guide locally. An agent on a machine with rcmd installed runs this to learn the full feature surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern: an agent finds itself on a machine with &lt;code&gt;rcmd&lt;/code&gt; → runs &lt;code&gt;rcmd guide&lt;/code&gt; → learns everything. An agent that only knows the domain → fetches &lt;code&gt;/llms.txt&lt;/code&gt; → gets pointed to &lt;code&gt;/guide&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why no SSH?
&lt;/h2&gt;

&lt;p&gt;SSH is designed for humans typing into terminals. It's not designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt; that need to run commands programmatically and parse output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT traversal&lt;/strong&gt; — if the target is behind NAT, you need a VPN or a jump host&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoped access&lt;/strong&gt; — SSH keys grant full shell access; there's no easy way to say "this agent can only restart this one service on this one server"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit trails&lt;/strong&gt; — SSH logs connections, not commands (unless you set up auditd or similar)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;rcmd solves these by moving the routing to a relay. The daemon connects outbound (no firewall changes). Tokens are scoped (admin/operator/viewer, target-restricted). Every command is audited. And the CLI is designed for agents — JSON output, semantic exit codes, a guide command that teaches the agent everything it can do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go binary, single file, ~7MB stripped&lt;/li&gt;
&lt;li&gt;WebSocket relay (runs on a VPS, behind Traefik + Let's Encrypt)&lt;/li&gt;
&lt;li&gt;JSON file storage (no database — teams, cron jobs, audit logs, customers)&lt;/li&gt;
&lt;li&gt;Resend for transactional email (team invites)&lt;/li&gt;
&lt;li&gt;Stripe for billing (Pro tier)&lt;/li&gt;
&lt;li&gt;21 unit tests, all passing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://rcmd.intrane.fr/install.sh | sh
rcmd signup &lt;span class="nt"&gt;--email&lt;/span&gt; you@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The free tier gives you the relay. Pro adds scheduled commands, tunnels, and team access.&lt;/p&gt;

&lt;p&gt;Full reference: &lt;code&gt;rcmd guide&lt;/code&gt; or &lt;a href="https://rcmd.intrane.fr/guide" rel="noopener noreferrer"&gt;https://rcmd.intrane.fr/guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/javimosch/remotecmd-cloud" rel="noopener noreferrer"&gt;https://github.com/javimosch/remotecmd-cloud&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by &lt;a href="https://intrane.fr" rel="noopener noreferrer"&gt;Javier Leandro Arancibia&lt;/a&gt; — making infrastructure agent-first, one tool at a time.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ssh</category>
      <category>devops</category>
      <category>saas</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I replaced ssh -L with one CLI command. No SSH keys, no VPN, no open ports.</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Fri, 17 Jul 2026 11:56:31 +0000</pubDate>
      <link>https://dev.to/javimosch/i-replaced-ssh-l-with-one-cli-command-no-ssh-keys-no-vpn-no-open-ports-91j</link>
      <guid>https://dev.to/javimosch/i-replaced-ssh-l-with-one-cli-command-no-ssh-keys-no-vpn-no-open-ports-91j</guid>
      <description>&lt;p&gt;If you manage servers, you've done this a thousand times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-L&lt;/span&gt; 5432:localhost:5432 user@prod-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. But it requires SSH keys, an open port 22, a VPN if you're behind NAT, and a running SSH daemon on the target. Every one of those is a maintenance burden and an attack surface.&lt;/p&gt;

&lt;p&gt;I just shipped &lt;code&gt;rcmd tunnel&lt;/code&gt; — port forwarding through a WebSocket relay. No SSH, no VPN, no open ports.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your laptop ──wss──► Relay ──wss──► Target daemon ──► localhost:5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The target runs a tiny daemon (~6 MB Go binary) that connects outbound to a relay. Your client connects to the same relay. The relay routes TCP data between them. That's it.&lt;/p&gt;

&lt;p&gt;Both sides connect outbound. No inbound ports. Works behind NAT, firewalls, corporate proxies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The command
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rcmd tunnel &lt;span class="nt"&gt;--target&lt;/span&gt; prod &lt;span class="nt"&gt;--local&lt;/span&gt; 5432 &lt;span class="nt"&gt;--remote&lt;/span&gt; localhost:5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;localhost:5432&lt;/code&gt; on your machine tunnels to &lt;code&gt;prod:5432&lt;/code&gt;. You can connect with &lt;code&gt;psql&lt;/code&gt;, &lt;code&gt;redis-cli&lt;/code&gt;, a browser dashboard — anything that speaks TCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can tunnel
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; — &lt;code&gt;--local 5432 --remote localhost:5432&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis&lt;/strong&gt; — &lt;code&gt;--local 6379 --remote localhost:6379&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debug dashboards&lt;/strong&gt; — &lt;code&gt;--local 8080 --remote localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jupyter notebooks&lt;/strong&gt; running on a remote GPU box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal admin panels&lt;/strong&gt; behind a firewall&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any TCP service&lt;/strong&gt; — if it speaks TCP, rcmd tunnels it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But wait, I already have SSH
&lt;/h2&gt;

&lt;p&gt;So did I. Here's why I built this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SSH requires port 22 open.&lt;/strong&gt; Every server with an open SSH port is a brute-force target. rcmd's daemon connects outbound — zero inbound ports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH key management is a tax.&lt;/strong&gt; Rotate keys, distribute them, revoke them, deal with &lt;code&gt;known_hosts&lt;/code&gt; pollution. rcmd uses per-target tokens, auto-generated, no files to manage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH doesn't work behind NAT.&lt;/strong&gt; If your server is behind a corporate firewall or NAT, you need a VPN just to reach it. rcmd works from anywhere — both sides connect outbound to the relay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH isn't built for automation.&lt;/strong&gt; Parsing SSH output in scripts is fragile. rcmd returns structured JSON for every command — stdout, stderr, exit code, duration. Built for AI agents and CI/CD pipelines.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  It's also a remote execution tool
&lt;/h2&gt;

&lt;p&gt;Tunneling is just one feature. rcmd also does:&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;# Execute a command on a remote machine&lt;/span&gt;
rcmd &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt; prod &lt;span class="nt"&gt;--cmd&lt;/span&gt; &lt;span class="s1"&gt;'docker ps'&lt;/span&gt; &lt;span class="nt"&gt;--timeout&lt;/span&gt; 10

&lt;span class="c"&gt;# Run the same command across 10 servers at once&lt;/span&gt;
rcmd &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--targets&lt;/span&gt; web1,web2,web3,db1 &lt;span class="nt"&gt;--cmd&lt;/span&gt; &lt;span class="s1"&gt;'uptime'&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; table

&lt;span class="c"&gt;# Check fleet health&lt;/span&gt;
rcmd list-targets

&lt;span class="c"&gt;# Copy files&lt;/span&gt;
rcmd &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt; prod &lt;span class="nt"&gt;--src&lt;/span&gt; ./app.tar.gz &lt;span class="nt"&gt;--dst&lt;/span&gt; /opt/app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every command returns JSON:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stdout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CONTAINER ID   IMAGE   ..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exit_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&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;No parsing. No guessing. No wasted tokens when an AI agent uses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-hosted or hosted
&lt;/h2&gt;

&lt;p&gt;Two ways to run it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free (OSS)&lt;/strong&gt;: Self-host the relay on any VPS. Unlimited targets, all features. MIT licensed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pro (€5/mo)&lt;/strong&gt;: We host the relay at rcmd.intrane.fr. Automatic TLS, no infrastructure to manage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same binary, same features. The hosted version just means you don't run the relay yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://rcmd.intrane.fr/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then either self-host a relay or &lt;code&gt;rcmd signup --email you@company.com&lt;/code&gt; for the hosted version.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Tunnel is the first of three SSH-killer features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Port forwarding&lt;/strong&gt; — shipped today&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled commands&lt;/strong&gt; — &lt;code&gt;rcmd cron add --target prod --cmd 'docker restart app' --schedule '0 3 * * *'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive shell&lt;/strong&gt; — full PTY sessions, &lt;code&gt;rcmd exec --target prod --pty&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is simple: make SSH optional for the 80% of server access that doesn't require a full interactive session.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;: &lt;a href="https://rcmd.intrane.fr" rel="noopener noreferrer"&gt;rcmd.intrane.fr&lt;/a&gt; · &lt;a href="https://github.com/javimosch/remotecmd-cli" rel="noopener noreferrer"&gt;GitHub (OSS)&lt;/a&gt; · &lt;a href="https://rcmd.intrane.fr/install.sh" rel="noopener noreferrer"&gt;Install&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Made in France. MIT licensed. Built for AI agents first, humans second.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ssh</category>
      <category>devops</category>
      <category>cli</category>
      <category>remotework</category>
    </item>
    <item>
      <title>I ran a 7B Mixture-of-Experts LLM in a language I built — token-identical to fp32</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Thu, 16 Jul 2026 19:01:45 +0000</pubDate>
      <link>https://dev.to/javimosch/i-ran-a-7b-mixture-of-experts-llm-in-a-language-i-built-token-identical-to-fp32-26m9</link>
      <guid>https://dev.to/javimosch/i-ran-a-7b-mixture-of-experts-llm-in-a-language-i-built-token-identical-to-fp32-26m9</guid>
      <description>&lt;p&gt;I've been building &lt;strong&gt;machin&lt;/strong&gt; (MFL), a machine-first language, and using it to write an LLM inference engine with &lt;strong&gt;zero dependencies&lt;/strong&gt; — no PyTorch, no llama.cpp, no BLAS, no Python at runtime. Just a static binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wall
&lt;/h2&gt;

&lt;p&gt;A dense 1B model got me ~20 tok/s on a laptop CPU. That's the ceiling, and it's &lt;em&gt;fundamental&lt;/em&gt;: decode speed is set by &lt;strong&gt;bytes moved per token&lt;/strong&gt;, and on weak hardware you're pinned to the memory bus. I built and measured every trick — speculative decoding, int4, contextual sparsity, early-exit, continuous batching. Every one topped out at ~1.35×, because the box is balanced: save bandwidth and you go compute-bound, and vice-versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The disruption isn't in the engine. It's in the model.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mixture-of-Experts
&lt;/h2&gt;

&lt;p&gt;A dense model prices every token at its &lt;em&gt;total&lt;/em&gt; params. An MoE decouples quality from speed: only a few experts fire per token. &lt;a href="https://huggingface.co/allenai/OLMoE-1B-7B-0924" rel="noopener noreferrer"&gt;OLMoE-1B-7B&lt;/a&gt; is &lt;strong&gt;6.9B total but 1.3B active&lt;/strong&gt; (top-8 of 64 experts/layer). And since only a handful fire, you &lt;code&gt;mmap&lt;/code&gt; the checkpoint and let the OS page cache &lt;strong&gt;stream cold experts from disk&lt;/strong&gt; — total size bounded by disk, not RAM.&lt;/p&gt;

&lt;h2&gt;
  
  
  It works — and it's exact
&lt;/h2&gt;

&lt;p&gt;I wrote an fp32 numpy reference reading the original weights, and checked my pure-MFL int8 engine against it token for token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numpy fp32 : The capital of France is Paris. The capital of the United States is Washington
pure MFL   : The capital of France is Paris. The capital of the United States is Washington
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;12/12 tokens identical.&lt;/strong&gt; Quantization didn't flip one.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;experts&lt;/th&gt;
&lt;th&gt;lm_head&lt;/th&gt;
&lt;th&gt;size&lt;/th&gt;
&lt;th&gt;tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;7.65 GB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14.5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int4&lt;/td&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;4.43 GB&lt;/td&gt;
&lt;td&gt;11.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;int8 lm_head buys speed (memory-bound); int4 experts buy footprint. Then I wrapped it in an OpenAI-compatible server — tokenizer and all in pure MFL — and pointed the official &lt;code&gt;openai&lt;/code&gt; client at it. Works.&lt;/p&gt;

&lt;p&gt;7B-class quality, ~1B speed, on hardware you own, no numeric libraries anywhere.&lt;/p&gt;

&lt;p&gt;Full write-up: &lt;a href="https://blog.intrane.fr/a-7b-moe-llm-at-1b-speed-in-pure-machin" rel="noopener noreferrer"&gt;https://blog.intrane.fr/a-7b-moe-llm-at-1b-speed-in-pure-machin&lt;/a&gt;&lt;br&gt;
Code (engine, converters, tokenizer, every dead end): &lt;a href="https://github.com/javimosch/machin-colibri" rel="noopener noreferrer"&gt;https://github.com/javimosch/machin-colibri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>I made my programming language run a 1B LLM at 20 tok/s on a laptop CPU (it beat the reference C by 4x)</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Sat, 11 Jul 2026 16:27:39 +0000</pubDate>
      <link>https://dev.to/javimosch/i-made-my-programming-language-run-a-1b-llm-at-20-toks-on-a-laptop-cpu-it-beat-the-reference-c-by-4jd7</link>
      <guid>https://dev.to/javimosch/i-made-my-programming-language-run-a-1b-llm-at-20-toks-on-a-laptop-cpu-it-beat-the-reference-c-by-4jd7</guid>
      <description>&lt;p&gt;I build &lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin&lt;/a&gt; — a small "machine-first" language that compiles through C, designed for AI agents to write. Its roadmap rule is simple: every feature has to be earned by dogfooding, by building something real that breaks.&lt;/p&gt;

&lt;p&gt;So I gave it an unreasonable challenge: &lt;strong&gt;run TinyLlama-1.1B on a 4-core laptop CPU at 20 tokens/second, in pure MFL.&lt;/strong&gt; No FFI. No BLAS. No llama.cpp. The matmul included.&lt;/p&gt;

&lt;h2&gt;
  
  
  The correctness bar
&lt;/h2&gt;

&lt;p&gt;LLM demos are easy to fake, so speed only counted if greedy decoding stayed &lt;strong&gt;token-for-token identical to karpathy's llama2.c&lt;/strong&gt; (&lt;code&gt;run.c&lt;/code&gt; / &lt;code&gt;runq.c&lt;/code&gt;). Every optimization below was re-verified with a per-position logits diff against the reference before it counted.&lt;/p&gt;

&lt;p&gt;The engine is ~600 lines: RoPE, GQA attention + KV cache, SwiGLU, int8/Q8_0 group quantization, and a from-scratch sentencepiece BPE encoder. (Fun find along the way: llama2.c's HuggingFace export silently breaks on GQA models — &lt;code&gt;n_kv_heads&lt;/code&gt; is hardcoded to &lt;code&gt;n_heads&lt;/code&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The arc: 2.1 → 21.8 tok/s
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.1   naive engine, single thread
2.5   -O3 -march=native on the generated C
6.1   goroutine worker pool (jobs as packed ints over channels)
8.4   peek_i8 (byte loads the autovectorizer understands)
9.9   512-bit vector width
15.7  int8 activations (i8 x i8 dot, half the loads)
21.8  dot_i8 builtin + fused qkv / w1-w3 dispatch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two lessons worth stealing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Deterministic parallelism is free performance you can trust.&lt;/strong&gt; Matmul rows fan out to a worker pool as packed-int jobs over channels; each row is computed by exactly one worker, so output is bit-identical at any thread count. I never had to choose between "fast" and "still provably correct."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Your accumulator width is your vector width.&lt;/strong&gt; The language's &lt;code&gt;int&lt;/code&gt; is 64-bit — and a 64-bit reduction forces the autovectorizer into half-width lanes. The same loop with an &lt;code&gt;int32&lt;/code&gt; accumulator is 40% faster and &lt;em&gt;inexpressible in the source language&lt;/em&gt;. So it became a builtin: &lt;code&gt;dot_i8(a, b, n)&lt;/code&gt; — the signed-byte dot product that is to quantized inference what &lt;code&gt;sha256&lt;/code&gt; is to crypto. Plain C inside, zero intrinsics; gcc's autovectorizer does the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results (TinyLlama-1.1B, Q8_0, greedy)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;runq.c -O2 reference (1 thread)      1.67 tok/s
pure-MFL engine (1 thread)           6.8  tok/s   &amp;lt;- 4x the C
6 threads, cold                     21.8  tok/s
6 threads, 200-tok sustained        19.0  tok/s   (91C thermal throttle)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Honest asterisk included: sustained generation on this thermally-limited laptop is 19.0; the same binary holds 21.8 whenever the package is under 60°C, which is what interactive bursts look like.&lt;/p&gt;

&lt;p&gt;The part I keep staring at: a garbage-collected-feeling, type-inferred language that compiles through C &lt;strong&gt;beat the hand-written reference C by 4x single-threaded&lt;/strong&gt; — because the compiler emits the loop shapes vectorizers want, and iterating was cheap enough to find them.&lt;/p&gt;

&lt;p&gt;Full story with the compiler-internals details: &lt;a href="https://blog.intrane.fr/a-1b-llm-at-20-tokens-per-second-in-pure-machin" rel="noopener noreferrer"&gt;blog.intrane.fr&lt;/a&gt;&lt;br&gt;
Engine + reproduction protocol: &lt;a href="https://github.com/javimosch/machin-colibri" rel="noopener noreferrer"&gt;github.com/javimosch/machin-colibri&lt;/a&gt;&lt;br&gt;
The ecosystem: &lt;a href="https://github.com/javimosch/awesome-machin" rel="noopener noreferrer"&gt;awesome-machin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>An AI Agent Audits Your LinkedIn Profile in Public — Here's the Stack</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:33:54 +0000</pubDate>
      <link>https://dev.to/javimosch/an-ai-agent-audits-your-linkedin-profile-in-public-heres-the-stack-1pog</link>
      <guid>https://dev.to/javimosch/an-ai-agent-audits-your-linkedin-profile-in-public-heres-the-stack-1pog</guid>
      <description>&lt;p&gt;I shipped a free tool this week: &lt;a href="https://cvboost.intrane.fr" rel="noopener noreferrer"&gt;cvboost.intrane.fr&lt;/a&gt;. Paste your LinkedIn URL, get a scored audit (6 criteria, diagnosis, action plan). No signup.&lt;/p&gt;

&lt;p&gt;The point isn't the audit — it's that an &lt;strong&gt;autonomous agent does it in public&lt;/strong&gt;, and it's a live demo of three things I build.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can watch the work happen
&lt;/h2&gt;

&lt;p&gt;No spinner-and-a-black-box. Each request becomes a &lt;strong&gt;GitHub issue&lt;/strong&gt; → an agent scores your profile and opens a &lt;strong&gt;pull request&lt;/strong&gt; with the report → a second agent reviews and merges it, no human in the loop → the report is published as a shareable page. Every step is a clickable link on the result page. It's all public: &lt;a href="https://github.com/javimosch/cvboost-audits" rel="noopener noreferrer"&gt;github.com/javimosch/cvboost-audits&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://mago.intrane.fr" rel="noopener noreferrer"&gt;mago&lt;/a&gt; — agents that run companies.&lt;/strong&gt; The audits are done by autonomous agents that take work from a GitHub repo, ship PRs, and escalate to a human only when needed. A "company" is a repo; here the team is an &lt;em&gt;auditor&lt;/em&gt; and a &lt;em&gt;reviewer&lt;/em&gt;. BYO model key, runs on your machine. CVBoost is that loop running live on every request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://hart.intrane.fr" rel="noopener noreferrer"&gt;hart&lt;/a&gt; — Claude Artifacts, self-hosted.&lt;/strong&gt; Each report is a self-contained HTML page published with one CLI call → a live, sandboxed, versioned URL. The "publish this artifact" primitive from claude.ai, unbundled and runnable on your own box, callable from any terminal agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin&lt;/a&gt; — one binary, no Node.&lt;/strong&gt; The whole app — SSR site, reactive WebAssembly UI, and JSON API — is a single static native binary. No Node, no bundler, no node_modules. The browser client compiles to wasm from the same language as the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why free
&lt;/h2&gt;

&lt;p&gt;It's the shop window, not the product: watch an agent do real work end to end, traceably, instead of trusting a landing page. Try it → &lt;a href="https://cvboost.intrane.fr" rel="noopener noreferrer"&gt;cvboost.intrane.fr&lt;/a&gt;, then open the PR the agent left behind. Full story: &lt;a href="https://blog.intrane.fr/an-ai-agent-audits-your-linkedin-in-public" rel="noopener noreferrer"&gt;blog.intrane.fr/an-ai-agent-audits-your-linkedin-in-public&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your AI Assistant Can Run Your Website Chatbot Now</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Mon, 06 Jul 2026 16:29:30 +0000</pubDate>
      <link>https://dev.to/javimosch/your-ai-assistant-can-run-your-website-chatbot-now-36e9</link>
      <guid>https://dev.to/javimosch/your-ai-assistant-can-run-your-website-chatbot-now-36e9</guid>
      <description>&lt;p&gt;I shipped &lt;a href="https://chatsnip.intrane.fr" rel="noopener noreferrer"&gt;chatsnip&lt;/a&gt; this week: a chatbot for your landing page that you install by pasting one script tag — and that &lt;strong&gt;your AI assistant operates for you&lt;/strong&gt;. No dashboard. You never log into anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two sins of chatbot SaaS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The dashboard tax.&lt;/strong&gt; Every chatbot product ships an admin panel you must learn, configure, and babysit. You wanted answers on your landing page; you got another SaaS subscription to manage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The token markup.&lt;/strong&gt; Most resell LLM completions at 5–20x wrapped in "message credits". Your bill scales with your success.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bet: agents are the new admin panel
&lt;/h2&gt;

&lt;p&gt;If you're reading dev.to in 2026, you probably already have an AI assistant with a terminal — Claude Code, Codex, whatever. That assistant is better at operating software than any dashboard.&lt;/p&gt;

&lt;p&gt;So chatsnip has none. After checkout you get a &lt;strong&gt;prompt&lt;/strong&gt; — a block of text you paste to your assistant. It installs a small CLI, interviews you about your product, configures the bot, sets your spend limits, and hands you the script tag. Ongoing ops are one weekly command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./chatsnip hosted digest &lt;span class="nt"&gt;-since&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ &lt;em&gt;"37 conversations — 5 support, 1 complaint (contact captured), and a lead named Sam who left &lt;a href="mailto:sam@dev.io"&gt;sam@dev.io&lt;/a&gt; asking for a call about the Pro plan."&lt;/em&gt; When visitors show buying intent or frustration, the bot offers a personal founder follow-up and asks for contact info. Those get extracted automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your keys, your costs
&lt;/h2&gt;

&lt;p&gt;Completions run on &lt;strong&gt;your own OpenRouter key&lt;/strong&gt; (encrypted at rest). Pick any model, see real LLM spend on your own bill, set your own budgets: tokens/day, tokens/visitor, messages/minute. I don't resell tokens, so I have zero incentive to inflate your conversation volume — my price is flat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Absurdly small, on purpose
&lt;/h2&gt;

&lt;p&gt;The widget is ~6 KB of dependency-free JS — no iframe, no framework, no cookie banner. The entire backend (HTTP server, SQLite, LLM client, billing, CLI) is a single ~240 KB native binary written in &lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin&lt;/a&gt;, a language I've been building for AI agents. Self-hosting means: one file, one command, a €3 VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-host: $79 one-time&lt;/strong&gt; (launch price) — binary + a year of updates through your personal install URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted: €19/mo&lt;/strong&gt;, 7-day free trial, 5 chatbots/sites included, +€2/mo per extra.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full story on my blog: &lt;a href="https://blog.intrane.fr/your-ai-assistant-can-run-your-website-chatbot-now" rel="noopener noreferrer"&gt;Your AI Assistant Can Run Your Website Chatbot Now&lt;/a&gt; — or watch your own assistant set it up at &lt;a href="https://chatsnip.intrane.fr" rel="noopener noreferrer"&gt;chatsnip.intrane.fr&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatbot</category>
      <category>saas</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Day My Language Started Compiling Itself</title>
      <dc:creator>Javier Leandro Arancibia</dc:creator>
      <pubDate>Wed, 01 Jul 2026 15:42:32 +0000</pubDate>
      <link>https://dev.to/javimosch/the-day-my-language-started-compiling-itself-330k</link>
      <guid>https://dev.to/javimosch/the-day-my-language-started-compiling-itself-330k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (v0.85.0):&lt;/strong&gt; it went further — the &lt;em&gt;entire toolchain&lt;/em&gt; now self-hosts, not just the compiler. &lt;code&gt;encode&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, and &lt;code&gt;run&lt;/code&gt; are written in machin too, so machin rebuilds its own toolchain from source, &lt;strong&gt;byte-for-byte identical&lt;/strong&gt; — a complete bootstrap. &lt;a href="https://github.com/javimosch/machin/tree/main/selfhost" rel="noopener noreferrer"&gt;&lt;code&gt;selfhost/&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A year ago I built a programming language. This year it crossed the line that separates a toy from a real compiler: &lt;strong&gt;it started compiling itself.&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foqmvzob4yh2wgyh705x2.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foqmvzob4yh2wgyh705x2.gif" alt="watch machin compile itself" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(That GIF is the real thing — machin compiling its own compiler, then that binary reproducing its own source byte-for-byte.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That sentence sounds like a party trick. It isn't. It's one of the oldest and hardest proofs in systems engineering — and reaching it, with AI as my pair, is the clearest evidence I can offer of how I actually build software.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the backstory
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/javimosch/machin" rel="noopener noreferrer"&gt;machin&lt;/a&gt; is a language I designed for a specific user: &lt;strong&gt;the AI agent writing the code&lt;/strong&gt;, not the human reading it. Zero type annotations, one canonical declaration per line, every design choice measured in tokens — then compiled straight through C to a single native binary. Script-like to write, C-class to run. (I wrote about &lt;em&gt;why&lt;/em&gt; &lt;a href="https://dev.to/why-i-built-a-language-for-ai-agents"&gt;in an earlier post&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;For a year it grew the way real tools grow — by being used. Web servers, database drivers, a WebSocket client, crypto, even games. But a language is only as trustworthy as its compiler, and machin's compiler was written in Go. So I asked the question every language eventually has to answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Could machin compile itself?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What "compiles itself" actually means
&lt;/h2&gt;

&lt;p&gt;Every serious compiler faces a rite of passage called the &lt;strong&gt;bootstrap&lt;/strong&gt;. You rewrite the compiler &lt;em&gt;in its own language&lt;/em&gt;, and then you use the original to compile the new one. If the language is real — expressive enough, correct enough, fast enough — the new compiler works. If it isn't, you find out fast.&lt;/p&gt;

&lt;p&gt;The gold standard is the &lt;strong&gt;fixpoint&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The original compiler builds the self-hosted one.&lt;/li&gt;
&lt;li&gt;That self-hosted compiler compiles &lt;em&gt;its own source&lt;/em&gt; into a fresh native binary.&lt;/li&gt;
&lt;li&gt;That fresh binary compiles the same source again — and the output is &lt;strong&gt;byte-for-byte identical.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When those bytes match, you have proof that isn't a matter of opinion. The compiler has reproduced itself exactly. It stands on its own.&lt;/p&gt;

&lt;p&gt;Machin now does this. The whole pipeline — lexer, parser, type checker, and C code generator, about 4,000 lines — is written &lt;em&gt;in machin&lt;/em&gt;, and it emits the same machine code as the original compiler down to the byte.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it was actually built (this is the part that matters)
&lt;/h2&gt;

&lt;p&gt;I don't ship "it works on my machine." I ship &lt;em&gt;proof&lt;/em&gt;. So every single stage was built against a &lt;strong&gt;byte-diff oracle&lt;/strong&gt;: the original compiler and the new one were run on the same input and their output compared, character for character, across the entire ecosystem of real programs I'd already written. A stage wasn't "done" until that diff was empty — not on a test case, but on &lt;strong&gt;every&lt;/strong&gt; program in the corpus.&lt;/p&gt;

&lt;p&gt;That discipline paid for itself immediately. Building the compiler in its own language stress-tested the language harder than a year of app-building had, and it flushed out &lt;strong&gt;three genuine bugs&lt;/strong&gt; in the original compiler that had been hiding in plain sight — a string-comparison that compared memory addresses instead of contents, a quadratic slowdown in string handling, an escaping edge case in code generation. Each was found because the self-hosted compiler and the reference disagreed by a byte, and I refused to wave it away.&lt;/p&gt;

&lt;p&gt;Then the honest numbers. The self-hosted compiler doesn't just work — on the full parse-typecheck-codegen of its own source, it runs at about &lt;strong&gt;0.9× the original's speed&lt;/strong&gt;. Slightly &lt;em&gt;faster&lt;/em&gt; than the compiler that built it. (It didn't start there — the first version was 7× slower, and closing that gap meant finding the real bottleneck instead of the obvious-looking one. It was string building, not the "slow lookups" everyone assumes.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm telling you this
&lt;/h2&gt;

&lt;p&gt;Because this is what I mean when I say I build with AI.&lt;/p&gt;

&lt;p&gt;Not "I prompted a chatbot and shipped whatever came out." The opposite. AI was the engine, but the &lt;em&gt;engineering&lt;/em&gt; — the oracles, the byte-level verification, the refusal to accept a passing test over a passing proof, the honesty about what's fast and what isn't — that's the part that makes the output trustworthy. AI without that rigor produces plausible code. AI &lt;em&gt;with&lt;/em&gt; it produces a compiler that compiles itself, byte-for-byte, and you can go check the bytes.&lt;/p&gt;

&lt;p&gt;That combination — senior engineering judgment as the guardrail, AI as the multiplier — is exactly what I bring to the systems I build for clients at &lt;a href="https://intrane.fr" rel="noopener noreferrer"&gt;Intrane&lt;/a&gt;. Most teams get one or the other: rigor without speed, or speed without rigor. The interesting work lives where they meet.&lt;/p&gt;

&lt;p&gt;A language that compiles itself is a hard, verifiable, slightly obsessive proof that they can meet. If that's the kind of engineer you want on your hardest problem, &lt;a href="https://intrane.fr/#contact" rel="noopener noreferrer"&gt;let's talk&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;machin is open source (MIT) — the self-hosting compiler lives in &lt;a href="https://github.com/javimosch/machin/tree/main/selfhost" rel="noopener noreferrer"&gt;&lt;code&gt;selfhost/&lt;/code&gt;&lt;/a&gt;, and you can reproduce the fixpoint yourself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>compilers</category>
      <category>ai</category>
      <category>programming</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
