<?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: Masahiko Ebisuda</title>
    <description>The latest articles on DEV Community by Masahiko Ebisuda (@ebibibi).</description>
    <link>https://dev.to/ebibibi</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%2F4078938%2Fde9c270e-09a2-4fe1-99a0-e979e758a3e6.png</url>
      <title>DEV Community: Masahiko Ebisuda</title>
      <link>https://dev.to/ebibibi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ebibibi"/>
    <language>en</language>
    <item>
      <title>AI Agents Yield to Each Other in the "Break Room" — A Month in My DIY Discord Bridge</title>
      <dc:creator>Masahiko Ebisuda</dc:creator>
      <pubDate>Mon, 17 Aug 2026 01:02:17 +0000</pubDate>
      <link>https://dev.to/ebibibi/ai-agents-yield-to-each-other-in-the-break-room-a-month-in-my-diy-discord-bridge-5gf1</link>
      <guid>https://dev.to/ebibibi/ai-agents-yield-to-each-other-in-the-break-room-a-month-in-my-diy-discord-bridge-5gf1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://veritastracto194617.substack.com/p/ai-agents-yield-to-each-other-in" rel="noopener noreferrer"&gt;my Substack&lt;/a&gt;. I'm a Microsoft MVP based in Japan, writing in English about the AI agent systems I actually run in production.&lt;/em&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;🤖✍️ This article was co-written with AI — the AI agent (Claude Code) generated the draft based on actual collaborative work with Ebisuda, who then reviewed and edited it before publishing. Before starting to write this very article, the session posted a self-introduction in the "AI break room" described later in the piece.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is about &lt;strong&gt;CCDB (Claude &amp;amp; Codex Discord Bridge)&lt;/strong&gt;, the open-source tool I built for running Claude and Codex from Discord.&lt;/p&gt;

&lt;p&gt;The last time I wrote about this series was &lt;strong&gt;June 18, 2026&lt;/strong&gt; , in an article titled "Fire off tasks to Claude or Codex from your browser with one tap — how I added 'safe LAN exposure' to my DIY Discord Bridge," which covered &lt;strong&gt;v3.1.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;About a month has passed since then. Before I knew it, the version had gone from &lt;strong&gt;v3.1.0 → v3.2.4&lt;/strong&gt; , and it had quietly become a different tool. Even I found myself thinking "wait, where did I leave off last time?" — so this post is a roundup of what changed over the past month. This time, it's all free.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/ebibibi/claude-code-discord-bridge" rel="noopener noreferrer"&gt;https://github.com/ebibibi/claude-code-discord-bridge&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CCDB, anyway? (30-second version)
&lt;/h2&gt;

&lt;p&gt;Just send a message from the Discord app on your phone, and behind the scenes the Claude Code or Codex CLI springs into action — reading and writing code, running tests, even opening a PR. It's a tool that turns Discord into a doorway for AI coding.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One thread = one AI session.&lt;/strong&gt; You can run a new feature in thread A, a PR review in thread B, and documentation in thread C, all &lt;strong&gt;in parallel&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each session is isolated in its own &lt;strong&gt;git worktree&lt;/strong&gt; , so running them simultaneously doesn't cause conflicts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backend can be switched between Claude and Codex per thread via &lt;strong&gt;/backend&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the previous article, I described adding a feature that lets you "safely expose only the safe entry points of your own machine's API from outside, while keeping the dangerous parts closed" — that is, exposing &lt;strong&gt;/api/ingest&lt;/strong&gt; externally. That's what made it possible to say "send this whole page to the AI" from a browser extension.&lt;/p&gt;

&lt;p&gt;So what's changed since then? There are three headline items.&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  ① AI sessions can now "see, yield, talk to, and warn" each other (v3.2.0)
&lt;/h2&gt;

&lt;p&gt;This is the biggest change of the past month.&lt;/p&gt;

&lt;p&gt;Until now, multiple AI sessions running in parallel could only &lt;strong&gt;post self-introductions&lt;/strong&gt; to a shared bulletin board called the "AI Lounge (break room)." A session would post "I'm currently looking at a bug in the XXX repo," but another session reading that post &lt;strong&gt;couldn't actually do anything concrete about it&lt;/strong&gt;. It was basically just talking to itself on a bulletin board.&lt;/p&gt;

&lt;p&gt;In v3.2.0, &lt;strong&gt;four layers&lt;/strong&gt; were added on top of this. And all of them are designed to be "enabled by default, dormant until sessions actually overlap" (Zero-Config).&lt;/p&gt;

&lt;h3&gt;
  
  
  See
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;GET /api/sessions&lt;/strong&gt; returns a list of who's currently alive, where, and doing what. It even surfaces sessions that were just born, before anything has been recorded to the DB yet — because &lt;strong&gt;the sessions most likely to collide are exactly the ones at that moment&lt;/strong&gt;. &lt;strong&gt;GET /api/threads/{id}/messages&lt;/strong&gt; also lets you peek directly at the conversation in another thread.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yield (Avoid)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; starting work, a session can place an "advisory lock" reservation tag on a resource.&lt;/p&gt;

&lt;p&gt;POST /api/claims resource: "repo:ccdb#issue-123"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If it succeeds, you get &lt;strong&gt;201&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If someone already holds it, you get &lt;strong&gt;409&lt;/strong&gt; — along with &lt;strong&gt;who holds it and for what purpose&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Couldn't get the lock. Guess I'll do something else instead" can now happen entirely between AI sessions, without human involvement. Locks have a TTL (2 hours by default), so a dead session can't hold a resource hostage forever. This is the "cheap half" of coordination — it &lt;strong&gt;uses no AI calls at all&lt;/strong&gt; (i.e., consumes no tokens).&lt;/p&gt;

&lt;h3&gt;
  
  
  Talk
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;POST /api/threads/{id}/message&lt;/strong&gt; lets one session deliver a message directly to another live session. &lt;strong&gt;mode=queue&lt;/strong&gt; waits for the other session's turn to finish, while &lt;strong&gt;mode=interrupt&lt;/strong&gt; breaks in with "stop right now."&lt;/p&gt;

&lt;p&gt;What's interesting is that the decision rule for &lt;strong&gt;who continues and who steps back&lt;/strong&gt; is embedded in the shared prompt. The order is deterministic: "already committed / has a PR &amp;gt; still investigating" → "whoever started earlier" → "whoever has the smaller thread ID." Since both sides run the same calculation, they arrive at &lt;strong&gt;the same conclusion&lt;/strong&gt; , so it never gets stuck in an endless "after you" / "no, after you" loop. Whichever session steps back always &lt;strong&gt;pushes its own branch first&lt;/strong&gt; before backing off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be warned
&lt;/h3&gt;

&lt;p&gt;The three mechanisms above all assume a session says something explicitly. This fourth one catches &lt;strong&gt;collisions no one declared&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each session's file writes (Write / Edit / MultiEdit) are logged, and if &lt;strong&gt;two sessions write to the same file within 15 minutes&lt;/strong&gt; , it's treated as a collision, and a warning is posted to the break room and both threads. The key point here is checking by &lt;strong&gt;file path, not working directory&lt;/strong&gt;. On a single-user machine, all sessions share the same &lt;strong&gt;$HOME&lt;/strong&gt; , so comparing by directory would flag &lt;strong&gt;every pair as colliding&lt;/strong&gt; , making the check meaningless. I've been squashing these "looks reasonable but is actually useless" traps one by one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Incidentally, &lt;strong&gt;this very article&lt;/strong&gt; was written on top of this mechanism. The session that started writing first posted a self-introduction in the break room saying "I'm going to write an article about CCDB," checked whether any other session was touching the same repo, claimed the work, and then started writing. It's a case of writing an article about a feature using that very feature.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  ② Search that solves "wait, where did that conversation go?" (v3.2.1 onward)
&lt;/h2&gt;

&lt;p&gt;Discord threads get auto-archived after a period of inactivity and disappear from the sidebar (hidden, not deleted). Titles are often generic too, so "which thread was that thing I did before?" tended to become a &lt;strong&gt;missing-persons case&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I added two-tier search. Neither one &lt;strong&gt;uses a single AI token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1: /search &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CCDB already stores the "first prompt" of each session as a summary, so this is a &lt;strong&gt;LIKE&lt;/strong&gt; search against that. No new storage, no re-indexing needed. Each matching thread comes with a &lt;strong&gt;Discord deep link&lt;/strong&gt; , so even archived threads can be reopened with one click.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2: /search body:True (full-text search)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For when you want to find a keyword that appeared &lt;strong&gt;partway through a conversation&lt;/strong&gt; , not in the first prompt. Since Claude Code writes out the entire conversation to &lt;strong&gt;~/.claude/projects/…jsonl&lt;/strong&gt; , this &lt;strong&gt;grep&lt;/strong&gt; s through those files (it doesn't use &lt;strong&gt;shell=True&lt;/strong&gt; ; the keyword is passed as a literal string after &lt;strong&gt;--&lt;/strong&gt; , so it can't be abused as a flag or regex). I actually validated this against &lt;strong&gt;709MB across 5,400 files&lt;/strong&gt; of real data — each query completes within 2 seconds and matches both Japanese and English.&lt;/p&gt;

&lt;p&gt;Rather than "having the AI search," it's "using ordinary search to pull up the traces the AI already left behind." Not burning tokens is my favorite part of this.&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  ③ Long threads can now be sent as "just the diff" (latest)
&lt;/h2&gt;

&lt;p&gt;This follows on from the &lt;strong&gt;/api/ingest&lt;/strong&gt; feature (sending a whole page from the browser) covered in the previous article.&lt;/p&gt;

&lt;p&gt;Consider a case like replying to the same long Teams thread for months on end. Since CCDB is designed to spin up a new session for every ingest call, it had to &lt;strong&gt;resend the entire thread every time&lt;/strong&gt; just to convey context. Sending months' worth of history every single time was way too wasteful.&lt;/p&gt;

&lt;p&gt;So now, for each stable key the client specifies (e.g., the ID of the first message in a Teams thread), the server keeps a &lt;strong&gt;running summary&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Before sending, the client calls &lt;strong&gt;GET /api/ingest/summary?key=…&lt;/strong&gt; to fetch the "stored summary" and "how far it's already been read (marker)"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The client exports and sends &lt;strong&gt;only the diff since then&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The session gets full context from "stored summary + diff," and once done, updates and saves the summary&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;strong&gt;marker&lt;/strong&gt; advances based on the server's own ingest records, so &lt;strong&gt;the read position only moves forward once the summary has actually been saved&lt;/strong&gt;. If a session fails, it can just resend the same diff without dropping any messages. And of course, if you don't specify a key, everything works exactly as before (Zero-Config).&lt;/p&gt;

&lt;p&gt;From "send the full thing every time" to "diff plus server-side memory." It's a quiet change, but it pays off over long-term operation.&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  Other small improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Codex model/reasoning strength is now configurable&lt;/strong&gt; : dropped the hardcoded fixed model &lt;strong&gt;gpt-5.4&lt;/strong&gt; in favor of following &lt;strong&gt;the Codex CLI's own default&lt;/strong&gt; when no model is specified (so it won't silently go stale). &lt;strong&gt;/effort&lt;/strong&gt; also lets you switch reasoning strength per backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/api/spawn can now post attachments to a new thread&lt;/strong&gt; : when watching a Forgejo issue/PR to spin up a thread, issue attachments are now carried over and visible too&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;(Security fix) Closed a hole in mention-only channels&lt;/strong&gt; : fixed a path where, in channels configured to "only respond when @mentioned," a thread manually created by a human could unintentionally spawn a session&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Squashed several minor parser bugs, including one where the Codex backend's progress display would get stuck showing "Running… Ns elapsed" forever&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion — "running things in parallel without incidents" keeps getting more real
&lt;/h2&gt;

&lt;p&gt;A month ago, things were at the stage of "made it possible to safely poke the entry point from outside." Since then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiple AIs now notice each other, yield to each other, and talk it out to avoid collisions when needed&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Past work can be dug back up without spending tokens&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Long conversations can continue with just diffs&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's been a month that moved straight in the direction of "&lt;strong&gt;keep lots of AI sessions running without incidents, without a human having to watch over them&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;What's fun is that this coordination feature directly powers CCDB's own development. New CCDB features get built by multiple AI sessions working in parallel through CCDB itself, exchanging messages in the break room like "I'm working on that right now, hold on a sec." There's a real sense of the tool becoming its own scaffolding for building itself, and that's the part I enjoy most.&lt;/p&gt;

&lt;p&gt;It's all open source, so take a look if you're curious.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/ebibibi/claude-code-discord-bridge" rel="noopener noreferrer"&gt;https://github.com/ebibibi/claude-code-discord-bridge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>automation</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Asked the Same Question to 7 Local LLMs — Speed and Intelligence Didn't Line Up: DGX Spark Benchmarks</title>
      <dc:creator>Masahiko Ebisuda</dc:creator>
      <pubDate>Sun, 16 Aug 2026 01:01:37 +0000</pubDate>
      <link>https://dev.to/ebibibi/i-asked-the-same-question-to-7-local-llms-speed-and-intelligence-didnt-line-up-dgx-spark-4mg1</link>
      <guid>https://dev.to/ebibibi/i-asked-the-same-question-to-7-local-llms-speed-and-intelligence-didnt-line-up-dgx-spark-4mg1</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://veritastracto194617.substack.com/p/i-asked-the-same-question-to-7-local" rel="noopener noreferrer"&gt;my Substack&lt;/a&gt;. I'm a Microsoft MVP based in Japan, writing in English about the AI agent systems I actually run in production.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Local AI models keep multiplying. But comparing numbers on model cards alone doesn't tell you which one to actually use.&lt;/p&gt;

&lt;p&gt;Does a higher parameter count mean smarter? Does MoE mean faster? If a model is popular on AI Arena, is it good for my own work? Each question offers a partial clue, but in the end you can't decide without running the same task through the models yourself.&lt;/p&gt;

&lt;p&gt;So this time, I ran the exact same Japanese question through 7 major models running on a single NVIDIA DGX Spark. That includes NVIDIA's Nemotron 3 Super 120B-A12B, for which I actually deployed the large quantized version.&lt;/p&gt;

&lt;p&gt;What I compared wasn't just tokens/s.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Whether the answer finished in the specified format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether it made claims that would be risky in real business use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What caveats it raised&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether any model couldn't answer without changing its settings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results didn't shake out into a clean "bigger model = better" story. One model was fast but gave an answer too risky to show a customer as-is. Another had excellent timing but dropped the instruction to provide 3 items. And one 120B model, after thinking as hard as it could, ended up with a completely empty answer field.&lt;/p&gt;

&lt;p&gt;So which model struck the best balance for short business-style answers? And did Nemotron 3 Super prove that its 87GB of weights are worth it compared to a 23GB-class model? Below I lay out the raw measurements and every full answer, unedited.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖✍️ This article was co-written with AI — AI agents (Claude Code / Codex) generated the draft based on actual collaborative work with Ebisuda and real measurement data, and Ebisuda reviewed and edited the content before publishing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📘 The infrastructure behind my workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ebi Workspace — Never forgetting experimental conditions and decisions
&lt;/h3&gt;

&lt;p&gt;To keep observing while only swapping out the model, you need to keep the previous conditions, raw logs, and the reasoning behind each decision in one place. I use "Ebi Workspace," a plugin compatible with Claude Code / Codex, to manage the project's current state and measurement records in Obsidian.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://note.com/ebibibi/n/n300772aeac93" rel="noopener noreferrer"&gt;Claude Code / Codex That Never Forgets, Never Gets Lost — Ebi Workspace&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Ebi Agent Chat Relay — Driving real hardware work from Discord
&lt;/h3&gt;

&lt;p&gt;I handle model deployment, measurement, and article writing from Discord through the open-source "Ebi Agent Chat Relay." It's a conversation and coordination framework that splits multiple AI sessions into separate threads, letting them run while avoiding conflicts over the same work targets.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/ebibibi/ebi-agent-chat-relay" rel="noopener noreferrer"&gt;Ebi Agent Chat Relay (GitHub)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Same input, watching speed and answer quality together
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://substackcdn.com/image/fetch/$s_!wfVl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff82903d2-8c49-41df-974d-da62470dfe32_1280x672.jpeg" rel="noopener noreferrer"&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%2Fbtt13xyhm34x3fdj7l6q.jpeg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used the GB10 in a DGX Spark. The unified memory available from the OS is about 121GiB, and Ollama is version 0.32.9. I fixed the comparison conditions as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;temperature: 0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;seed: 42&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;context: 8192&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Max generation budget: 320 tokens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;thinking: OFF&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One cold run after unloading each model, followed by 3 warm runs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Primary comparison: average response time across the 3 warm runs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optimizing each model individually toward its own recommended settings would blend configuration differences together with model differences. So I kept the primary comparison on common conditions, and only ran separate diagnostics to check the cause for any model that couldn't answer under those common conditions.&lt;/p&gt;

&lt;p&gt;The question posed a scenario where a small or midsize business wants to adopt generative AI without sending customer data to an external cloud AI. I asked the models to list 3 tasks suited to local AI, with each item written as a single line in the form "Task name: reason / caveat," followed by a short adoption verdict at the end. I also prohibited inventing product names or law names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed first: more than a 14x gap between the fastest and slowest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://substackcdn.com/image/fetch/$s_!x0Lw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52200e5c-4b50-43ad-81f0-09436c84c17d_1280x672.jpeg" rel="noopener noreferrer"&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%2Fjy59z9t24f0jhs5gf1ap.jpeg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The warm averages ranked as follows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Qwen3.5 35B — 1.49s, 76.27 tokens/s, followed the format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GLM-4.7-Flash — 1.94s, 64.64 tokens/s, broke the format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Qwen3.6 35B-A3B — 2.12s, 44.72 tokens/s, followed the format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GPT-OSS 120B — 8.98s, displayed answer was empty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nemotron 3 Super 120B-A12B — 9.09s, 20.36 tokens/s, followed the format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gemma 4 31B — 9.81s, 10.41 tokens/s, followed the format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Qwen2.5 72B — 21.68s, 4.42 tokens/s, followed the format&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For short-form responses, Qwen3.5 is overwhelmingly the fastest. But looking at the actual answer shows why deciding on speed alone is dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fastest model, Qwen3.5, also returned its risky claim the fastest
&lt;/h2&gt;

&lt;p&gt;Here's Qwen3.5 35B's answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Customer support log analysis: zero risk of confidential data leakage / need to check the balance between processing speed and accuracy&lt;/p&gt;

&lt;p&gt;Internal document summarization and drafting: no need to send materials externally even when they contain personal information / depends on the quality of the training data&lt;/p&gt;

&lt;p&gt;Business rule matching system: can reference confidential internal regulations with high security / incurs initial setup costs&lt;/p&gt;

&lt;p&gt;Adoption verdict: when handling highly confidential customer data, local AI is a valid option.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The format is clean. But "zero risk of leakage" is an overstatement. Even with local deployment, risks remain from device compromise, permission settings, logs, backups, and data being carried out. The fastest number on the clock and an answer quality you could adopt for business as-is didn't line up.&lt;/p&gt;

&lt;h2&gt;
  
  
  At just over 2 seconds, Qwen3.6 was the most practical for this one question
&lt;/h2&gt;

&lt;p&gt;Here's Qwen3.6 35B-A3B's answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using internal data: avoids the risk of customer information leakage / requires specialized knowledge to set up the environment&lt;/p&gt;

&lt;p&gt;Internal document summarization: drafting meeting minutes where confidentiality is essential / improving accuracy requires curating training data&lt;/p&gt;

&lt;p&gt;Handling business FAQs: responding to inquiries that include personal information / building a verification process to prevent incorrect answers&lt;/p&gt;

&lt;p&gt;Adoption verdict: carefully weigh the balance between securing safety and operational load, and roll it out in stages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It raised distinct caveats — environment setup, training data, and a verification process for incorrect answers — and kept its final verdict to a staged rollout. It followed the format in 2.12 seconds.&lt;/p&gt;

&lt;p&gt;This is purely my editorial judgment on this one question, but for short, structured Japanese business answers, Qwen3.6 would be my first candidate. It wasn't the fastest, but it struck the best balance between speed and answer quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nemotron 3 Super wasn't slow — its answer was long and careful
&lt;/h2&gt;

&lt;p&gt;Nemotron 3 Super, added this time, is a 120B total / 12B active MoE. Its Q4_K_M quantization in Ollama measured 86.83GB. On the DGX Spark, all the weights fit onto the GPU side, and the warm average was 9.09 seconds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Auto-generating FAQs for customer support: can learn internal knowledge and respond instantly / operate only within a scope that excludes confidential information&lt;/p&gt;

&lt;p&gt;Drafting sales materials: generates templates from past proposals and deal records / exclude personal information from the input&lt;/p&gt;

&lt;p&gt;Summarizing and translating internal manuals: restructures long documents into forms appropriate for each department / don't feed in documents where alteration is prohibited&lt;/p&gt;

&lt;p&gt;Adoption verdict: it's appropriate to start with a staged pilot operation, within a scope that protects data confidentiality while achieving operational efficiency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Among the 7 models, this was the longest and most careful answer. On the other hand, it's somewhat conservative — for instance, demanding the exclusion of personal information even though local operation is the whole premise. On raw short-answer speed alone, it loses to the 23GB-class Qwen3.6.&lt;/p&gt;

&lt;p&gt;That said, Nemotron 3 Super's real strength lies in agentic processing, code, function calling, and long-form reasoning. You can't conclude from this one question that "loading 87GB isn't worth it." It didn't show a speed advantage in the short-answer sprint — the result points to measuring it on longer work next.&lt;/p&gt;

&lt;h2&gt;
  
  
  GPT-OSS thought for 8.98 seconds and left the answer field empty
&lt;/h2&gt;

&lt;p&gt;GPT-OSS 120B used up the shared 320-token budget entirely on internal thinking, leaving the displayed answer empty. This isn't an API error. It's the result of all 320 generated tokens going into the thinking side.&lt;/p&gt;

&lt;p&gt;Even raising the max generation budget to 1000 tokens, it cut off partway through the second item. Raising it to 4000 tokens finally produced a complete answer, at a warm time of 25.89 seconds and 1087 output tokens.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Handling customer inquiries: can be trained using only internal data, reducing the risk of information leakage / model updates require regular data maintenance&lt;/p&gt;

&lt;p&gt;Automatic summarization of internal documents: can extract key points without sending confidential information externally / summarization accuracy requires tuning for business terminology&lt;/p&gt;

&lt;p&gt;Inventory optimization simulation: runs demand forecasting and ordering plans locally / needs to periodically retrain on seasonal variation in the data&lt;/p&gt;

&lt;p&gt;Adoption verdict: if confidentiality is the top priority, start with local AI and consider expanding in stages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even with the same model, not knowing the generation budget turns it into "a model that answers nothing." Model configuration is part of its performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The remaining 3 models' answers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GLM-4.7-Flash
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Summarizing and drafting internal documents: since it contains confidential information, data leakage risk can be avoided. / If there's uncertainty about accuracy due to insufficient recognition, training adjustments on the local model are needed.&lt;/p&gt;

&lt;p&gt;Generating FAQs from customer support history: quality is high because it can reflect internal-specific terminology and know-how.&lt;/p&gt;

&lt;p&gt;Adoption verdict:&lt;/p&gt;

&lt;p&gt;If data protection is the priority, it's best suited for document creation and QA tasks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;1.94 seconds is attractive, but against the requirement of 3 items it effectively delivered only 2, and the one-line-under-80-characters constraint broke down too. By speed measurement alone it ranks 2nd; by the standard of completing the task, it's a failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma 4 31B
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Looking up internal regulations: handles highly confidential material such as employment rules, to prevent external leakage / answer accuracy&lt;/p&gt;

&lt;p&gt;Drafting customer responses: creates drafts without hiding personal information, for efficiency / securing compute resources&lt;/p&gt;

&lt;p&gt;Summarizing technical documents: to safely analyze proprietary design documents and know-how / model optimization&lt;/p&gt;

&lt;p&gt;Adoption verdict: recommended when confidentiality is the top priority and the operating cost is acceptable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It followed the format. But the caveats end in bare nouns like "answer accuracy" and "securing compute resources," leaving it weak on what to actually check. "Without hiding personal information" is also a phrase that shouldn't be adopted without permissions and auditing in place first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Qwen2.5 72B
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Customer information management: strengthens data protection and privacy compliance / high initial cost&lt;/p&gt;

&lt;p&gt;Document creation support: can handle highly confidential information / requires learning up-to-date information&lt;/p&gt;

&lt;p&gt;Automating quality inspection: improves productivity through fast processing / requires specialized training data&lt;/p&gt;

&lt;p&gt;Adoption verdict: suited to work where security and privacy are prioritized.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It followed the format, but at 21.68 seconds it was the slowest among the models that completed their answer this time. "Privacy compliance" can't be guaranteed by localization alone, and the answer overall stays abstract.&lt;/p&gt;

&lt;h2&gt;
  
  
  My conclusion: measure task completion, not model rankings
&lt;/h2&gt;

&lt;p&gt;I drew four conclusions from this one question.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The fastest model doesn't necessarily return the safest answer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even with high tokens/s, dropping the specified format means the task isn't complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thinking models are put at a disadvantage just by matching the generation budget, so separate the common-condition test from the recovery diagnostic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For short structured answers, Qwen3.6 strikes a good balance. Nemotron 3 Super should be re-evaluated on longer agentic work&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This isn't a comprehensive ranking. There was only one question, and I didn't measure factuality, code, images, long context, or parallel load. The common conditions of temperature=0 and thinking OFF also aren't settings that draw out each model's maximum capability.&lt;/p&gt;

&lt;p&gt;That's exactly why I kept the raw answers. Rather than stopping at "it took 9.09 seconds," I compared what it actually said in those 9.09 seconds. From there, you can pick the model that fits your own work.&lt;/p&gt;

&lt;p&gt;Next, I'll hand the same agentic task to Nemotron 3 Super, Qwen3.6, and GPT-OSS, and compare completion rate, tool calls, and time taken. After Qwen wins the sprint, does the 87GB Nemotron come back in the long distance? That's the next thing to observe.&lt;/p&gt;

&lt;h2&gt;
  
  
  One thing that caught my attention in the distribution license labeling
&lt;/h2&gt;

&lt;p&gt;As of August 12, 2026, NVIDIA's official Hugging Face model card points to the NVIDIA Nemotron Open Model License. On the other hand, the embedded label on &lt;strong&gt;nemotron-3-super:120b-a12b-q4_K_M&lt;/strong&gt; as pulled from Ollama showed the NVIDIA Software and Model Evaluation License.&lt;/p&gt;

&lt;p&gt;Since my use here is evaluation, I went ahead with the measurements, but before moving the Ollama-distributed build into production or commercial use, I'll double-check whether this labeling discrepancy has been resolved. I'm not drawing a legal conclusion here.&lt;/p&gt;

&lt;p&gt;So, what did you think? You might have been surprised that even a smaller local LLM can return answers this fast and this good. They keep getting smaller and smarter. That feeling of the same hardware getting more and more capable over time is something you can only experience in an era like this one. It's genuinely fascinating.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>When I Narrowed My Human Inputs Down to Just Todoist and Discord, the System Started Running Itself</title>
      <dc:creator>Masahiko Ebisuda</dc:creator>
      <pubDate>Sat, 15 Aug 2026 12:32:48 +0000</pubDate>
      <link>https://dev.to/ebibibi/when-i-narrowed-my-human-inputs-down-to-just-todoist-and-discord-the-system-started-running-itself-51lf</link>
      <guid>https://dev.to/ebibibi/when-i-narrowed-my-human-inputs-down-to-just-todoist-and-discord-the-system-started-running-itself-51lf</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://veritastracto194617.substack.com/p/when-i-narrowed-my-human-inputs-down" rel="noopener noreferrer"&gt;my Substack&lt;/a&gt;. I'm a Microsoft MVP based in Japan, writing in English about the AI agent systems I actually run in production.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;AI tools have multiplied. So have agents, skills, and automation scripts.&lt;/p&gt;

&lt;p&gt;And yet, somehow, my hands are never free. I wake up, open a dashboard, check notifications, go look at the logs for a failed job, and think, "wait, where was that process even running?" Every time I add one more automation, I add one more place I have to go check.&lt;/p&gt;

&lt;p&gt;That was me, up until last year.&lt;/p&gt;

&lt;p&gt;The cause was clear: &lt;strong&gt;I kept thinking about what to have AI do, and never once designed where I myself would touch things.&lt;/strong&gt; So I rewrote my policy down to one line. There are only two things a human does: throw tasks into one place, and have conversations in one place. No other entry points get added.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖✍️ This article was co-written with AI — an AI agent (Claude Code) generated the draft automatically based on real collaborative work with Ebisuda, who then reviewed and revised it before publishing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this series, I share the systems I've actually built using AI as case studies — including both the ones that worked and the ones that failed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Set Out to Build
&lt;/h2&gt;

&lt;p&gt;What I set out to build wasn't a specific tool or a specific agent. It was &lt;strong&gt;the design of the surface humans touch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rule I settled on was just two lines.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The only human entry points are &lt;strong&gt;Todoist&lt;/strong&gt; (for dropping in things to do) and &lt;strong&gt;Discord&lt;/strong&gt; (for conversation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everything else gets pushed to the AI and scheduler side&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the opposite of "let's have AI do a ton of work." When people try to maximize what AI can do, they end up adding more tools. More tools means more settings screens, more places logs pile up, more places you have to go check "how's it doing now." Left unchecked, the number of automated processes and the number of places a human has to go look both grow together.&lt;/p&gt;

&lt;p&gt;So the thing I needed to decide first wasn't the scope of AI's work — it was &lt;strong&gt;the footprint on the human side.&lt;/strong&gt; If you fix that footprint first, whatever overflows has nowhere to go but onto the AI side. It's a strategy of turning the design from "addition" into "displacement."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Hard
&lt;/h2&gt;

&lt;p&gt;Once you actually try it, you find that reducing entry points is much harder than reducing features. There are three reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reason 1: Entry points multiply without you ever meaning to create them
&lt;/h3&gt;

&lt;p&gt;Start using a new service, and you gain one more UI for that service. Write one automation, and you gain its config file plus the logs you check when it fails. Add monitoring, and you gain a monitoring dashboard.&lt;/p&gt;

&lt;p&gt;Each of these is, individually, the right call. Nobody sets out thinking "let's add another entry point." And yet they keep adding up. That's because &lt;strong&gt;the growth in entry points happens outside the scope of any single decision.&lt;/strong&gt; By the time you notice, your morning check-in has gone from ten minutes to thirty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reason 2: The "last ten percent" effectively takes over everything
&lt;/h3&gt;

&lt;p&gt;Say you have a process that's ninety percent automated, with the remaining ten percent needing a final human check. That's a common design, and not a bad one.&lt;/p&gt;

&lt;p&gt;The problem is that for the sake of that ten percent, &lt;strong&gt;you still have to keep opening that tool.&lt;/strong&gt; Even though the actual work time has dropped by ninety percent, the amount of mental real estate it occupies barely shrinks. That nagging "wait, I haven't checked that today" feeling is proportional to the number of entry points, not the amount of work. Raise the automation rate all you want — as long as the entry point remains, the perceived burden doesn't go down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reason 3: Entry points shrink only through the decision not to add
&lt;/h3&gt;

&lt;p&gt;Features grow when you add them, so adding is a task you can just do. Entry points are different — &lt;strong&gt;there's no such thing as a task that reduces them.&lt;/strong&gt; All you can do is take the roundabout path: decide "starting today, I won't go check this tool's UI," and then build the wiring to funnel that information somewhere else instead.&lt;/p&gt;

&lt;p&gt;What's more, while you're building that wiring, entry points temporarily increase, because both the old route and the new route are alive at once. If you run out of steam at this stage, you end up simply having added one more entry point. I've done this more than once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Questions Left Standing
&lt;/h2&gt;

&lt;p&gt;The policy is simple. Narrow it down to two entry points. Saying it takes three seconds.&lt;/p&gt;

&lt;p&gt;But when you actually try to do it, some questions remain that you can't take a single step past without answering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does everything you cut go?&lt;/strong&gt; Closing an entry point doesn't make the information you used to see there disappear. Failure notifications, deadlines, pending approvals — they all need somewhere to go. Close an entry point without preparing a destination, and that's not automation; it's just choosing not to look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What becomes invisible when you close an entry point?&lt;/strong&gt; And how do you notice that it's become invisible? I actually caused an incident here. There was a stretch of time when I assumed a process was running, and it had quietly stopped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is "two" even enough to begin with?&lt;/strong&gt; There will inevitably come a moment when it isn't. Do you add another one then, or hold the line? Without a clear criterion, you slide back into three, then four, without ever deciding to.&lt;/p&gt;

&lt;p&gt;From here on, I'll write about the actual results of running this design, counting up everything the records show. How many processes are currently running automatically, how many times a day they execute, and how many of those runs fail. What broke as the price of narrowing down to two entry points, and how I fixed it. And, in the end, what I had to give up to hold the line at "two."&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  📘 The Foundation Under This System — Ebi Workspace
&lt;/h2&gt;

&lt;p&gt;The "two entry points" design described in this article doesn't run on philosophy alone. Only once AI can recall on its own which project is being discussed, and can execute fixed procedures at the same quality every time, does it become possible to shrink the surface humans touch. The foundation for that is Ebi Workspace (formerly Ebi Workspace (formerly claude-workspace)). Project management, context recovery, the skill execution framework — every mechanism that appears in this article runs on top of this plugin.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://note.com/ebibibi/n/n300772aeac93" rel="noopener noreferrer"&gt;I sell the actual Claude Code setup I use, packaged as a plugin.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📡 Another Foundation — Ebi Agent Chat Relay
&lt;/h2&gt;

&lt;p&gt;This is the execution framework that connects Claude Code and Codex through Discord as the front door, letting multiple AI agents converse, hand off work, and coordinate with each other.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/ebibibi/claude-code-discord-bridge" rel="noopener noreferrer"&gt;Ebi Agent Chat Relay — Supporting Conversation and Coordination Across Multiple AIs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;p&gt;__ *&lt;/p&gt;

&lt;h2&gt;
  
  
  The Actual Setup — Two Entry Points, One Execution Layer, Two Exits
&lt;/h2&gt;

&lt;p&gt;Here's the overall picture first. Humans touch only the two items at the top; in principle, the three below are never checked directly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://substackcdn.com/image/fetch/$s_!F0Bo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab44bdd8-a916-4724-aab0-c2ccc65843b5_1280x672.jpeg" rel="noopener noreferrer"&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%2Fi4li94x65qnln4zb1ydk.jpeg" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the numbers below are actual measurements I counted on August 5, 2026, the day I wrote this article. They aren't drawn from memory or from design documents — I counted them directly from config files and databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entry Point 1: Todoist — Just Drop in Things to Do
&lt;/h3&gt;

&lt;p&gt;Anything I think of, anything I'm asked to do, anything with a deadline — it all goes straight into Todoist. I don't categorize it, and I don't assign it to a project. I just drop it in.&lt;/p&gt;

&lt;p&gt;The reason I don't need to categorize is that &lt;strong&gt;Todoist isn't the source of truth.&lt;/strong&gt; The source of truth for tasks lives in each project's note in Obsidian; Todoist is used purely as an intake tray for the entry point. A morning job picks up whatever's been dropped in and writes it out to Obsidian, and anything with a deadline gets aggregated into a deadline dashboard.&lt;/p&gt;

&lt;p&gt;This was my first design decision. &lt;strong&gt;An entry point must never be a "place to organize things."&lt;/strong&gt; The moment you demand organization, it becomes a chore, and any entry point that becomes a chore will inevitably be neglected. The only job an entry point is allowed to do is receive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entry Point 2: Discord — The Only Window for Talking to AI
&lt;/h3&gt;

&lt;p&gt;The other entry point is Discord. This has effectively become my entire working environment.&lt;/p&gt;

&lt;p&gt;My self-built OSS project, Ebi Agent Relay Chat (formerly known as claude-code-discord-bridge), maps Discord threads and Claude Code sessions one-to-one. Start a thread, and one session spins up; reply in that thread, and the same session continues. Even from the Discord app on my phone, I get a fully-featured Claude Code.&lt;/p&gt;

&lt;p&gt;When I actually measured it, across the 33 days since July 3rd — when session records began — &lt;strong&gt;557 sessions&lt;/strong&gt; had been started (541 in just the last 30 days). That's roughly 17 a day. And interestingly, of the 557 recorded sessions, &lt;strong&gt;every single one had "discord" as its origin.&lt;/strong&gt; I no longer start Claude Code by opening a terminal.&lt;/p&gt;

&lt;p&gt;The backend breakdown also came out: 219 on Claude, 67 on Codex, and 271 from before records began. Since I can switch AI per thread, I use Claude for implementation and Codex for review, and that split happens entirely within the same single entry point. &lt;strong&gt;Narrowing to one entry point doesn't mean narrowing to one AI.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Execution Layer: Claude Code and 130 Skills
&lt;/h3&gt;

&lt;p&gt;Claude Code is what executes the instructions that come in through the entry points. On top of it, I've been building up "skills" — repeated tasks solidified into procedures.&lt;/p&gt;

&lt;p&gt;The actual count is &lt;strong&gt;130.&lt;/strong&gt; Of those, &lt;strong&gt;124 are ones I built myself&lt;/strong&gt; , and the remaining 6 are links to external repositories. Fetching the weather, generating invoices, building slides, promoting articles, finishing off video metadata — once I've done a task once, I make sure it can be called as a skill from then on.&lt;/p&gt;

&lt;p&gt;Skills matter not because they add capability, but because &lt;strong&gt;they lower the pressure on the entry points.&lt;/strong&gt; A task without a fixed procedure requires the human to remember "how did I do this again" every single time, and remembering means opening documents or tools — in other words, adding an entry point. Turning something into a skill is also, in effect, closing off one entry point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exit 1: The Scheduler — 114 Jobs Running on Their Own
&lt;/h3&gt;

&lt;p&gt;Processes that run without any human instruction are pushed onto my self-built scheduler. This is a domain governed by a written rule: "don't use cron" (I'll get to the story of how this declaration was, in practice, not fully upheld, later on).&lt;/p&gt;

&lt;p&gt;Counting the config files: &lt;strong&gt;196 job definitions&lt;/strong&gt; (118 of them active), and &lt;strong&gt;249 schedule definitions&lt;/strong&gt; (183 of them active). Cross-referencing active schedules against active jobs, &lt;strong&gt;114 jobs are actually running on a regular schedule.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every execution record is kept in a database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Executions in the last 30 days: &lt;strong&gt;81,335&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Breakdown: 80,755 succeeded / 145 failed / 435 reclaimed while still marked as running (stale)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Success rate: &lt;strong&gt;99.29%&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Narrowing to the last 7 days: 20,107 runs with &lt;strong&gt;6 failures&lt;/strong&gt; (99.97%)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yesterday alone: &lt;strong&gt;2,534 runs&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2,534 runs in a single day means that &lt;strong&gt;on average, something runs automatically once every 34 seconds.&lt;/strong&gt; Across the entire period for which records exist, the cumulative total was over 250,000 runs.&lt;/p&gt;

&lt;p&gt;The content ranges from posting and analyzing social media, promoting articles, post-processing YouTube videos, maintaining knowledge in Obsidian, backups, health checks, deadline reminders, and even generating this very series of articles. This article itself was born from &lt;strong&gt;a job that fires every 7 days.&lt;/strong&gt; It automatically picks one topic from a ledger, actually has the AI read the source files backing it, and generates a draft — all the way through.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exit 2: Obsidian — The Second Brain Humans and AI Share
&lt;/h3&gt;

&lt;p&gt;The results of every process, and the knowledge extracted from them, all get written back into Obsidian. There are &lt;strong&gt;6,060 Markdown notes&lt;/strong&gt; , and in just the last 30 days there were &lt;strong&gt;1,182 commits&lt;/strong&gt; (roughly 39 a day).&lt;/p&gt;

&lt;p&gt;Knowledge is split into three types. There are &lt;strong&gt;234 wiki entries&lt;/strong&gt; answering "what is X," &lt;strong&gt;75 KB entries&lt;/strong&gt; answering "here's what to do when you hit this problem," and &lt;strong&gt;12 ADR entries&lt;/strong&gt; answering "why I chose this." The daily notes, my day-to-day log, cover &lt;strong&gt;479 days.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This three-way split isn't a human filing hobby — it's for the AI's sake. When you have the AI recall "what did I do last time," having it search through one box with everything mixed together degrades accuracy. &lt;strong&gt;Splitting the boxes by the shape of the question lets the AI go straight to the right box and only that box.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Breaks When You Narrow Down to Two Entry Points
&lt;/h2&gt;

&lt;p&gt;Now for the main event. Writing only about what went well isn't useful, so here are the four things that actually broke.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Broke #1: "Silent Failures" Become Invisible
&lt;/h3&gt;

&lt;p&gt;This was the most dangerous one.&lt;/p&gt;

&lt;p&gt;Closing an entry point means &lt;strong&gt;not going to check.&lt;/strong&gt; In other words, you simultaneously close off the opportunity to notice that something has stopped working. If a process fails loudly with an error, a notification fires — but in reality, most failures are silent.&lt;/p&gt;

&lt;p&gt;The measurements bear this out. Those 435 stale entries from the last 30 days are a case in point. Digging into them, &lt;strong&gt;almost all 435 had been batch-marked as terminated at the exact same timestamp on the same day (July 19, 06:49:12).&lt;/strong&gt; In other words, they didn't fail one at a time — this is the trace of a later cleanup job sweeping up things that had been left stuck in a "running" state. No exit code was recorded. Whether a process died or the machine rebooted, nobody was watching at the moment it happened.&lt;/p&gt;

&lt;p&gt;Since none of this was flagged as an error, if I hadn't put a cleanup job in place, these 435 records would have been stuck showing "running" forever. &lt;strong&gt;The anomaly never sounded an alarm as an anomaly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've had incidents of the same structure happen over and over. A process skips its work and exits normally (exit code 0, so it looks successful). A script written with relative paths misfires (zero targets found, so it looks successful). A limit-value config key is missing, so it runs wide open on the default (it's running, so it looks successful). &lt;strong&gt;None of these gets reported as a "failure."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The countermeasure was to place &lt;strong&gt;actively-alerting mechanisms&lt;/strong&gt; on the exit side, in place of the entry point I'd closed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run a health-check job continuously, monitoring whether services are alive at all (it ran 8,697 times in the last 30 days)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a separate job that detects consecutive failures and notifies, plus a separate job that reports a weekly roundup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Question whether the notification path itself is dead. In fact, there was a period when the destination webhook had been deleted, and failure notifications kept getting silently dropped with a 404. &lt;strong&gt;A state where no notifications arrive is indistinguishable from "normal."&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When in doubt, err on the side of alerting too much. The one thing you never choose is silence&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're going to design for fewer entry points, &lt;strong&gt;you must add active notifications matching the number you removed.&lt;/strong&gt; That's the bare minimum condition.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Broke #2: Adding More Notifications Makes Notifications Stop Working
&lt;/h3&gt;

&lt;p&gt;But once you start adding notifications, the opposite problem shows up.&lt;/p&gt;

&lt;p&gt;People inevitably grow numb to a notification that fires every morning. Push an important deadline that only comes once or twice a year into a channel you've gone numb to, and you will absolutely never notice it. I actually had an incident where I &lt;strong&gt;failed to notice a deadline for 21 days&lt;/strong&gt; — the kind of deadline where missing it causes real damage. The notification had arrived. It just arrived in a place that fires every day.&lt;/p&gt;

&lt;p&gt;The lesson here was counterintuitive: &lt;strong&gt;a safety net doesn't get stronger the more you add.&lt;/strong&gt; Every notification channel you add reduces the weight of each existing one. The effectiveness of the whole set gets diluted.&lt;/p&gt;

&lt;p&gt;As a countermeasure, I introduced the concept of "tiers" for deadline notifications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tier 0 (things where missing them costs money or forfeits a right) gets isolated into &lt;strong&gt;a dedicated channel that fires only about 20 times a year.&lt;/strong&gt; It keeps firing until I report completion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tier 1 (monthly recurring items) goes to the normal channel, once, on the relevant day&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to preserve the sense that "it fired = something's wrong." If the Tier 0 channel fired three times a day, I'd be right back where I started. So I restricted the midday and evening re-notifications to Tier 0 only. &lt;strong&gt;Designing notifications is not a job of designing volume — it's a job of designing silence.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Broke #3: The One-Message-Equals-One-Process Trap
&lt;/h3&gt;

&lt;p&gt;Making Discord the entry point led me straight into a trap specific to it.&lt;/p&gt;

&lt;p&gt;Every single Discord message becomes its own new process. That means &lt;strong&gt;the working directory resets with every message.&lt;/strong&gt; Even if I &lt;code&gt;cd&lt;/code&gt;'d into a directory in the previous message, by the next message it's back to the default.&lt;/p&gt;

&lt;p&gt;The worst part is that &lt;strong&gt;when a relative-path process misfires, it doesn't error out.&lt;/strong&gt; It goes looking for a file, doesn't find it, processes zero items, and exits normally. Nothing shows up in the logs. All you get back is a report saying "done."&lt;/p&gt;

&lt;p&gt;The countermeasure is simple, but it demands discipline.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always write paths as absolute paths&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have every script explicitly set its working directory at the top&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For long-running processes or heavy output, don't rely on stdout — &lt;strong&gt;write to an absolute-path log file and read it back&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And rather than just writing this down as a rule, I placed it at the very top of the config file the AI reads. It's designed to be prevented on the AI's input side, not relying on human attentiveness.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Broke #4: Even After Writing the Rule, Only the Automated-Execution Path Ignores It
&lt;/h3&gt;

&lt;p&gt;This is the one that chilled me the most.&lt;/p&gt;

&lt;p&gt;A phenomenon occurred where the AI followed the rules when instructed interactively, but &lt;strong&gt;violated them specifically when auto-launched by the scheduler.&lt;/strong&gt; The cause was simple: the rule was written only in the skill's documentation, and never made it into the prompt that the automated-execution path assembles.&lt;/p&gt;

&lt;p&gt;It behaved correctly only while a human was watching, and broke when nobody was. In an environment with fewer entry points, detecting this takes longer.&lt;/p&gt;

&lt;p&gt;And while recounting everything to write this article, &lt;strong&gt;I found one more instance of the same structural gap.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rules in my environment explicitly state: "use the scheduler for recurring execution; don't use cron." The reason is clear-cut — a process placed in cron leaves no execution history in the database, and no notification fires even if it fails. It's exactly the kind of breeding ground for "silent failures."&lt;/p&gt;

&lt;p&gt;But when I actually checked, &lt;strong&gt;there was one job still surviving in cron.&lt;/strong&gt; It was the daily backup for a certain service. It had been running since before the rule was decided, and precisely because it was running, nobody had touched it. The rule got written after the fact, and it never got applied to what already existed.&lt;/p&gt;

&lt;p&gt;This captures the limits of what a rule can do well. &lt;strong&gt;A rule only takes effect on "things you're about to write."&lt;/strong&gt; Anything that already existed at the moment you wrote the rule keeps living outside its reach unless you explicitly go audit for it. And because it's running fine, nobody's inconvenienced — until it stops.&lt;/p&gt;

&lt;p&gt;There are two countermeasures. One is an operating rule: &lt;strong&gt;whenever I create a new convention, search the automated-execution scripts and embed it there too.&lt;/strong&gt; The other is structural: &lt;strong&gt;separate the side that generates from the side that inspects.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As it happens, the very article you're reading right now is a product of that countermeasure. The articles in this series are generated automatically, but after generation, a separate inspection step runs. It cross-checks the body text against a list of words that must never be published (my employer's name, client names, internal hostnames, and so on), and &lt;strong&gt;if even a single one remains, it drops the article's status to "needs revision" and marks the job as failed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generate article → write body to a fixed path&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Inspect (a process separate from the generator)&lt;/p&gt;

&lt;p&gt;├─ Any forbidden word remains → drop to "needs revision," fail&lt;/p&gt;

&lt;p&gt;├─ Body was not saved → drop to "needs revision," fail&lt;/p&gt;

&lt;p&gt;└─ Passes → notify with draft URL&lt;/p&gt;

&lt;p&gt;The key point is that the inspection isn't left to the AI's prompt. &lt;strong&gt;I don't rely on "I wrote it in the prompt, so it should be followed."&lt;/strong&gt; AI follows instructions most of the time, but there are kinds of mistakes where "most of the time" isn't good enough. Anything that would be irreversible on a life-altering scale gets turned into a mechanical constraint.&lt;/p&gt;

&lt;p&gt;In the same spirit, I've kept &lt;strong&gt;only the publish button in human hands.&lt;/strong&gt; Everything up to the draft is fully automated; publishing is human. I have no plans to automate this going forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, In the End, Was "Two" Enough?
&lt;/h2&gt;

&lt;p&gt;It was enough. With a condition, though.&lt;/p&gt;

&lt;p&gt;Running on two entry points only works &lt;strong&gt;when the exit side has been made to actively alert, in place of the entry point you closed.&lt;/strong&gt; Counting it up, of the 114 jobs running on a regular schedule, &lt;strong&gt;20 were jobs purely for monitoring and upkeep.&lt;/strong&gt; Health checks, failure alerts, backups, database cleanup, deadline reminders, detecting neglected projects — jobs that produce zero deliverables account for &lt;strong&gt;18% of the total.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't consider this waste — I consider it the legitimate cost of reducing entry points. &lt;strong&gt;In exchange for the human no longer going to check, the system takes on the obligation to report on its own.&lt;/strong&gt; As long as that trade is fair, this design holds together.&lt;/p&gt;

&lt;p&gt;Conversely, I've also become clear on how to recognize the moment when I can no longer hold the line at "two." &lt;strong&gt;If I start opening some new tool's UI every day, that's a sign I'm losing.&lt;/strong&gt; If not opening it makes me anxious, that means my notification design is insufficient. It's not that I added one more tool — it's that I added one more entry point. When that happens, I stop going to check the UI and instead write the wiring to funnel the necessary information into Discord.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;Having run this design in practice, I've narrowed down the principles that remain to five.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Decide where you yourself will touch things before deciding what to have AI do.&lt;/strong&gt; The former expands without limit; the latter is finite. Fix the finite one first, and the rest gets automatically pushed onto the AI side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Don't demand "organizing" from an entry point.&lt;/strong&gt; Make it a place that only receives. The moment you make categorization, prioritization, or project assignment happen at the entry point, that entry point gets neglected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Add actively-alerting mechanisms matching the number of entry points you closed.&lt;/strong&gt; A design where you no longer go check only works when it's paired with a design where the system reports to you. Do only one half, and it breaks quietly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Notifications dilute as you add more. Physically split routes by importance.&lt;/strong&gt; The sense of "it fired = something's wrong" can only be built through frequency of firing. Deliberately reserve one channel that fires only around 20 times a year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. For anything you absolutely need followed, guarantee it through inspection, not through the prompt.&lt;/strong&gt; Separate the side that generates from the side that inspects, and stop the process if something trips the check. AI follows instructions most of the time, but for the things where "most of the time" isn't acceptable, put up a mechanical wall.&lt;/p&gt;

&lt;p&gt;And what actually made the biggest difference turned out to be simply counting things. In writing this article, I measured everything for real, for the first time. I didn't know, until I counted, that there were 114 jobs alive on a regular schedule, that they'd run 81,335 times in the last 30 days, or that 100% of sessions were now coming through Discord. &lt;strong&gt;As for the one job left surviving in cron — if I hadn't counted, I would never have noticed it, for the rest of my life.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The most dangerous state is believing "it's running fine" without ever knowing the scale of your own system.&lt;/strong&gt; What to automate next is better decided from actual counted results, not from a feeling.&lt;/p&gt;

&lt;p&gt;Starting next time, I'll break down, one by one, the individual systems I've built on top of this foundation — beginning with the story of how I dropped cron in favor of a queue-based approach.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
