<?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: yukihiro amadatsu</title>
    <description>The latest articles on DEV Community by yukihiro amadatsu (@suruseas).</description>
    <link>https://dev.to/suruseas</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%2F852203%2Fe8e2c8e4-a9f6-4726-9878-22f90505518c.jpeg</url>
      <title>DEV Community: yukihiro amadatsu</title>
      <link>https://dev.to/suruseas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/suruseas"/>
    <language>en</language>
    <item>
      <title>I ran 29 real docker-compose projects on Apple's container runtime. Here's what broke</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:51:59 +0000</pubDate>
      <link>https://dev.to/suruseas/i-ran-29-real-docker-compose-projects-on-apples-container-runtime-heres-what-broke-2fk7</link>
      <guid>https://dev.to/suruseas/i-ran-29-real-docker-compose-projects-on-apples-container-runtime-heres-what-broke-2fk7</guid>
      <description>&lt;p&gt;Docker Desktop keeps a &lt;strong&gt;~7.8 GB Linux VM&lt;/strong&gt; provisioned the entire time it's&lt;br&gt;
running — even when zero containers are up. Apple's new&lt;br&gt;
&lt;a href="https://github.com/apple/container" rel="noopener noreferrer"&gt;&lt;code&gt;container&lt;/code&gt;&lt;/a&gt; runtime idles at &lt;strong&gt;~58 MB&lt;/strong&gt; of&lt;br&gt;
helper processes and only spends memory while a container actually runs, because&lt;br&gt;
it boots a lightweight VM &lt;em&gt;per container&lt;/em&gt;, on demand. It hit 1.0 in June, and on&lt;br&gt;
macOS 26 containers can finally talk to each other, which makes multi-service&lt;br&gt;
dev stacks possible.&lt;/p&gt;

&lt;p&gt;So the question stopped being "is it interesting?" and became: &lt;strong&gt;is it&lt;br&gt;
compatible enough to run the &lt;code&gt;docker-compose.yml&lt;/code&gt; files people actually have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of guessing, I measured. I took Docker's own&lt;br&gt;
&lt;a href="https://github.com/docker/awesome-compose" rel="noopener noreferrer"&gt;awesome-compose&lt;/a&gt; repository — the&lt;br&gt;
official collection of sample compose projects (WordPress, React+Express+Mongo,&lt;br&gt;
Spring+Postgres, Prometheus+Grafana, …) — and ran &lt;strong&gt;29 of its samples,&lt;br&gt;
unmodified&lt;/strong&gt;, on Apple &lt;code&gt;container&lt;/code&gt;. An alphabetical slice, no cherry-picking:&lt;br&gt;
every sample from &lt;code&gt;nextcloud-postgres&lt;/code&gt; through &lt;code&gt;wordpress-mysql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the breakdown, and — more useful — &lt;em&gt;why&lt;/em&gt; each failure failed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Apple's &lt;code&gt;container&lt;/code&gt; is a runtime, not an orchestrator: it has no &lt;code&gt;compose&lt;/code&gt;&lt;br&gt;
subcommand, no dependency ordering, no service discovery. For that I used&lt;br&gt;
&lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;opossum&lt;/a&gt;, a small compose-like&lt;br&gt;
orchestrator for Apple &lt;code&gt;container&lt;/code&gt; that I've been building. It reads your&lt;br&gt;
existing &lt;code&gt;compose.yaml&lt;/code&gt; / &lt;code&gt;docker-compose.yml&lt;/code&gt; and gives you the familiar&lt;br&gt;
verbs — &lt;code&gt;up&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;logs&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;down&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
container system start                     &lt;span class="c"&gt;# start the runtime (once)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;container system dns create opossum   &lt;span class="c"&gt;# one-time: DNS domain so services&lt;/span&gt;
                                           &lt;span class="c"&gt;# resolve each other by name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method: macOS 26 on Apple silicon, Apple &lt;code&gt;container&lt;/code&gt; 1.0. For each sample:&lt;br&gt;
&lt;code&gt;cd&lt;/code&gt; in, &lt;code&gt;opossum up&lt;/code&gt;, give it ~90 seconds to come up, check &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;logs&lt;/code&gt;,&lt;br&gt;
categorize, &lt;code&gt;down&lt;/code&gt;, next. Every failure got a second look to find the actual&lt;br&gt;
root cause — the interesting part is &lt;em&gt;whose fault&lt;/em&gt; each one was.&lt;/p&gt;
&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅ Ran &lt;strong&gt;as-is&lt;/strong&gt; — zero changes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WordPress, React+Express+MySQL/Mongo, Spring, nginx+Go+MySQL, pgAdmin, Kafka, …&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔧 Ran after a &lt;strong&gt;one-line&lt;/strong&gt; compose change&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3× Postgres data dir, 1× amd64-only image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏗️ Broken &lt;strong&gt;upstream&lt;/strong&gt; — the sample itself has rotted&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;would fail regardless of runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚫 Can't run &lt;strong&gt;by design&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Docker socket ×2, Linux kernel access ×1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ Environment / setup&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;placeholder path, host port already taken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐌 Build outlasted my timeout&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;a 10–15 min Rust→Wasm build (no errors — I got impatient)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The headline: &lt;strong&gt;18 of 29 real-world stacks run on Apple's runtime today, 14 of&lt;br&gt;
them without touching a single line.&lt;/strong&gt; And of the 11 that didn't, &lt;em&gt;not one&lt;/em&gt;&lt;br&gt;
failed because of the runtime's container execution or networking — every&lt;br&gt;
failure traced to the sample itself, to Docker-specific host features, or to my&lt;br&gt;
environment.&lt;/p&gt;

&lt;p&gt;Let's look at the categories, because a couple of them teach you something&lt;br&gt;
about how Apple's runtime actually differs from Docker.&lt;/p&gt;
&lt;h2&gt;
  
  
  The one-line fixes (and what they reveal)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Postgres refuses its data volume (3 samples)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;nextcloud-postgres&lt;/code&gt;, &lt;code&gt;nginx-golang-postgres&lt;/code&gt;, and &lt;code&gt;spring-postgres&lt;/code&gt; all define&lt;br&gt;
the classic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db-data:/var/lib/postgresql/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Docker this works. On Apple &lt;code&gt;container&lt;/code&gt; Postgres dies with &lt;em&gt;"initdb: error:&lt;br&gt;
directory exists but is not empty"&lt;/em&gt;. Why: the runtime mounts a named volume as&lt;br&gt;
a real ext4 mount point — which contains &lt;code&gt;lost+found&lt;/code&gt; — and &lt;code&gt;initdb&lt;/code&gt; refuses a&lt;br&gt;
non-empty directory. Docker's volumes don't surface that detail.&lt;/p&gt;

&lt;p&gt;The one-line fix is the same one you'd use on any bare-metal mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;PGDATA&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/postgresql/data/pgdata&lt;/span&gt;   &lt;span class="c1"&gt;# a subdirectory of the mount&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is &lt;em&gt;everywhere&lt;/em&gt; in self-hosted app composes (Gitea, Nextcloud,&lt;br&gt;
…), so opossum detects it at &lt;code&gt;up&lt;/code&gt; time and prints exactly that suggested fix.&lt;br&gt;
MySQL and MariaDB tolerate the mount point, which is why the WordPress and&lt;br&gt;
MySQL samples sailed through.&lt;/p&gt;
&lt;h3&gt;
  
  
  amd64-only images (1 sample)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;nginx-nodejs-redis&lt;/code&gt; uses &lt;code&gt;redismod&lt;/code&gt;, an image published only for x86-64. The&lt;br&gt;
fix is the same line you'd add for Docker on Apple silicon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;opossum passes the platform through and automatically enables Rosetta&lt;br&gt;
translation for the container, so the x86-64 image runs on the arm64 VM.&lt;/p&gt;
&lt;h2&gt;
  
  
  The ones that were broken before I arrived (5 samples)
&lt;/h2&gt;

&lt;p&gt;This was the fun discovery. Five samples fail &lt;em&gt;on any runtime&lt;/em&gt; today, because&lt;br&gt;
they pin nothing and the world moved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nginx-flask-mysql&lt;/code&gt; — Flask backend crashes with &lt;code&gt;ImportError: cannot import
name 'url_quote' from 'werkzeug.urls'&lt;/code&gt;: the famous Flask/Werkzeug 2.1 break,
hit because the sample doesn't pin Werkzeug. (The nginx "host not found in
upstream" error that follows is just the dead backend cascading.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prometheus-grafana&lt;/code&gt; — the unpinned &lt;code&gt;prom/prometheus&lt;/code&gt; image now rejects the
sample's &lt;code&gt;api_version: v1&lt;/code&gt; Alertmanager config.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nginx-wsgi-flask&lt;/code&gt;, &lt;code&gt;react-rust-postgres&lt;/code&gt;, &lt;code&gt;vuejs&lt;/code&gt; — &lt;code&gt;pip install&lt;/code&gt; /
&lt;code&gt;cargo&lt;/code&gt; / &lt;code&gt;yarn global add&lt;/code&gt; failures during build, all dependency rot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I went in expecting to find runtime incompatibilities; instead I found a small&lt;br&gt;
museum of what happens to unmaintained compose files after a few years. If&lt;br&gt;
your own stack pins its images and dependencies, this whole category doesn't&lt;br&gt;
apply to you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Can't run by design (3 samples)
&lt;/h2&gt;

&lt;p&gt;Full honesty, because this is where the model genuinely differs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;portainer&lt;/code&gt;, &lt;code&gt;traefik-golang&lt;/code&gt;&lt;/strong&gt; bind-mount &lt;code&gt;/var/run/docker.sock&lt;/code&gt; — they
manage/inspect &lt;em&gt;Docker&lt;/em&gt;. Apple's runtime has no Docker socket; anything whose
job is talking to the Docker daemon is out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;wireguard&lt;/code&gt;&lt;/strong&gt; needs &lt;code&gt;NET_ADMIN&lt;/code&gt; plus the host's kernel modules
(&lt;code&gt;/lib/modules&lt;/code&gt;). There's no shared Linux host kernel to reach into — each
container has its own micro-VM. (Docker Desktop on a Mac can't satisfy the
host-path part either.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your compose file is "a normal app + database + cache", none of this&lt;br&gt;
touches you. If it's host-level infrastructure tooling, stay on Docker.&lt;/p&gt;
&lt;h2&gt;
  
  
  The rest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;plex&lt;/code&gt; ships a placeholder bind path (&lt;code&gt;/media/your/plex/path&lt;/code&gt;) you're meant
to edit — environment, not compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pihole-cloudflared-DoH&lt;/code&gt; wants host port 53, which my Mac was already using.
(opossum checks published ports up front and names the conflict instead of
failing mid-startup.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wasmedge-mysql-nginx&lt;/code&gt; compiles Rust to WebAssembly inside the build —
10–15 minutes of &lt;code&gt;cargo build&lt;/code&gt;. It was progressing without errors when my
90-second patience ran out, so it goes in the "almost certainly fine" pile,
not the failure pile.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Gotchas beyond this sample set
&lt;/h2&gt;

&lt;p&gt;Two more differences worth knowing before you try your own stack, found in&lt;br&gt;
wider testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fresh volumes mount empty.&lt;/strong&gt; Docker pre-fills a brand-new named/anonymous
volume from the image's contents at that path; Apple &lt;code&gt;container&lt;/code&gt; doesn't.
That breaks the beloved &lt;code&gt;- /app/node_modules&lt;/code&gt; trick. opossum replicates
Docker's seeding behavior itself, so this pattern works — but it's a real
runtime difference you'd hit with raw &lt;code&gt;container&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cgroup-sniffing JVMs crash.&lt;/strong&gt; Elasticsearch 7.x's bundled JDK reads the
host cgroup to size its heap, and the micro-VM doesn't expose the mount it
expects — it dies at launch before any config applies. A runtime/JDK
incompatibility with no workaround I know of.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the trade-offs cut both ways — this isn't "Docker but better":&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;Docker Desktop&lt;/th&gt;
&lt;th&gt;Apple &lt;code&gt;container&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Idle memory&lt;/td&gt;
&lt;td&gt;~373 MB host procs + &lt;strong&gt;~7.8 GB VM&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~58 MB&lt;/strong&gt;, no always-on VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single container start&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~0.19 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~0.81 s (boots a fresh micro-VM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bind-mount small-file I/O&lt;/td&gt;
&lt;td&gt;slow&lt;/td&gt;
&lt;td&gt;slightly &lt;strong&gt;slower&lt;/strong&gt; (same host↔VM model)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;shared VM kernel&lt;/td&gt;
&lt;td&gt;per-container VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;paid for larger orgs&lt;/td&gt;
&lt;td&gt;open source&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Docker still wins if you churn many short-lived containers or hammer bind&lt;br&gt;
mounts. Apple's runtime wins on footprint and isolation. (Numbers from one&lt;br&gt;
machine — &lt;a href="https://github.com/suruseas/opossum/blob/main/docs/benchmarks.md" rel="noopener noreferrer"&gt;method and caveats here&lt;/a&gt;.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it on your own compose file
&lt;/h2&gt;

&lt;p&gt;The whole experiment, reproduced on your project, is three commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project        &lt;span class="c"&gt;# with its existing docker-compose.yml&lt;/span&gt;
opossum up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's safe to try next to Docker: Apple's runtime keeps entirely separate&lt;br&gt;
images, containers, and volumes, so your Docker state isn't touched. &lt;code&gt;opossum&lt;br&gt;
config&lt;/code&gt; shows you up front which compose fields (if any) it will ignore, and&lt;br&gt;
&lt;code&gt;down&lt;/code&gt; cleans everything up.&lt;/p&gt;

&lt;p&gt;Based on this sample: &lt;strong&gt;48% of real-world stacks ran with zero changes, 62%&lt;br&gt;
with at most one line&lt;/strong&gt; — and the failures concentrated in stale samples and&lt;br&gt;
Docker-specific tooling, not in the runtime.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;https://github.com/suruseas/opossum&lt;/a&gt; — and I'd genuinely like to grow&lt;br&gt;
this survey: if you run &lt;code&gt;opossum up&lt;/code&gt; on a real compose file and it breaks,&lt;br&gt;
tell me what broke (here or in an issue). The failure catalog is the product.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>macos</category>
      <category>devops</category>
      <category>containers</category>
    </item>
    <item>
      <title>I ran 29 real docker-compose projects on Apple's container runtime. Here's what broke</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:47:11 +0000</pubDate>
      <link>https://dev.to/suruseas/i-ran-29-real-docker-compose-projects-on-apples-container-runtime-heres-what-broke-28cb</link>
      <guid>https://dev.to/suruseas/i-ran-29-real-docker-compose-projects-on-apples-container-runtime-heres-what-broke-28cb</guid>
      <description>&lt;p&gt;Docker Desktop keeps a &lt;strong&gt;~7.8 GB Linux VM&lt;/strong&gt; provisioned the entire time it's&lt;br&gt;
running — even when zero containers are up. Apple's new&lt;br&gt;
&lt;a href="https://github.com/apple/container" rel="noopener noreferrer"&gt;&lt;code&gt;container&lt;/code&gt;&lt;/a&gt; runtime idles at &lt;strong&gt;~58 MB&lt;/strong&gt; of&lt;br&gt;
helper processes and only spends memory while a container actually runs, because&lt;br&gt;
it boots a lightweight VM &lt;em&gt;per container&lt;/em&gt;, on demand. It hit 1.0 in June, and on&lt;br&gt;
macOS 26 containers can finally talk to each other, which makes multi-service&lt;br&gt;
dev stacks possible.&lt;/p&gt;

&lt;p&gt;So the question stopped being "is it interesting?" and became: &lt;strong&gt;is it&lt;br&gt;
compatible enough to run the &lt;code&gt;docker-compose.yml&lt;/code&gt; files people actually have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of guessing, I measured. I took Docker's own&lt;br&gt;
&lt;a href="https://github.com/docker/awesome-compose" rel="noopener noreferrer"&gt;awesome-compose&lt;/a&gt; repository — the&lt;br&gt;
official collection of sample compose projects (WordPress, React+Express+Mongo,&lt;br&gt;
Spring+Postgres, Prometheus+Grafana, …) — and ran &lt;strong&gt;29 of its samples,&lt;br&gt;
unmodified&lt;/strong&gt;, on Apple &lt;code&gt;container&lt;/code&gt;. An alphabetical slice, no cherry-picking:&lt;br&gt;
every sample from &lt;code&gt;nextcloud-postgres&lt;/code&gt; through &lt;code&gt;wordpress-mysql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the breakdown, and — more useful — &lt;em&gt;why&lt;/em&gt; each failure failed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Apple's &lt;code&gt;container&lt;/code&gt; is a runtime, not an orchestrator: it has no &lt;code&gt;compose&lt;/code&gt;&lt;br&gt;
subcommand, no dependency ordering, no service discovery. For that I used&lt;br&gt;
&lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;opossum&lt;/a&gt;, a small compose-like&lt;br&gt;
orchestrator for Apple &lt;code&gt;container&lt;/code&gt; that I've been building. It reads your&lt;br&gt;
existing &lt;code&gt;compose.yaml&lt;/code&gt; / &lt;code&gt;docker-compose.yml&lt;/code&gt; and gives you the familiar&lt;br&gt;
verbs — &lt;code&gt;up&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;logs&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;down&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
container system start                     &lt;span class="c"&gt;# start the runtime (once)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;container system dns create opossum   &lt;span class="c"&gt;# one-time: DNS domain so services&lt;/span&gt;
                                           &lt;span class="c"&gt;# resolve each other by name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method: macOS 26 on Apple silicon, Apple &lt;code&gt;container&lt;/code&gt; 1.0. For each sample:&lt;br&gt;
&lt;code&gt;cd&lt;/code&gt; in, &lt;code&gt;opossum up&lt;/code&gt;, give it ~90 seconds to come up, check &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;logs&lt;/code&gt;,&lt;br&gt;
categorize, &lt;code&gt;down&lt;/code&gt;, next. Every failure got a second look to find the actual&lt;br&gt;
root cause — the interesting part is &lt;em&gt;whose fault&lt;/em&gt; each one was.&lt;/p&gt;
&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅ Ran &lt;strong&gt;as-is&lt;/strong&gt; — zero changes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WordPress, React+Express+MySQL/Mongo, Spring, nginx+Go+MySQL, pgAdmin, Kafka, …&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔧 Ran after a &lt;strong&gt;one-line&lt;/strong&gt; compose change&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3× Postgres data dir, 1× amd64-only image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏗️ Broken &lt;strong&gt;upstream&lt;/strong&gt; — the sample itself has rotted&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;would fail regardless of runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚫 Can't run &lt;strong&gt;by design&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Docker socket ×2, Linux kernel access ×1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ Environment / setup&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;placeholder path, host port already taken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐌 Build outlasted my timeout&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;a 10–15 min Rust→Wasm build (no errors — I got impatient)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The headline: &lt;strong&gt;18 of 29 real-world stacks run on Apple's runtime today, 14 of&lt;br&gt;
them without touching a single line.&lt;/strong&gt; And of the 11 that didn't, &lt;em&gt;not one&lt;/em&gt;&lt;br&gt;
failed because of the runtime's container execution or networking — every&lt;br&gt;
failure traced to the sample itself, to Docker-specific host features, or to my&lt;br&gt;
environment.&lt;/p&gt;

&lt;p&gt;Let's look at the categories, because a couple of them teach you something&lt;br&gt;
about how Apple's runtime actually differs from Docker.&lt;/p&gt;
&lt;h2&gt;
  
  
  The one-line fixes (and what they reveal)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Postgres refuses its data volume (3 samples)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;nextcloud-postgres&lt;/code&gt;, &lt;code&gt;nginx-golang-postgres&lt;/code&gt;, and &lt;code&gt;spring-postgres&lt;/code&gt; all define&lt;br&gt;
the classic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db-data:/var/lib/postgresql/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Docker this works. On Apple &lt;code&gt;container&lt;/code&gt; Postgres dies with &lt;em&gt;"initdb: error:&lt;br&gt;
directory exists but is not empty"&lt;/em&gt;. Why: the runtime mounts a named volume as&lt;br&gt;
a real ext4 mount point — which contains &lt;code&gt;lost+found&lt;/code&gt; — and &lt;code&gt;initdb&lt;/code&gt; refuses a&lt;br&gt;
non-empty directory. Docker's volumes don't surface that detail.&lt;/p&gt;

&lt;p&gt;The one-line fix is the same one you'd use on any bare-metal mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;PGDATA&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/postgresql/data/pgdata&lt;/span&gt;   &lt;span class="c1"&gt;# a subdirectory of the mount&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is &lt;em&gt;everywhere&lt;/em&gt; in self-hosted app composes (Gitea, Nextcloud,&lt;br&gt;
…), so opossum detects it at &lt;code&gt;up&lt;/code&gt; time and prints exactly that suggested fix.&lt;br&gt;
MySQL and MariaDB tolerate the mount point, which is why the WordPress and&lt;br&gt;
MySQL samples sailed through.&lt;/p&gt;
&lt;h3&gt;
  
  
  amd64-only images (1 sample)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;nginx-nodejs-redis&lt;/code&gt; uses &lt;code&gt;redismod&lt;/code&gt;, an image published only for x86-64. The&lt;br&gt;
fix is the same line you'd add for Docker on Apple silicon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;opossum passes the platform through and automatically enables Rosetta&lt;br&gt;
translation for the container, so the x86-64 image runs on the arm64 VM.&lt;/p&gt;
&lt;h2&gt;
  
  
  The ones that were broken before I arrived (5 samples)
&lt;/h2&gt;

&lt;p&gt;This was the fun discovery. Five samples fail &lt;em&gt;on any runtime&lt;/em&gt; today, because&lt;br&gt;
they pin nothing and the world moved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nginx-flask-mysql&lt;/code&gt; — Flask backend crashes with &lt;code&gt;ImportError: cannot import
name 'url_quote' from 'werkzeug.urls'&lt;/code&gt;: the famous Flask/Werkzeug 2.1 break,
hit because the sample doesn't pin Werkzeug. (The nginx "host not found in
upstream" error that follows is just the dead backend cascading.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prometheus-grafana&lt;/code&gt; — the unpinned &lt;code&gt;prom/prometheus&lt;/code&gt; image now rejects the
sample's &lt;code&gt;api_version: v1&lt;/code&gt; Alertmanager config.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nginx-wsgi-flask&lt;/code&gt;, &lt;code&gt;react-rust-postgres&lt;/code&gt;, &lt;code&gt;vuejs&lt;/code&gt; — &lt;code&gt;pip install&lt;/code&gt; /
&lt;code&gt;cargo&lt;/code&gt; / &lt;code&gt;yarn global add&lt;/code&gt; failures during build, all dependency rot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I went in expecting to find runtime incompatibilities; instead I found a small&lt;br&gt;
museum of what happens to unmaintained compose files after a few years. If&lt;br&gt;
your own stack pins its images and dependencies, this whole category doesn't&lt;br&gt;
apply to you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Can't run by design (3 samples)
&lt;/h2&gt;

&lt;p&gt;Full honesty, because this is where the model genuinely differs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;portainer&lt;/code&gt;, &lt;code&gt;traefik-golang&lt;/code&gt;&lt;/strong&gt; bind-mount &lt;code&gt;/var/run/docker.sock&lt;/code&gt; — they
manage/inspect &lt;em&gt;Docker&lt;/em&gt;. Apple's runtime has no Docker socket; anything whose
job is talking to the Docker daemon is out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;wireguard&lt;/code&gt;&lt;/strong&gt; needs &lt;code&gt;NET_ADMIN&lt;/code&gt; plus the host's kernel modules
(&lt;code&gt;/lib/modules&lt;/code&gt;). There's no shared Linux host kernel to reach into — each
container has its own micro-VM. (Docker Desktop on a Mac can't satisfy the
host-path part either.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your compose file is "a normal app + database + cache", none of this&lt;br&gt;
touches you. If it's host-level infrastructure tooling, stay on Docker.&lt;/p&gt;
&lt;h2&gt;
  
  
  The rest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;plex&lt;/code&gt; ships a placeholder bind path (&lt;code&gt;/media/your/plex/path&lt;/code&gt;) you're meant
to edit — environment, not compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pihole-cloudflared-DoH&lt;/code&gt; wants host port 53, which my Mac was already using.
(opossum checks published ports up front and names the conflict instead of
failing mid-startup.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wasmedge-mysql-nginx&lt;/code&gt; compiles Rust to WebAssembly inside the build —
10–15 minutes of &lt;code&gt;cargo build&lt;/code&gt;. It was progressing without errors when my
90-second patience ran out, so it goes in the "almost certainly fine" pile,
not the failure pile.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Gotchas beyond this sample set
&lt;/h2&gt;

&lt;p&gt;Two more differences worth knowing before you try your own stack, found in&lt;br&gt;
wider testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fresh volumes mount empty.&lt;/strong&gt; Docker pre-fills a brand-new named/anonymous
volume from the image's contents at that path; Apple &lt;code&gt;container&lt;/code&gt; doesn't.
That breaks the beloved &lt;code&gt;- /app/node_modules&lt;/code&gt; trick. opossum replicates
Docker's seeding behavior itself, so this pattern works — but it's a real
runtime difference you'd hit with raw &lt;code&gt;container&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cgroup-sniffing JVMs crash.&lt;/strong&gt; Elasticsearch 7.x's bundled JDK reads the
host cgroup to size its heap, and the micro-VM doesn't expose the mount it
expects — it dies at launch before any config applies. A runtime/JDK
incompatibility with no workaround I know of.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the trade-offs cut both ways — this isn't "Docker but better":&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;Docker Desktop&lt;/th&gt;
&lt;th&gt;Apple &lt;code&gt;container&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Idle memory&lt;/td&gt;
&lt;td&gt;~373 MB host procs + &lt;strong&gt;~7.8 GB VM&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~58 MB&lt;/strong&gt;, no always-on VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single container start&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~0.19 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~0.81 s (boots a fresh micro-VM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bind-mount small-file I/O&lt;/td&gt;
&lt;td&gt;slow&lt;/td&gt;
&lt;td&gt;slightly &lt;strong&gt;slower&lt;/strong&gt; (same host↔VM model)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;shared VM kernel&lt;/td&gt;
&lt;td&gt;per-container VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;paid for larger orgs&lt;/td&gt;
&lt;td&gt;open source&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Docker still wins if you churn many short-lived containers or hammer bind&lt;br&gt;
mounts. Apple's runtime wins on footprint and isolation. (Numbers from one&lt;br&gt;
machine — &lt;a href="https://github.com/suruseas/opossum/blob/main/docs/benchmarks.md" rel="noopener noreferrer"&gt;method and caveats here&lt;/a&gt;.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it on your own compose file
&lt;/h2&gt;

&lt;p&gt;The whole experiment, reproduced on your project, is three commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project        &lt;span class="c"&gt;# with its existing docker-compose.yml&lt;/span&gt;
opossum up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's safe to try next to Docker: Apple's runtime keeps entirely separate&lt;br&gt;
images, containers, and volumes, so your Docker state isn't touched. &lt;code&gt;opossum&lt;br&gt;
config&lt;/code&gt; shows you up front which compose fields (if any) it will ignore, and&lt;br&gt;
&lt;code&gt;down&lt;/code&gt; cleans everything up.&lt;/p&gt;

&lt;p&gt;Based on this sample: &lt;strong&gt;48% of real-world stacks ran with zero changes, 62%&lt;br&gt;
with at most one line&lt;/strong&gt; — and the failures concentrated in stale samples and&lt;br&gt;
Docker-specific tooling, not in the runtime.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;https://github.com/suruseas/opossum&lt;/a&gt; — and I'd genuinely like to grow&lt;br&gt;
this survey: if you run &lt;code&gt;opossum up&lt;/code&gt; on a real compose file and it breaks,&lt;br&gt;
tell me what broke (here or in an issue). The failure catalog is the product.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>macos</category>
      <category>devops</category>
      <category>containers</category>
    </item>
    <item>
      <title>Run your docker-compose.yml on Apple's container runtime</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Mon, 06 Jul 2026 16:49:45 +0000</pubDate>
      <link>https://dev.to/suruseas/run-your-docker-composeyml-on-apples-container-runtime-10o3</link>
      <guid>https://dev.to/suruseas/run-your-docker-composeyml-on-apples-container-runtime-10o3</guid>
      <description>&lt;p&gt;If you develop on a Mac and reach for &lt;code&gt;docker compose&lt;/code&gt; to spin up a multi-service&lt;br&gt;
stack, you might like &lt;strong&gt;&lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;opossum&lt;/a&gt;&lt;/strong&gt; — a small,&lt;br&gt;
Docker Compose–like orchestrator for &lt;strong&gt;&lt;a href="https://github.com/apple/container" rel="noopener noreferrer"&gt;Apple's &lt;code&gt;container&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
runtime on macOS 26.&lt;/p&gt;

&lt;p&gt;The pitch is simple: &lt;strong&gt;point it at a &lt;code&gt;docker-compose.yml&lt;/code&gt; you already have and run&lt;br&gt;
&lt;code&gt;opossum up&lt;/code&gt;.&lt;/strong&gt; The commands and mental model are the same ones you already know —&lt;br&gt;
&lt;code&gt;up&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;logs&lt;/code&gt;, &lt;code&gt;down&lt;/code&gt; — but everything runs on Apple's native &lt;code&gt;container&lt;/code&gt;&lt;br&gt;
runtime (a lightweight VM per container) instead of Docker Desktop.&lt;/p&gt;

&lt;p&gt;Let me show you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;opossum ships as a Homebrew formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two one-time steps (Apple &lt;code&gt;container&lt;/code&gt; prerequisites):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;container system start                    &lt;span class="c"&gt;# start the runtime&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;container system dns create opossum  &lt;span class="c"&gt;# register a local DNS domain so&lt;/span&gt;
                                          &lt;span class="c"&gt;# services can find each other by name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. (Requires macOS 26 on Apple silicon, since the runtime's&lt;br&gt;
container-to-container networking relies on macOS 26 features.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Just try it on a project you already have
&lt;/h2&gt;

&lt;p&gt;The fastest way to get a feel for it: &lt;code&gt;cd&lt;/code&gt; into a directory you already run with&lt;br&gt;
&lt;code&gt;docker compose&lt;/code&gt; and run &lt;code&gt;opossum up&lt;/code&gt;. For a lot of stacks it just works — same&lt;br&gt;
file, same command, nothing to change. (opossum finds your &lt;code&gt;compose.yaml&lt;/code&gt; or&lt;br&gt;
&lt;code&gt;docker-compose.yml&lt;/code&gt; automatically.)&lt;/p&gt;

&lt;p&gt;And it's &lt;strong&gt;safe to try side by side with Docker.&lt;/strong&gt; opossum drives Apple's&lt;br&gt;
&lt;code&gt;container&lt;/code&gt; runtime, which is entirely separate from Docker — its own images,&lt;br&gt;
containers, and volumes — so running &lt;code&gt;opossum up&lt;/code&gt; won't touch your Docker&lt;br&gt;
containers or data.&lt;/p&gt;

&lt;p&gt;To follow along in this post, here's a tiny stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;opossum up&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum up
&lt;span class="go"&gt;Creating network intro-net
Starting redis (redis:7)
redis.intro.opossum
Starting web (nginx:alpine)
web.intro.opossum
  ↳ web on the host: localhost:8080
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It starts the services in dependency order (redis before web, because &lt;code&gt;web&lt;/code&gt;&lt;br&gt;
&lt;code&gt;depends_on&lt;/code&gt; it) and tells you where to reach a published service from the host —&lt;br&gt;
&lt;code&gt;localhost:8080&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;opossum ps&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Same output you'd expect from &lt;code&gt;docker compose ps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum ps
&lt;span class="go"&gt;SERVICE  CONTAINER            IMAGE         IP            PORTS                 STATUS
redis    redis.intro.opossum  redis:7       192.168.67.2  -                     running
&lt;/span&gt;&lt;span class="gp"&gt;web      web.intro.opossum    nginx:alpine  192.168.67.3  0.0.0.0:8080-&amp;gt;&lt;/span&gt;80/tcp  running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:8080&lt;/code&gt; in your browser (or curl it) and you get nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8080/ | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-4&lt;/span&gt;
&lt;span class="gp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Services find each other by name
&lt;/h2&gt;

&lt;p&gt;Just like Compose, peers reach each other by their &lt;strong&gt;service name&lt;/strong&gt; over the&lt;br&gt;
project's network. From inside the &lt;code&gt;web&lt;/code&gt; container, &lt;code&gt;redis&lt;/code&gt; resolves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum &lt;span class="nb"&gt;exec &lt;/span&gt;web sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"getent hosts redis"&lt;/span&gt;
&lt;span class="go"&gt;...  redis.intro.opossum  redis
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So your app connects to &lt;code&gt;redis:6379&lt;/code&gt; — no IPs, no hardcoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;opossum logs&lt;/code&gt; and &lt;code&gt;opossum stats&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Follow logs like usual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum logs redis
&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;1:M 06 Jul 2026 16:43:09.983 * Ready to accept connections tcp
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there's a &lt;code&gt;docker stats&lt;/code&gt;–style live view of resource usage per service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum stats &lt;span class="nt"&gt;--no-stream&lt;/span&gt;
&lt;span class="go"&gt;Container ID         Cpu %  Memory Usage          Net Rx/Tx             Block I/O             Pids
redis.intro.opossum  0.74%  29.91 MiB / 1.00 GiB  16.18 KiB / 0.57 KiB  25.68 MiB / 0.00 KiB  6
web.intro.opossum    0.00%  15.48 MiB / 1.00 GiB  15.15 KiB / 2.14 KiB  9.94 MiB / 4.00 KiB   6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;opossum down&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;opossum down
&lt;span class="go"&gt;Stopping web
Stopping redis
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tears everything down in reverse order and removes the project network. Add &lt;code&gt;-v&lt;/code&gt;&lt;br&gt;
to also drop named volumes.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's &lt;em&gt;almost&lt;/em&gt; the same as docker compose
&lt;/h2&gt;

&lt;p&gt;If you know Compose, you already know opossum. The everyday commands map 1:1:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You'd type in Compose&lt;/th&gt;
&lt;th&gt;With opossum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opossum up&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose ps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opossum ps&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose logs -f web&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opossum logs web -f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose exec web sh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opossum exec -it web sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose down -v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;opossum down -v&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;opossum also has &lt;code&gt;stats&lt;/code&gt;, &lt;code&gt;images&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;run&lt;/code&gt;, &lt;code&gt;start&lt;/code&gt;/&lt;code&gt;stop&lt;/code&gt;/&lt;br&gt;
&lt;code&gt;restart&lt;/code&gt;/&lt;code&gt;kill&lt;/code&gt;, and &lt;code&gt;config&lt;/code&gt; — the usual toolbox.&lt;/p&gt;

&lt;p&gt;A few honest differences, since it targets Apple's runtime rather than Docker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-time setup&lt;/strong&gt;: the &lt;code&gt;sudo container system dns create opossum&lt;/code&gt; step above,
which is what makes bare-name service discovery work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime&lt;/strong&gt;: it's Apple &lt;code&gt;container&lt;/code&gt; (a per-container lightweight VM), not Docker
Engine. Compose fields the runtime can't act on (like custom &lt;code&gt;networks:&lt;/code&gt; or
&lt;code&gt;container_name:&lt;/code&gt;) are parsed and &lt;strong&gt;warned about&lt;/strong&gt;, not silently dropped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS 26 + Apple silicon&lt;/strong&gt; only.&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;brew &lt;span class="nb"&gt;install &lt;/span&gt;suruseas/opossum/opossum
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project-with-a-compose-file
opossum up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repo: &lt;a href="https://github.com/suruseas/opossum" rel="noopener noreferrer"&gt;https://github.com/suruseas/opossum&lt;/a&gt;. If you have a &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;br&gt;
lying around, give &lt;code&gt;opossum up&lt;/code&gt; a try and see how far it gets — for a lot of&lt;br&gt;
stacks, the answer is "all the way."&lt;/p&gt;

</description>
      <category>docker</category>
      <category>macos</category>
      <category>containers</category>
      <category>devtools</category>
    </item>
    <item>
      <title>🐢 and 🐇 in My Claude Code Status Line: Now Watching the Week</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Mon, 11 May 2026 15:45:27 +0000</pubDate>
      <link>https://dev.to/suruseas/and-in-my-claude-code-status-line-now-watching-the-week-1m1e</link>
      <guid>https://dev.to/suruseas/and-in-my-claude-code-status-line-now-watching-the-week-1m1e</guid>
      <description>&lt;p&gt;I recently built a tortoise-and-hare status line for Claude Code that shows whether you're burning tokens faster than a steady pace. &lt;a href="https://dev.to/suruseas/and-in-my-claude-code-status-line-372f"&gt;That post is here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then &lt;a href="https://www.anthropic.com/news/higher-limits-spacex" rel="noopener noreferrer"&gt;Anthropic raised the 5h limit but tightened the weekly cap&lt;/a&gt;. Suddenly the 7-day limit became the one that actually bites — with the relaxed 5h window, hitting 100% in five hours takes real effort. The weekly cap doesn't.&lt;/p&gt;

&lt;p&gt;So I updated the script: 7d gets the full-width tortoise/hare bar, 5h keeps the same logic in a shorter bar on the right:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Sonnet 4.6] ········🐢···········🐇 7d:105% ⚠️@5/14 | ··🐢··🐇··· 5h:70% ⚠️@18:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The &lt;code&gt;7d:105%&lt;/code&gt; is real — that's what I'm seeing right now. Going over 100% means you're into Claude Code's additional usage allowance beyond the base weekly limit. The 🐇 flies off the right edge of the bar when that happens.)&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;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.model.display_name'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;FIVE_H_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'(.rate_limits.five_hour.used_percentage // 0)'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SEVEN_D_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'(.rate_limits.seven_day.used_percentage // 0)'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;FIVE_H_RESETS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.rate_limits.five_hour.resets_at // empty'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SEVEN_D_RESETS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.rate_limits.seven_day.resets_at // empty'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;NOW&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;TZ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Asia/Tokyo  &lt;span class="c"&gt;# change to your local timezone&lt;/span&gt;
&lt;span class="nv"&gt;W7&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;20&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;W5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10   &lt;span class="c"&gt;# bar widths: 7d full, 5h half&lt;/span&gt;

make_bar&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="nv"&gt;ideal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt; &lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; i
    &lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;0 &lt;span class="k"&gt;$((&lt;/span&gt;width &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ideal&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐢🐇"&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ideal&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐢"&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐇"&lt;/span&gt;
        &lt;span class="k"&gt;else &lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;·"&lt;/span&gt;
        &lt;span class="k"&gt;fi
    done&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$width&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐇"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$bar&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 7-day window (main bar, width=20)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SEVEN_D_RESETS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;REMAINING_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;SEVEN_D_RESETS &lt;span class="o"&gt;-&lt;/span&gt; NOW&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_7D_MD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SEVEN_D_RESETS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"+%m/%d"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;/ &lt;span class="s1"&gt;'{printf "%d/%d", $1, $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_7D_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET_7D_MD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 604800 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;604800&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; REMAINING_7D&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; W7 &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;604800&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
    &lt;span class="k"&gt;fi
else
    &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;RESET_7D_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"@?"&lt;/span&gt;
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nv"&gt;ACTUAL_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN {print int(&lt;/span&gt;&lt;span class="nv"&gt;$SEVEN_D_PCT&lt;/span&gt;&lt;span class="s2"&gt; * &lt;/span&gt;&lt;span class="nv"&gt;$W7&lt;/span&gt;&lt;span class="s2"&gt; / 100)}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BAR_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;make_bar &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$W7&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_7D&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;WARN_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" ⚠️"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;WARN_7D&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nv"&gt;SEVEN_D_DISP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%.0f"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SEVEN_D_PCT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# 5-hour window (half bar, width=10)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_RESETS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;REMAINING_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;FIVE_H_RESETS &lt;span class="o"&gt;-&lt;/span&gt; NOW&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_5H_JST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_RESETS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"+%H:%M"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_5H_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET_5H_JST&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 18000 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;18000&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; REMAINING_5H&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; W5 &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;18000&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
    &lt;span class="k"&gt;fi
else
    &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;RESET_5H_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"@?"&lt;/span&gt;
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nv"&gt;ACTUAL_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN {print int(&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_PCT&lt;/span&gt;&lt;span class="s2"&gt; * &lt;/span&gt;&lt;span class="nv"&gt;$W5&lt;/span&gt;&lt;span class="s2"&gt; / 100)}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BAR_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;make_bar &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$W5&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_5H&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;WARN_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" ⚠️"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;WARN_5H&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nv"&gt;FIVE_H_DISP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%.0f"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_PCT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MODEL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR_7D&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 7d:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SEVEN_D_DISP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WARN_7D&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET_7D_TAG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR_5H&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 5h:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FIVE_H_DISP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WARN_5H&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET_5H_TAG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;W7=20&lt;/code&gt; and &lt;code&gt;W5=10&lt;/code&gt; control bar widths. &lt;code&gt;18000&lt;/code&gt; = 5 hours in seconds, &lt;code&gt;604800&lt;/code&gt; = 7 days. Change &lt;code&gt;TZ=Asia/Tokyo&lt;/code&gt; at the top to your local timezone.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>programming</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>🐢 and 🐇 in My Claude Code Status Line</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Thu, 30 Apr 2026 09:28:08 +0000</pubDate>
      <link>https://dev.to/suruseas/and-in-my-claude-code-status-line-372f</link>
      <guid>https://dev.to/suruseas/and-in-my-claude-code-status-line-372f</guid>
      <description>&lt;p&gt;The Claude Code status line gives you a JSON blob and lets you render whatever you want. &lt;a href="https://code.claude.com/docs/en/statusline" rel="noopener noreferrer"&gt;Docs here.&lt;/a&gt; I made mine an Aesop's fable — borrowing the idea from &lt;a href="https://rabbit-shocker.org/ja/" rel="noopener noreferrer"&gt;Rabbit&lt;/a&gt;, a presentation tool by Kouhei Sutou that famously races a rabbit against a tortoise to show whether you're on pace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Sonnet 4.6] ········🐢····🐇······· 5h:62% ⚠️ | reset 18:00 | 7d:23%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;🐢 = where you &lt;em&gt;should&lt;/em&gt; be (time elapsed in the 5-hour window). &lt;/li&gt;
&lt;li&gt;🐇 = where you &lt;em&gt;actually&lt;/em&gt; are (tokens used).&lt;/li&gt;
&lt;li&gt;⚠️  = hare is ahead, you're burning too fast.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point: a raw "62%" means opposite things at hour 1 vs hour 4. Comparing actual pace to ideal pace is what I actually want to know — and the tortoise/hare visual does it at a glance, no mental math.&lt;/p&gt;

&lt;h2&gt;
  
  
  The script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.model.display_name'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;FIVE_H_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'(.rate_limits.five_hour.used_percentage // 0)'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SEVEN_D_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'(.rate_limits.seven_day.used_percentage // 0) * 10 | floor | . / 10'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;RESETS_AT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.rate_limits.five_hour.resets_at // empty'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESETS_AT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;REMAINING_SEC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;RESETS_AT &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_JST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nv"&gt;TZ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Asia/Tokyo &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESETS_AT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"+%H:%M"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;RESET_STR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" | reset &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET_JST&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_SEC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REMAINING_SEC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 18000 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;18000&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; REMAINING_SEC&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;18000&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
    &lt;span class="k"&gt;fi
else
    &lt;/span&gt;&lt;span class="nv"&gt;IDEAL_PCT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;RESET_STR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;BAR_WIDTH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;20
&lt;span class="nv"&gt;ACTUAL_POS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN {print int(&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_PCT&lt;/span&gt;&lt;span class="s2"&gt; * &lt;/span&gt;&lt;span class="nv"&gt;$BAR_WIDTH&lt;/span&gt;&lt;span class="s2"&gt; / 100)}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;IDEAL_POS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;IDEAL_PCT &lt;span class="o"&gt;*&lt;/span&gt; BAR_WIDTH &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;

&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;0 &lt;span class="k"&gt;$((&lt;/span&gt;BAR_WIDTH &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐢🐇"&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐢"&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then &lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;🐇"&lt;/span&gt;
    &lt;span class="k"&gt;else &lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;·"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTUAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IDEAL_POS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;WARN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" ⚠️"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;WARN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nv"&gt;FIVE_H_DISP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FIVE_H_PCT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{printf "%.0f", $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="nv"&gt;$MODEL&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 5h:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FIVE_H_DISP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WARN&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET_STR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | 7d:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SEVEN_D_PCT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;18000&lt;/code&gt; is 5 hours in seconds. Drop &lt;code&gt;TZ=Asia/Tokyo&lt;/code&gt; for your local zone.&lt;/p&gt;

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

&lt;p&gt;Save as &lt;code&gt;~/.claude/statusline.sh&lt;/code&gt;, &lt;code&gt;chmod +x&lt;/code&gt; it, then in &lt;code&gt;~/.claude/settings.json&lt;/code&gt;:&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;"statusLine"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&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;"~/.claude/statusline.sh"&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;Restart Claude Code. Done.&lt;/p&gt;




&lt;p&gt;The rabbit-vs-tortoise pacing metaphor is lifted straight from &lt;a href="https://rabbit-shocker.org/ja/" rel="noopener noreferrer"&gt;Rabbit&lt;/a&gt; (うさぎとかめ). Same idea, different domain — slide timer → token budget.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>programming</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Stop Counting Prompts — Start Reflecting on AI Fluency</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Sat, 28 Mar 2026 05:03:07 +0000</pubDate>
      <link>https://dev.to/suruseas/stop-counting-prompts-start-reflecting-on-ai-fluency-32n4</link>
      <guid>https://dev.to/suruseas/stop-counting-prompts-start-reflecting-on-ai-fluency-32n4</guid>
      <description>&lt;h2&gt;
  
  
  "I'm the best at piloting this thing!"
&lt;/h2&gt;

&lt;p&gt;There's a famous line from a Japanese mecha anime — the protagonist screams: &lt;strong&gt;「僕が一番ガンダムをうまく使えるんだ！」&lt;/strong&gt; — &lt;em&gt;"I'm the one who can pilot this Gundam the best!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you use AI coding tools every day, you've probably felt something similar. That sense of clicking with the AI. Knowing you're getting more out of it than most people around you.&lt;/p&gt;

&lt;p&gt;But how do you show that?&lt;/p&gt;

&lt;p&gt;"Look at my PR count"? "Check how many lines I generated"? That's not it. Those numbers don't capture the &lt;em&gt;feel&lt;/em&gt; of working well with AI. That nagging gap between what you &lt;em&gt;know&lt;/em&gt; and what you can &lt;em&gt;prove&lt;/em&gt; is what got me started.&lt;/p&gt;

&lt;h2&gt;
  
  
  My own question, answered
&lt;/h2&gt;

&lt;p&gt;In my previous post, I asked:&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6" class="crayons-story__hidden-navigation-link"&gt;I Deleted 66% of My AI Coding Guide — Here's What Survived&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/suruseas" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852203%2Fe8e2c8e4-a9f6-4726-9878-22f90505518c.jpeg" alt="suruseas profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/suruseas" class="crayons-story__secondary fw-medium m:hidden"&gt;
              yukihiro amadatsu
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                yukihiro amadatsu
                
              
              &lt;div id="story-author-preview-content-3367393" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/suruseas" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852203%2Fe8e2c8e4-a9f6-4726-9878-22f90505518c.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;yukihiro amadatsu&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6" id="article-link-3367393"&gt;
          I Deleted 66% of My AI Coding Guide — Here's What Survived
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/codequality"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;codequality&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Is your team measuring AI coding productivity by any of these?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Common metric&lt;/th&gt;
&lt;th&gt;What it actually rewards&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code generated&lt;/td&gt;
&lt;td&gt;Volume targets promote bloat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of prompts per session&lt;/td&gt;
&lt;td&gt;High count may signal poor instructions, not hard work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response speed&lt;/td&gt;
&lt;td&gt;Penalizes people who think before they ask&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commit count&lt;/td&gt;
&lt;td&gt;Easily inflated by splitting work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of AI tools adopted&lt;/td&gt;
&lt;td&gt;Using ≠ using well&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They all measure &lt;em&gt;quantity&lt;/em&gt;. But whether you're actually good at working with AI never shows up in volume metrics.&lt;/p&gt;

&lt;p&gt;That article laid out three enduring principles: &lt;strong&gt;keep things reversible, make intent explicit, verify outputs&lt;/strong&gt;. AI Fluency is my attempt to turn those into a structured self-reflection — not a score that ranks you, but a mirror that shows you &lt;em&gt;how&lt;/em&gt; you collaborate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "Fluency"?
&lt;/h2&gt;

&lt;p&gt;Fluency — like language fluency. When you're fluent, conversation flows naturally. You don't stumble, backtrack, or struggle to express what you mean.&lt;/p&gt;

&lt;p&gt;Working with AI has a similar feel. When it's going well, your instructions and the AI's output click, and the work just &lt;em&gt;flows&lt;/em&gt;. When it's not, you're stuck in loops of corrections and rework.&lt;/p&gt;

&lt;p&gt;AI Fluency tries to visualize that — &lt;em&gt;how naturally you collaborate with AI&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's what I built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsar5mxi2rwmlzujgco2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsar5mxi2rwmlzujgco2o.png" alt="AI Fluency scorecard showing a 5-axis radar chart with style type, rank, and axis scores" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My result: &lt;strong&gt;The Explorer&lt;/strong&gt; — the type that explores new ways of using AI. Strong in Breadth, with room to grow in Precision.&lt;/p&gt;

&lt;p&gt;Full ability sheet: &lt;a href="https://github.com/suruseas/ai-fluency/blob/main/output/profile.md" rel="noopener noreferrer"&gt;profile.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/suruseas/ai-fluency" rel="noopener noreferrer"&gt;github.com/suruseas/ai-fluency&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Also available in Japanese on &lt;a href="https://qiita.com/suruseas/items/1f4f701f439fded0cb40" rel="noopener noreferrer"&gt;Qiita&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A Different Yardstick: 5 Axes
&lt;/h2&gt;

&lt;p&gt;By breaking down what "fluency" actually means in practice, I landed on five dimensions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Axis&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context Design&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Setting up the environment so the AI can do its best work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Precision&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Communicating intent clearly with minimal back-and-forth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Steering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Guiding AI output in the right direction; judging quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Actually delivering value through AI collaboration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Breadth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Using AI's capabilities across diverse tasks, not just one pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first three map to the enduring principles from the previous article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Make intent explicit" → &lt;strong&gt;Context Design&lt;/strong&gt; + &lt;strong&gt;Precision&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;"Verify outputs" → &lt;strong&gt;Steering&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The remaining two go further — asking whether the collaboration actually produces results (&lt;strong&gt;Output&lt;/strong&gt;) and whether you're using AI's full range or stuck in a single pattern (&lt;strong&gt;Breadth&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Not "fewer prompts is better" — but "can you get it right with fewer exchanges?" Not "more commits" — but "are you actually achieving your goals?" That shift — from quantity to quality — is the whole point.&lt;/p&gt;

&lt;h3&gt;
  
  
  A note on methodology
&lt;/h3&gt;

&lt;p&gt;These five axes weren't derived from a literature review or formal research. They emerged from iterating with AI itself — breaking down what "good collaboration" felt like across dozens of my own sessions, then pressure-testing the categories until they stopped overlapping. It's an opinionated framework, not a scientific instrument. I think that's okay for a self-reflection tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  16 Style Types — A Bit of Fun That Stuck
&lt;/h2&gt;

&lt;p&gt;After generating the 5-axis scores, I realized raw numbers are hard to talk about. "My Context Design is 76 and Breadth is 96" — not exactly cocktail-party material.&lt;/p&gt;

&lt;p&gt;So I put together a personality-type system on a whim — classifying people by the &lt;em&gt;shape&lt;/em&gt; of their radar chart. It turned out to be surprisingly intuitive, so it stuck.&lt;/p&gt;

&lt;p&gt;The types are determined by &lt;strong&gt;which axes stand out&lt;/strong&gt;, not by how high your scores are. It's about style, not rank. Here are a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Sniper&lt;/strong&gt; (Precision) — Minimum input, maximum output. One-shot instructions that just work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Architect&lt;/strong&gt; (Context Design) — Master of setting the stage. The AI barely needs to ask questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Explorer&lt;/strong&gt; (Breadth) — Always finding new ways to use AI. First to try MCP, plugins, sub-agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Surgeon&lt;/strong&gt; (Precision + Steering) — Precision and finesse for tough problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Virtuoso&lt;/strong&gt; (Balanced) — Well-rounded across all axes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 16 types in total (1 balanced + 5 primary + 10 hybrid). &lt;a href="https://github.com/suruseas/ai-fluency" rel="noopener noreferrer"&gt;See the full list in the repo.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;High scores across the board aren't the goal — every shape has meaning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest Limitations
&lt;/h2&gt;

&lt;p&gt;This is a &lt;strong&gt;self-reflection tool&lt;/strong&gt;, not a performance metric. A couple of things to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scores vary between runs.&lt;/strong&gt; The qualitative assessment uses an LLM, so results aren't deterministic. That's a tradeoff of using AI-based evaluation — I leaned into it by emphasizing &lt;em&gt;shape&lt;/em&gt; over absolute numbers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style is personal, not comparable.&lt;/strong&gt; Common rubric, but not an identical scale. Your "72" and someone else's "72" don't mean the same thing. The radar chart shape is what matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's also an inherent circularity worth naming: the tool uses an LLM to evaluate how well you work with an LLM. It may have blind spots — for example, favoring verbose sessions over terse-but-expert ones. I don't have a fix for that yet, but I think the transparency of the framework (all scoring logic is in the repo) helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;p&gt;It currently supports &lt;strong&gt;Claude Code&lt;/strong&gt; session data. The five axes themselves are agent-agnostic by design — support for other agents is planned.&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;# 1. Clone &amp;amp; setup&lt;/span&gt;
git clone https://github.com/suruseas/ai-fluency.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ai-fluency
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# 2. Generate session analysis in Claude Code&lt;/span&gt;
claude&amp;gt; /insights

&lt;span class="c"&gt;# 3. Generate your scorecard (English output)&lt;/span&gt;
npm run score           &lt;span class="c"&gt;# → output/scores.json&lt;/span&gt;
npm run card            &lt;span class="c"&gt;# → output/card-dark.svg, card-light.svg&lt;/span&gt;
npm run profile         &lt;span class="c"&gt;# → output/profile.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Or even simpler:&lt;/strong&gt; if you're already in a Claude Code session, just type &lt;strong&gt;&lt;code&gt;/ai-fluency&lt;/code&gt;&lt;/strong&gt; — it handles everything in one shot.&lt;/p&gt;

&lt;p&gt;This produces SVG cards (dark/light themes) and a Markdown ability sheet in &lt;code&gt;output/&lt;/code&gt;. To embed the card in your GitHub README, &lt;a href="https://github.com/suruseas/ai-fluency#embedding-in-your-readme" rel="noopener noreferrer"&gt;see the instructions in the repo&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;This started as my answer to a question I posed in my previous article: if lines of code and prompt counts are the wrong metrics, what &lt;em&gt;should&lt;/em&gt; we look at?&lt;/p&gt;

&lt;p&gt;My answer: &lt;strong&gt;Context Design, Precision, Steering, Output, Breadth&lt;/strong&gt; — the quality of human-AI collaboration, not the volume.&lt;/p&gt;

&lt;p&gt;It's not a perfect tool. But if it makes you stop and think, "Huh, so &lt;em&gt;that's&lt;/em&gt; how I work with AI" — that's enough.&lt;/p&gt;

&lt;p&gt;If you use Claude Code, it takes about 2 minutes. Drop your type in the comments — I'll compile the dev.to distribution in a follow-up post!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/suruseas" rel="noopener noreferrer"&gt;
        suruseas
      &lt;/a&gt; / &lt;a href="https://github.com/suruseas/ai-fluency" rel="noopener noreferrer"&gt;
        ai-fluency
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI Fluency - Score your AI collaboration style across 5 axes
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AI Fluency&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;GitHub プロフィールに貼れる「AI活用力」のスコアカード生成ツール。&lt;/p&gt;

&lt;p&gt;AI エージェントとの協働スタイルを5軸でスコアリングし、SVGカードと能力シートを出力します。評価軸はエージェント共通の設計ですが、現時点では &lt;strong&gt;Claude Code&lt;/strong&gt; のセッション分析データ（&lt;code&gt;/insights&lt;/code&gt; で生成）に対応しています。&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;カード例&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
  &lt;br&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fsuruseas%2Fai-fluency%2F.%2Foutput%2Fcard-light.svg" 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%2Fgithub.com%2Fsuruseas%2Fai-fluency%2F.%2Foutput%2Fcard-light.svg" alt="AI Fluency Card"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;前提条件&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;現在の対応エージェント: &lt;strong&gt;Claude Code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.anthropic.com/en/docs/claude-code" rel="nofollow noopener noreferrer"&gt;Claude Code&lt;/a&gt; がインストール済みであること&lt;/li&gt;
&lt;li&gt;Claude Code でのセッション履歴があること（分析対象データとして必要）&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;他の AI エージェントへの対応は今後追加予定です。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;試してみる&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. リポジトリをクローンしてセットアップ&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/suruseas/ai-fluency.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; ai-fluency
npm install&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. facets データを生成する&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Claude Code で &lt;code&gt;/insights&lt;/code&gt; を実行してください。セッション履歴が分析され、&lt;code&gt;~/.claude/usage-data/facets/&lt;/code&gt; に facets データ（JSON）が生成されます。&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;claude&amp;gt; /insights
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; facets データがない状態では以降のステップは実行できません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. スコアカードを生成する&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;クローンしたディレクトリで Claude Code を起動し、&lt;code&gt;/ai-fluency&lt;/code&gt; を実行します。&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; ai-fluency
claude&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;claude&amp;gt; /ai-fluency
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;直近3ヶ月分のデータを対象に、スコア算出からカード・能力シートの生成まですべて自動で行われます。&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;手動で実行する場合&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 定量スコアのみ算出（output/scores.json に出力）&lt;/span&gt;
npm run score

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; SVG カードを生成（output/card-dark.svg, card-light.svg）&lt;/span&gt;
npm run card:ja     &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 日本語版&lt;/span&gt;
npm run card        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 英語版（デフォルト）&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 能力シートを生成（output/profile.md）&lt;/span&gt;
npm run profile:ja  &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 日本語版&lt;/span&gt;
npm run profile     &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 英語版（デフォルト）&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;生成物はすべて &lt;code&gt;output/&lt;/code&gt; ディレクトリに出力されます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意:&lt;/strong&gt; 生成物にはプロジェクト固有の情報は仕組み上含まれませんが、&lt;code&gt;output/profile.md&lt;/code&gt; に機密情報が出力されていないことを公開前にご確認ください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. README に埋め込む&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-text-md notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&amp;lt;&lt;span class="pl-ent"&gt;picture&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="pl-ent"&gt;source&lt;/span&gt; &lt;span class="pl-e"&gt;media&lt;/span&gt;=&lt;span class="pl-s"&gt;"&lt;/span&gt;&lt;span class="pl-s"&gt;(prefers-color-scheme: dark)&lt;/span&gt;&lt;span class="pl-s"&gt;"&lt;/span&gt; &lt;span class="pl-e"&gt;srcset&lt;/span&gt;=&lt;span class="pl-s"&gt;"&lt;/span&gt;&lt;span class="pl-s"&gt;https://raw.githubusercontent.com/suruseas/ai-fluency/main/output/card-dark.svg&lt;/span&gt;&lt;span class="pl-s"&gt;"&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="pl-ent"&gt;img&lt;/span&gt; &lt;span class="pl-e"&gt;src&lt;/span&gt;=&lt;span class="pl-s"&gt;"&lt;/span&gt;&lt;span class="pl-s"&gt;https://raw.githubusercontent.com/suruseas/ai-fluency/main/output/card-light.svg&lt;/span&gt;&lt;span class="pl-s"&gt;"&lt;/span&gt; &lt;span class="pl-e"&gt;alt&lt;/span&gt;=&lt;span class="pl-s"&gt;"&lt;/span&gt;&lt;span class="pl-s"&gt;AI Fluency&lt;/span&gt;&lt;span class="pl-s"&gt;"&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span class="pl-ent"&gt;picture&lt;/span&gt;&amp;gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;スコアについて&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;スコアの一部（定性評価）は AI がセッション内容を読み取って判定しています。そのため以下の点にご注意ください。&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;再現性はありません&lt;/strong&gt; — 同じデータでも実行ごとにスコアが多少変動します&lt;/li&gt;

&lt;li&gt;…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/suruseas/ai-fluency" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>devtools</category>
    </item>
    <item>
      <title>I Deleted 66% of My AI Coding Guide — Here's What Survived</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Wed, 18 Mar 2026 11:14:57 +0000</pubDate>
      <link>https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6</link>
      <guid>https://dev.to/suruseas/i-deleted-66-of-my-ai-coding-guide-heres-what-survived-55i6</guid>
      <description>&lt;p&gt;I started with 252 lines of AI coding principles. After four rounds of review, 86 lines survived. But first — a question.&lt;/p&gt;

&lt;p&gt;Is your team measuring AI coding productivity by any of these?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lines of code generated&lt;/li&gt;
&lt;li&gt;Number of prompts per session&lt;/li&gt;
&lt;li&gt;Response speed&lt;/li&gt;
&lt;li&gt;Commit count&lt;/li&gt;
&lt;li&gt;Number of AI tools adopted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If so, you might be optimizing for the wrong things. Lines-of-code targets reward bloat. Prompt-count targets punish thinking. Speed targets skip verification. When these metrics become goals, quality pays the price.&lt;/p&gt;

&lt;p&gt;I wrote an 86-line document called &lt;strong&gt;The AI Coding Way&lt;/strong&gt; that explains why — and what to measure instead. It tries to capture what stays true about human-AI coding collaboration, regardless of which tool or model you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Three principles&lt;/strong&gt;, in order of priority:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep things reversible&lt;/strong&gt; (prerequisite) — Linters, tests, CI, version control. Safety enables boldness. You can't ask AI to refactor a module if you can't undo it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make your intent explicit&lt;/strong&gt; (starting point) — Every context you give AI has three elements: purpose, constraints, and knowledge. Missing any one of them degrades output quality. Project-level intent (types, tests, naming conventions) compounds across every session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify the output&lt;/strong&gt; (non-negotiable) — The bottleneck has shifted from generation to verification. Code that was generated fast should be reviewed slow. The most expensive decision in AI coding: "it works, ship it."&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;One practice section&lt;/strong&gt; covering the collaboration cycle (instruct → generate → verify → improve) and two habits: ask questions instead of giving instructions, and turn repeated instructions into project-level conventions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One measurement section&lt;/strong&gt; listing six metrics that are tempting to track but dangerous if used as goals: lines generated, prompt count, response speed, commit count, session count, tool count. These aren't useless — but optimizing for them alone leads you away from what matters. Measure density instead: acceptance rate, rework frequency, final code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's not in it
&lt;/h2&gt;

&lt;p&gt;No tool names. No model names. No programming languages. No prompt templates. No opinions on whether AI is your boss, your colleague, your subordinate, or your tool — that's your call. The three principles apply regardless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I wrote it
&lt;/h2&gt;

&lt;p&gt;There are plenty of AI coding guides out there. Anthropic, OpenAI, and countless blog posts tell you how to write better prompts. But most of them have a shelf life of about six months — the next model update makes half the advice obsolete.&lt;/p&gt;

&lt;p&gt;I wanted something different: a set of principles that hold true even as models get smarter, context windows get larger, and tools come and go.&lt;/p&gt;

&lt;p&gt;So I set a rule: &lt;strong&gt;don't write anything that a better model would invalidate.&lt;/strong&gt; "AI hallucinates" is a current fact, not a lasting principle. "AI output is probabilistic" is a lasting principle. "Context windows are small" will age poorly. "Humans are responsible for verifying output" won't.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I wrote it
&lt;/h2&gt;

&lt;p&gt;This document is itself a product of AI coding. AI agents debated the structure. AI generated the text. I made every decision on what to keep, what to cut, and how to frame it — exactly the cycle the document describes.&lt;/p&gt;

&lt;p&gt;It started at 252 lines. Four AI agents reviewed it. One of them said: &lt;em&gt;"A blog post would have been enough."&lt;/em&gt; That forced me to ask what actually survives if you strip everything away. For example, a full section called "AI's Amplification Effect" was cut as a standalone section — but its core insight ("AI amplifies both good and bad design") survived as two lines in the principles preamble. That's the kind of compression that happened across the board. The answer was 86 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The full document
&lt;/h2&gt;

&lt;p&gt;Here it is — the entire thing. 86 lines.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AI Coding Way
&lt;/h2&gt;

&lt;p&gt;Principles for AI Coding — v0.1, March 2026&lt;/p&gt;

&lt;p&gt;If you write code with AI and want to get better at it, these principles are for you. Being a good engineer is the best AI strategy.&lt;/p&gt;

&lt;p&gt;This document is meant to live in your project repository — not read once and forgotten, but referenced daily as shared understanding across your team. It will be revised based on real-world feedback.&lt;/p&gt;




&lt;h3&gt;
  
  
  Three Principles
&lt;/h3&gt;

&lt;p&gt;AI output is probabilistic. The same instruction can produce different code. AI has knowledge gaps and states incorrect things with confidence. And AI amplifies — good intent produces good code at scale; sloppy instructions produce plausible but fragile code at scale. Given these properties, humans bear three responsibilities: intent, context, and verification.&lt;/p&gt;

&lt;p&gt;These three principles are non-negotiable requirements for AI coding. The numbers indicate the order you should address them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Keep things reversible (prerequisite)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The foundation for everything else. Without this, nothing is safe to try.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prevention:&lt;/em&gt; Type checking, linters, test suites, CI. If AI-generated code doesn't meet the bar, it gets rejected automatically. The stronger your prevention, the bolder you can delegate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recovery:&lt;/em&gt; Version control, branching strategies, snapshots. The last line of defense when prevention fails.&lt;/p&gt;

&lt;p&gt;Safety mechanisms are not constraints. They are the foundation that enables bold delegation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Make your intent explicit (starting point)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generating and verifying without clear intent is running without a map.&lt;/p&gt;

&lt;p&gt;Context has three elements: &lt;strong&gt;purpose&lt;/strong&gt; (what you want to achieve), &lt;strong&gt;constraints&lt;/strong&gt; (what must not happen), and &lt;strong&gt;knowledge&lt;/strong&gt; (background information needed for decisions). Without purpose, AI wanders. Without constraints, you get unwanted output. Without knowledge, AI guesses.&lt;/p&gt;

&lt;p&gt;Intent operates at two levels. At the &lt;em&gt;task level&lt;/em&gt;, you communicate purpose, constraints, and knowledge in your instructions. At the &lt;em&gt;project level&lt;/em&gt;, type definitions, tests, naming conventions, and directory structure express intent — set these up once and they improve every session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Verify the output (non-negotiable)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bottleneck has shifted from generation to verification. Generation takes seconds. Verification takes human time. That's why the quality of your verification determines the quality of your outcomes.&lt;/p&gt;

&lt;p&gt;The faster code was generated, the more carefully you should read it.&lt;/p&gt;

&lt;p&gt;A common failure: AI generates 200 lines that appear to work. Tests pass. But half is unnecessary abstraction from trying to be too clean, and the rest silently swallows errors and breaks on edge cases. "It works, merge it" is the most expensive decision in AI coding.&lt;/p&gt;




&lt;h3&gt;
  
  
  Practice
&lt;/h3&gt;

&lt;p&gt;AI coding follows this cycle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Communicate&lt;/strong&gt; — Pass purpose, constraints, and necessary knowledge to AI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate&lt;/strong&gt; — AI produces code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; — Human judges the output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve&lt;/strong&gt; — Revise instructions and context based on results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Skipping step 4 and jumping back to step 1 is the primary cause of spinning your wheels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask questions, not just instructions.&lt;/strong&gt; "Is there a problem with this design?" draws out more of AI's capability than "Write this function." When AI offers suggestions, dismissing them as "not what I asked for" is a missed opportunity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're writing the same instructions every time, turn them into conventions.&lt;/strong&gt; Put them in a rules file. Automate with hooks. What you systematize compounds across every future session.&lt;/p&gt;




&lt;h3&gt;
  
  
  What to Measure
&lt;/h3&gt;

&lt;p&gt;The only measure of progress is working software.&lt;/p&gt;

&lt;p&gt;The following metrics are tempting to track but dangerous when used as goals. They aren't useless as signals — but optimizing for them leads you away from what matters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lines generated.&lt;/strong&gt; Measuring quantity incentivizes quantity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt count.&lt;/strong&gt; Many exchanges signal low instruction quality, not productivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response speed.&lt;/strong&gt; Penalizes people who think before they instruct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit count.&lt;/strong&gt; Split commits and the number goes up. Measuring quantity invites inflation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session count.&lt;/strong&gt; More isn't better. Context loss from session breaks can reduce efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Number of tools used.&lt;/strong&gt; Using a tool and mastering a tool are different things.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common problem: measuring quantity and speed incentivizes quantity and speed at the expense of quality.&lt;/p&gt;

&lt;p&gt;Measure density instead. Acceptance rate. Rework frequency. Final code quality.&lt;/p&gt;




&lt;p&gt;This document is a product of AI coding. AI agents debated, AI generated text, and a human made the decisions, verified the output, and revised it.&lt;/p&gt;

&lt;p&gt;Whether you see AI as a subordinate, a collaborator, a supervisor, or a tool is up to you. The three principles apply regardless of what you expect from AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  v0.1
&lt;/h2&gt;

&lt;p&gt;This is v0.1, not a finished product. If you have feedback, I want to hear it. The only way this earns the right to be called a "guide" someday is through revision.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>When AI Joins Your Team, Where Should You Focus Your Resources?</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Thu, 12 Mar 2026 12:42:44 +0000</pubDate>
      <link>https://dev.to/suruseas/when-ai-joins-your-team-where-should-you-focus-your-resources-3p23</link>
      <guid>https://dev.to/suruseas/when-ai-joins-your-team-where-should-you-focus-your-resources-3p23</guid>
      <description>&lt;p&gt;I stopped thinking of AI as a tool.&lt;/p&gt;

&lt;p&gt;Copilot, Cursor, Claude Code — once I started treating these not as "convenient assistants" but as "talented teammates," the way I develop software changed entirely.&lt;/p&gt;

&lt;p&gt;And from that perspective, a simple question emerges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If an exceptional coder and an exceptional reviewer were already on your team, where should the team focus its resources?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Don't Treat AI as Special — Just as an Exceptionally Talented Human
&lt;/h2&gt;

&lt;p&gt;First, an important premise.&lt;/p&gt;

&lt;p&gt;AI is not special. Treat it the same as a highly skilled human engineer.&lt;/p&gt;

&lt;p&gt;AI can already write code, open pull requests, and leave review comments. The range of what it can do is expanding rapidly, and the justification for treating it differently "because it's AI" is fading. Think of it simply as having an exceptionally talented human engineer join the team.&lt;/p&gt;

&lt;p&gt;With that premise in place, the opening question takes on meaning.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Answer Is: Focus on Review
&lt;/h2&gt;

&lt;p&gt;The conclusion first.&lt;/p&gt;

&lt;p&gt;The team should focus on the review side — the process of questioning answers.&lt;/p&gt;

&lt;p&gt;The reason is simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generation (opening PRs) — let AI go all out.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Writing code is the process of "producing an answer given a set of requirements." This is where AI excels, and there's little reason for humans to run alongside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review (questioning answers) — requires a perspective outside the generation context.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the core insight. As long as you remain inside the same context in which the code was generated, you cannot question it from the outside. Conversely, even the same model can function as a reviewer if it operates in a fresh session, disconnected from the generation context. Being outside the context is precisely what makes it possible to question the answer. &lt;a href="https://claude.com/blog/code-review" rel="noopener noreferrer"&gt;Anthropic's Code Review&lt;/a&gt;, discussed later, is built on this same principle. Whether AI or human — "being outside the generation context" is the condition for effective review.&lt;/p&gt;

&lt;p&gt;"Does this code work?" is not the question. "Was this the right implementation?" "Is this tradeoff really justified?" — raising these questions requires a perspective that differs from the one that produced the code. Focusing resources on review is what makes these questions possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Maybe Not a Coincidence — What Anthropic Is Doing
&lt;/h2&gt;

&lt;p&gt;On March 9, 2026, Anthropic released Code Review for Claude Code.&lt;/p&gt;

&lt;p&gt;The feature automatically dispatches multiple AI agents in parallel whenever a PR is opened, detects bugs, ranks them by severity, and feeds the results back into GitHub. Anthropic applies this system to nearly every PR internally, and the proportion of PRs receiving substantive review comments &lt;a href="https://claude.com/blog/code-review" rel="noopener noreferrer"&gt;jumped from 16% to 54%&lt;/a&gt; as a result.&lt;/p&gt;

&lt;p&gt;What's worth noting is the design philosophy. It has been &lt;a href="https://techcrunch.com/2026/03/09/anthropic-launches-code-review-tool-to-check-flood-of-ai-generated-code/" rel="noopener noreferrer"&gt;reported&lt;/a&gt; that the tool &lt;strong&gt;focuses on logic errors&lt;/strong&gt;, not style or naming conventions. Could this reflect a deliberate choice to leave style correction to the generation side?&lt;/p&gt;

&lt;p&gt;This might be an embodiment of the idea: "rather than loading the generation side with detailed instructions, tighten the exit gate (review)."&lt;/p&gt;




&lt;h2&gt;
  
  
  Overloading CLAUDE.md Backfires
&lt;/h2&gt;

&lt;p&gt;Meanwhile, research is emerging that questions the approach of controlling generation through detailed instructions.&lt;/p&gt;

&lt;p&gt;A paper published on arXiv in February 2026, "Evaluating AGENTS.md" (ETH Zurich et al.), found that loading context files like CLAUDE.md or AGENTS.md with detailed instructions &lt;a href="https://arxiv.org/abs/2602.11988" rel="noopener noreferrer"&gt;&lt;strong&gt;reduces task success rates and increases inference costs by more than 20%&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AI tries to follow instructions, but in doing so generates unnecessary exploration and testing that gets in the way of the actual task. The paper's conclusion is simple: "Unnecessary requirements make tasks harder. Context files should contain only minimal requirements."&lt;/p&gt;

&lt;p&gt;Keeping instructions minimal — this direction may be empirically supported as well.&lt;/p&gt;




&lt;h2&gt;
  
  
  Skills Fall Into the Same Trap as CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;Agent Skills has been gaining attention recently. It's an open format for giving agents procedural knowledge via SKILL.md files, enabling capability expansion.&lt;/p&gt;

&lt;p&gt;There are valid uses. Tasks like generating PPTX files or operating internal proprietary tools — adding capabilities that agents don't have out of the box. In that sense, it differs from CLAUDE.md.&lt;/p&gt;

&lt;p&gt;But misused, it falls into exactly the same trap.&lt;/p&gt;

&lt;p&gt;Consider writing a rule like "always include the time, not just the date, in Rails migration filenames" as a Skill. This is just injecting a corrective instruction as a workaround for unstable output — structurally no different from writing it in CLAUDE.md.&lt;/p&gt;

&lt;p&gt;A practical rule of thumb: &lt;strong&gt;if it can be replaced by a linter or automation tool, it shouldn't be a Skill.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill type&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cannot be replaced by linters etc. (capability expansion)&lt;/td&gt;
&lt;td&gt;Valid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can be replaced by linters etc. (rule correction)&lt;/td&gt;
&lt;td&gt;Same trap as CLAUDE.md&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When you find yourself wanting to create a Skill to enforce a rule, first ask whether a linter or automation tool could handle it instead. If it can, it belongs at the exit gate — not injected into the generation side.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scale Benefits Belong on the Review Side
&lt;/h2&gt;

&lt;p&gt;AI scales. That's true for generation too — but I believe scale truly pays off on the review side.&lt;/p&gt;

&lt;p&gt;On the generation side, there's a "lottery approach": keep asking AI to regenerate until you get a good result. More attempts eventually yield better output.&lt;/p&gt;

&lt;p&gt;That said, I personally accept about 90% of AI output as-is. I think it's because I use AI as a collaborative partner rather than giving it detailed instructions. If generation quality is already high enough, there's no need to rely on the lottery approach. If you're going to invest scale somewhere, review is the more rational choice.&lt;/p&gt;

&lt;p&gt;What happens when you invest scale in review? Multiple AIs independently question the same PR. Each raises questions from different angles, catching what others miss. Anyone who has worked in code review knows the feeling of "I want as many eyes on this as possible" — review works the same way. The more reviewers, the lower the probability of something slipping through.&lt;/p&gt;

&lt;p&gt;Anthropic itself has &lt;a href="https://claude.com/blog/code-review" rel="noopener noreferrer"&gt;adopted a design for Code Review that runs multiple agents in parallel, then cross-checks to filter out false positives&lt;/a&gt;. Could this also be seen as an embodiment of the idea that scale belongs on the review side?&lt;/p&gt;

&lt;p&gt;The lottery approach in generation just accumulates cost. Scale in review has intrinsic value: it reduces what gets missed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Human Eyes Still Have Unique Value
&lt;/h2&gt;

&lt;p&gt;Does this mean humans are unnecessary if AI handles review? I don't think so.&lt;/p&gt;

&lt;p&gt;Business judgment, implicit team context, "this is technically correct but is it acceptable for our organization?" — these are areas where humans currently have an edge over AI. That's why there's still good reason for humans to actively invest time in review.&lt;/p&gt;

&lt;p&gt;Scale AI in review, and have humans actively invest in review too. Increasing both kinds of "eyes" raises the quality of the team's answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Who does it&lt;/th&gt;
&lt;th&gt;What scale means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generation (opening PRs)&lt;/td&gt;
&lt;td&gt;Let AI go all out&lt;/td&gt;
&lt;td&gt;More output, but no gain in quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review (questioning answers)&lt;/td&gt;
&lt;td&gt;Invest both AI and humans&lt;/td&gt;
&lt;td&gt;Quality improves&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When AI joins the team, the team's job is not to "beat AI at generation." It's to question the answers AI produces — together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Behind Anthropic's release of Code Review lies a real problem: AI is generating so much code that review has become a bottleneck. &lt;a href="https://claude.com/blog/code-review" rel="noopener noreferrer"&gt;Code output per engineer at Anthropic has grown 200% over the past year&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This trend won't stop. Generation will keep increasing, and the importance of review will only grow.&lt;/p&gt;

&lt;p&gt;If you truly trust AI as a teammate, let them go all out producing answers. And as a team, concentrate your resources on questioning those answers.&lt;/p&gt;

&lt;p&gt;Concretely: adopting tools like Code Review, enforcing style conventions with linters and automation, and making sure humans have time for review — these three are a good place to start.&lt;/p&gt;

&lt;p&gt;That's my conclusion for now.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://claude.com/blog/code-review" rel="noopener noreferrer"&gt;Code Review for Claude Code (Anthropic, 2026/03/09)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2602.11988" rel="noopener noreferrer"&gt;Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents? (arXiv:2602.11988)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agentskills.io/home" rel="noopener noreferrer"&gt;Agent Skills&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>📻 I Made Claude Code Instances Talk to Each Other in Real Time</title>
      <dc:creator>yukihiro amadatsu</dc:creator>
      <pubDate>Fri, 27 Feb 2026 17:58:16 +0000</pubDate>
      <link>https://dev.to/suruseas/i-made-claude-code-instances-talk-to-each-other-in-real-time-2kal</link>
      <guid>https://dev.to/suruseas/i-made-claude-code-instances-talk-to-each-other-in-real-time-2kal</guid>
      <description>&lt;p&gt;What if your AI coding assistants could collaborate — not through files or git, but by actually &lt;em&gt;talking&lt;/em&gt; to each other?&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Walkie-Talkie&lt;/strong&gt;, a real-time messaging system that lets multiple Claude Code instances communicate with each other. And now it's available as a plugin you can install in seconds.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/ZQRrYtqT4kg"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Why Would You Want This?
&lt;/h2&gt;

&lt;p&gt;Think of it as &lt;strong&gt;Slack for Claude Code instances&lt;/strong&gt;. Each terminal is a participant in a group chat. Anyone can lead, anyone can follow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents collaborating on code&lt;/strong&gt; — you don't pre-assign roles. Just like messaging a coworker on Slack, you'd say "hey, can you review this?" in the conversation. Roles emerge naturally. And there's no limit on the number of participants.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hands-off or hands-on — your choice.&lt;/strong&gt; Let agents work things out among themselves, or jump in anytime from the dashboard to steer the conversation, give new instructions, or correct course. You're not locked into either mode — you can switch between observer and director mid-conversation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Play a TRPG&lt;/strong&gt; — yes, seriously. Claude Code instances can play Call of Cthulhu with each other. One runs the scenario, the others roleplay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger Claude Code from anywhere, anytime.&lt;/strong&gt; The Hub is just an HTTP server. That means a cron job, a CI pipeline, or any script can send a message to a connected agent — and the agent will execute it. Until now, scheduling Claude Code tasks (like nightly code reviews or periodic cleanups) required the API. With Walkie-Talkie, you can do it with a single &lt;code&gt;curl&lt;/code&gt; command, no API key needed, while the agent maintains its full context window.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The possibilities are endless. Each terminal maintains its own context window, so conversations can go deep. And because this runs entirely through Claude Code's built-in infrastructure — &lt;strong&gt;no separate API calls&lt;/strong&gt; — it works within your existing Pro or Max plan. No extra cost.&lt;/p&gt;

&lt;p&gt;This isn't hypothetical. It works today.&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;Claude Code A ──stdio──&amp;gt; MCP Server ──HTTP──&amp;gt; Hub ──HTTP──&amp;gt; MCP Server ──stdio──&amp;gt; Claude Code B
                                               │
                                          Dashboard
                                        (ON-AIR screen)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system has three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hub&lt;/strong&gt; — A central server that routes messages between agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt; — Connects each Claude Code instance to the Hub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard&lt;/strong&gt; — A browser-based control panel where you can watch conversations, send instructions, and manage agents&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each Claude Code instance joins with a name (like a callsign), then enters an autonomous conversation loop — listening for messages, responding, and listening again. Just like a real walkie-talkie.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎥 See It In Action
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Two Agents Chatting
&lt;/h3&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/OFUtrS0qsRU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;The agents don't just reply once — they keep the conversation going autonomously. No human intervention needed. They listen, they talk back, they keep listening.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dashboard
&lt;/h3&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/nq08mf2hk_s"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;The ON-AIR dashboard gives you a bird's-eye view of everything happening. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watch all messages in real time&lt;/li&gt;
&lt;li&gt;Send instructions to any agent as the &lt;strong&gt;operator&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Kick individual agents or stop everyone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you send an instruction as operator, the agent actually &lt;em&gt;executes&lt;/em&gt; it — runs commands, reads files, writes code — then reports back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operator Mode: Distributing Tasks
&lt;/h3&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/-wfJGPiOMFw"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Tell one agent to write FizzBuzz in Ruby, then ask another to review it. They'll discuss, refactor, and improve the code — just like real teammates on Slack. You kicked it off, but they take it from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;p&gt;Walkie-Talkie is a Claude Code plugin. No manual MCP configuration needed.&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;# 1. Clone and build the Hub&lt;/span&gt;
git clone https://github.com/suruseas/walkie-talkie.git
&lt;span class="nb"&gt;cd &lt;/span&gt;walkie-talkie
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build

&lt;span class="c"&gt;# 2. Set the Join token (add this to your ~/.zshrc)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WALKIE_TALKIE_JOIN_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-secret-value-here
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc

&lt;span class="c"&gt;# 3. Start the Hub&lt;/span&gt;
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 4. In Claude Code, install the plugin
/plugin marketplace add suruseas/walkie-talkie
/plugin install walkie-talkie@suruseas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Code, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/walkie-talkie alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open another Claude Code session, join as a different name, and they'll start chatting. See the &lt;a href="https://github.com/suruseas/walkie-talkie" rel="noopener noreferrer"&gt;README&lt;/a&gt; for full setup details.&lt;/p&gt;

&lt;p&gt;To stop agents, click "Stop All" on the ON-AIR dashboard, or press &lt;code&gt;Escape&lt;/code&gt; (&lt;code&gt;Ctrl+C&lt;/code&gt;) in the individual terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 The Technical Bits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Autonomous Conversation Loop
&lt;/h3&gt;

&lt;p&gt;The magic is in the SKILL.md file that drives agent behavior. It instructs Claude Code to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Join the hub&lt;/li&gt;
&lt;li&gt;Wait for messages (long poll)&lt;/li&gt;
&lt;li&gt;Reply immediately&lt;/li&gt;
&lt;li&gt;Go back to waiting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never ask the user what to do&lt;/strong&gt; — just keep the loop going&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This creates truly autonomous agents that maintain conversations without human intervention.&lt;/p&gt;

&lt;p&gt;There's another crucial behavior in the SKILL.md: &lt;strong&gt;when an agent receives a message from &lt;code&gt;operator&lt;/code&gt;, it treats it as a task and executes it using Claude Code's full toolset&lt;/strong&gt; — Bash, file read/write, everything. This is what makes the dashboard so powerful, but also what makes this system dangerous — it can run commands on your computer. Any message from the operator is treated as an instruction to execute, not just a chat message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long Polling for Real-Time Feel
&lt;/h3&gt;

&lt;p&gt;Instead of WebSockets, I used HTTP long polling. The MCP server holds a connection open for up to an hour, waiting for messages. This gives a real-time feel while staying compatible with Claude Code's MCP stdio transport.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Important Safety Warning
&lt;/h2&gt;

&lt;p&gt;I need to be very clear about this: &lt;strong&gt;Walkie-Talkie is powerful, and power demands caution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NEVER expose the Hub server to the internet.&lt;/strong&gt; The Hub should only run on &lt;code&gt;localhost&lt;/code&gt;. If you make it accessible from outside your machine, anyone who discovers it could connect agents to your Hub and potentially execute commands on your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is not a theoretical risk.&lt;/strong&gt; The SKILL.md explicitly instructs agents to execute operator messages as tasks using Claude Code's full toolset — Bash commands, file operations, anything. If a malicious actor gains access to your Hub, they can run arbitrary commands on every connected agent's machine. This is by design for local use, but catastrophic if exposed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are fully responsible for how you use this tool.&lt;/strong&gt; I built this as an experiment and share it as-is. I cannot and do not take responsibility for any damage, data loss, or security incidents that may result from using Walkie-Talkie. By using it, you accept this risk.&lt;/p&gt;

&lt;p&gt;Some ground rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run the Hub on localhost only&lt;/strong&gt; — never bind it to &lt;code&gt;0.0.0.0&lt;/code&gt; or expose it through a reverse proxy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep your Join token secret&lt;/strong&gt; — anyone with the token can connect agents to your Hub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't leave agents running unattended&lt;/strong&gt; — autonomous agents with tool access can do unexpected things&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the code yourself&lt;/strong&gt; — this is open source for a reason. Understand what you're running.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that said — if you use it responsibly on your local machine, it's an incredibly fun and useful tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Try It
&lt;/h2&gt;

&lt;p&gt;The project is open source: &lt;a href="https://github.com/suruseas/walkie-talkie" rel="noopener noreferrer"&gt;github.com/suruseas/walkie-talkie&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install the plugin and let your Claude Code instances start talking. I'd love to hear what workflows you come up with.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have questions or ideas? Reach out on GitHub or DEV — but I'm running a full marathon on March 1st (JST), so responses may be slow around that time. If I go silent for too long... something may have happened out there on the course. 🏃&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>plugin</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
