<?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: Hiroki Kondo</title>
    <description>The latest articles on DEV Community by Hiroki Kondo (@kompiro).</description>
    <link>https://dev.to/kompiro</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%2F42410%2F93108716-16bb-4991-b656-79df07d9c7a9.jpg</url>
      <title>DEV Community: Hiroki Kondo</title>
      <link>https://dev.to/kompiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kompiro"/>
    <language>en</language>
    <item>
      <title>From requests to mechanisms: a week of risk-tiered review and a gh wrapper for agent PRs (karasu weekly)</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Sun, 01 Nov 2026 00:13:52 +0000</pubDate>
      <link>https://dev.to/kompiro/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for-agent-prs-karasu-36d0</link>
      <guid>https://dev.to/kompiro/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for-agent-prs-karasu-36d0</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt; is a text modeling language for system architecture, inspired by the C4 model.&lt;br&gt;
You describe your system in &lt;code&gt;.krs&lt;/code&gt; files and karasu draws the views: system, deployment, and team structure.&lt;br&gt;
I haven't written its code by hand; everything goes through Claude Code.&lt;/p&gt;

&lt;p&gt;This is the fourth weekly update.&lt;br&gt;
It covers changes merged from October 25 to 31.&lt;br&gt;
This time I start with what I learned building with agents, then go through what shipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This week in numbers:&lt;/strong&gt; 70 PRs merged (12 of them Dependabot) and 18 decisions recorded as ADRs.&lt;br&gt;
15 of the ADRs came in ADR-only PRs, and 3 were added inside implementation PRs.&lt;br&gt;
On October 25 the monthly release train left for the first time, shipping karasu 0.10.0 and the Visual Studio Code extension 0.5.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons from building with agents this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Risk tiers that set how deep a review goes are now running.&lt;/strong&gt;&lt;br&gt;
Last week I wrote that the design was merged and the implementation was still to come; it landed on October 27.&lt;br&gt;
Each PR falls into one of four tiers by the paths it touches.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High:&lt;/strong&gt; changes to the review machinery itself, CI, lockfiles, and the like. CodeRabbit reviews until no Critical or Major findings remain, and I read the diff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design:&lt;/strong&gt; design documents. CodeRabbit reviews once when the PR leaves draft, and I read it too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; no CodeRabbit. I decide from the local review record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low:&lt;/strong&gt; adding an ADR, or only adding tests. If the local review record and CI pass, I merge without reading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tier except High puts a local review record in the PR body.&lt;br&gt;
It's a table of who reviewed and, for each finding, whether it was fixed or declined.&lt;br&gt;
A required check confirms the record is for the PR's latest commit.&lt;/p&gt;

&lt;p&gt;This week 76 PRs were closed and 70 of them merged (a 92% merge rate).&lt;br&gt;
Of the 50 merged with a tier label, 18 were High, 10 Design, 12 Medium, and 10 Low.&lt;br&gt;
I merged the 10 Low PRs without reading the diff, so the auto-merge rate is 20%.&lt;br&gt;
9 of the 10 were ADR PRs, and the other was the monthly review of test perspectives.&lt;br&gt;
9 were merged within 3 minutes of leaving draft.&lt;br&gt;
The 22 Medium and Low PRs were merged without going through CodeRabbit.&lt;/p&gt;

&lt;p&gt;High is common because much of this week's work touched the review and process machinery itself.&lt;br&gt;
Changes to that machinery are set to land in High.&lt;br&gt;
It'll take a few more weeks of counting to see how the tiers split in everyday development.&lt;/p&gt;

&lt;p&gt;While counting, I found 4 High PRs that CodeRabbit never reviewed.&lt;br&gt;
I haven't checked yet whether they slipped through or were left out for a reason.&lt;br&gt;
I'll look into it before the next update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over the past week I came across several talks and posts on not reading code&lt;/strong&gt; (all in Japanese).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minodriven's talk &lt;a href="https://speakerdeck.com/minodriven/abstraction-design-and-quality" rel="noopener noreferrer"&gt;"Should we read AI-generated code? Abstraction design and code quality assurance"&lt;/a&gt; says it isn't the case that you never need to read code at all. It then argues that design by contract, isolating side effects, and abstraction reduce the need to read. It rephrases being able to use something without caring about its insides as "trusting" it.&lt;/li&gt;
&lt;li&gt;Yosuke Furukawa's talk &lt;a href="https://speakerdeck.com/yosuke_furukawa/ai-ga-kodo-o-kai-te-kureru-jidai-wareware-ha-nani-o-tashikameru-no-ka" rel="noopener noreferrer"&gt;"In an age when AI writes our code, what do we verify?"&lt;/a&gt; says it isn't a binary of reading or not reading. People decide what the criteria are, and checking whether they're met can be left to AI.&lt;/li&gt;
&lt;li&gt;nrs's &lt;a href="https://zenn.dev/nrs/articles/c777388530aa84" rel="noopener noreferrer"&gt;post on Zenn&lt;/a&gt; gives two preconditions for a "no look merge," merging a PR without a person reading the code: quality checks good enough to stand in for human review, and agreement within the organization.&lt;/li&gt;
&lt;li&gt;Yohei Watanabe's &lt;a href="https://gihyo.jp/article/2026/10/agentic-coding-and-harness-engineering" rel="noopener noreferrer"&gt;"Agentic Coding and harness engineering"&lt;/a&gt; puts the key point in deciding what stays a "request" and what moves to a mechanical check.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I never kept reading all the code of the systems I build at work.&lt;br&gt;
Even in reviews, I don't read much of the surrounding code.&lt;br&gt;
Since I started using AI, I have it check the surrounding situation while I read the parts that concern me in depth.&lt;br&gt;
The parts that don't concern me, I now skim.&lt;br&gt;
I think I can do that because I trust AI about as much as a capable contractor.&lt;/p&gt;

&lt;p&gt;The trust I mean is close to Minodriven's "using it without caring about its insides."&lt;br&gt;
But what I want to get right is less the code itself than the ground the code is written on.&lt;br&gt;
Even a capable contractor, not knowing the team's agreements and not following its steps, writes code full of places that concern me.&lt;br&gt;
Agents are the same.&lt;br&gt;
If the material to work without hesitation arrives before writing starts, and the steps are followed while writing, I should be able to read less.&lt;br&gt;
In karasu, I set up those two like this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before writing: leave the agent less room to get lost.&lt;/strong&gt;&lt;br&gt;
In karasu, a large change merges a design document first and is implemented after.&lt;br&gt;
This week's risk tiers (#3358 → #3365) and the &lt;code&gt;docs/process.md&lt;/code&gt; split described in this section (#3394 → #3402) both went in that order.&lt;br&gt;
Past decisions are recorded as ADRs, and a step to check them before designing is in the skills.&lt;/p&gt;

&lt;p&gt;On top of that, I cut down how much has to be read.&lt;br&gt;
&lt;code&gt;docs/process.md&lt;/code&gt; is the development guide every session reads in full first.&lt;br&gt;
It had grown to 46 KB.&lt;br&gt;
When all of it is read every time, the step needed right now gets buried in the others.&lt;br&gt;
So I kept only the flow that's always needed, at 14,876 bytes, and moved the rest into topic files under &lt;code&gt;docs/process/&lt;/code&gt;.&lt;br&gt;
The guide has an index that says when to read each file.&lt;br&gt;
For example, the review tiers and how to write the record are read in the step just before a PR leaves draft.&lt;br&gt;
I measured how far this read-it-when-needed approach (Progressive Disclosure) reaches current models in &lt;a href="https://fukurou.kompiro.dev/en/progressive-disclosure/" rel="noopener noreferrer"&gt;a September post&lt;/a&gt;.&lt;br&gt;
Then, path-scoped rules that load when a file is opened almost never fired, while steps written into skills got through.&lt;br&gt;
This split doesn't rely on loading on file open either.&lt;br&gt;
The always-read guide names which file to read at which step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;While writing: move "requests" into mechanisms.&lt;/strong&gt;&lt;br&gt;
I had shrunk &lt;code&gt;docs/process.md&lt;/code&gt; to 12.7 KB once before.&lt;br&gt;
It had grown back to 46 KB.&lt;br&gt;
Tidying by hand was undone as steps were added.&lt;br&gt;
This time I added &lt;code&gt;pnpm lint:process-index&lt;/code&gt;, which checks the index-to-file mapping, the links, and the guide's size in lefthook and CI.&lt;/p&gt;

&lt;p&gt;Last week I wrote that a check refusing &lt;code&gt;gh pr ready&lt;/code&gt; before the local review was in a PR. That's merged too.&lt;br&gt;
The first version was a Claude Code hook that inspected the text of the command about to run.&lt;br&gt;
But each CodeRabbit review found another way around it: &lt;code&gt;gh&lt;/code&gt; after a heredoc, &lt;code&gt;gh&lt;/code&gt; behind &lt;code&gt;env -u&lt;/code&gt; or &lt;code&gt;timeout -s&lt;/code&gt;, &lt;code&gt;gh&lt;/code&gt; through &lt;code&gt;eval&lt;/code&gt; or &lt;code&gt;xargs&lt;/code&gt;.&lt;br&gt;
The command text can't tell you what will finally run.&lt;br&gt;
After 20 CodeRabbit reviews, it was rebuilt as a &lt;code&gt;gh&lt;/code&gt; wrapper placed first on the session's PATH, deciding from the arguments &lt;code&gt;gh&lt;/code&gt; actually receives.&lt;/p&gt;

&lt;p&gt;What wasn't followed when it was written in the guide, I'm moving into lint, the &lt;code&gt;gh&lt;/code&gt; wrapper, and required checks.&lt;br&gt;
That's Watanabe's move from "request" to mechanical check.&lt;/p&gt;

&lt;p&gt;Low's auto-merge sits on top of these two.&lt;br&gt;
I'll keep counting the merge rate and the auto-merge rate in the coming weeks.&lt;br&gt;
I also plan to track whether bugs later turn up in PRs merged without reading.&lt;br&gt;
I'll write about "ground that lets me read less" in a separate post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fold a video into one image, and the agent can check it
&lt;/h2&gt;

&lt;p&gt;The two demo videos in last week's update were recorded by an agent.&lt;br&gt;
This week added the skill behind them (&lt;code&gt;demo-video&lt;/code&gt;) and &lt;code&gt;pnpm demo-video:record &amp;lt;scenario&amp;gt; --lang en|ja&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the real karasu app (through &lt;code&gt;karasu serve&lt;/code&gt;), or Visual Studio Code with the extension, on an Xvfb virtual display.&lt;/li&gt;
&lt;li&gt;The scenario moves the pointer, clicks, and types into the editor, while ffmpeg records the whole screen.&lt;/li&gt;
&lt;li&gt;Join title cards at the start and end, lay a caption over each scene, and write a 1920×1080 MP4.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Captions and title cards are kept per language, so one scenario produces both an English and a Japanese video.&lt;br&gt;
Visual Studio Code is driven over CDP (Chrome DevTools Protocol).&lt;br&gt;
ExTester, a UI testing tool for Visual Studio Code extensions, isn't used, because its ChromeDriver doesn't run in the arm64 devcontainer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once the video is made, the agent looks at it.&lt;/strong&gt;&lt;br&gt;
The agent can open images with Read, but not videos.&lt;br&gt;
So the recording is cut into a frame every 3 seconds and tiled into one image (a contact sheet), which the agent opens with Read.&lt;br&gt;
The skill's end state says: don't report "done" without having looked at what's in the video.&lt;/p&gt;

&lt;p&gt;Below is last week's &lt;code&gt;serve-import&lt;/code&gt; video (71 seconds), cut every 3 seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw2tterrvf1211xcpbsj3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw2tterrvf1211xcpbsj3.jpg" alt="A contact sheet of last week's serve-import demo video, one frame every 3 seconds: 24 frames in 6 columns and 4 rows, with the cards turning from blue to green partway through" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cards are blue up to the first frame of the second row and green in the second frame.&lt;br&gt;
The code panel at the top right of that same frame shows the diff that changed the colors in &lt;code&gt;theme.krs.style&lt;/code&gt;.&lt;br&gt;
A single frame with the green cards only tells you the cards are green.&lt;br&gt;
Laid side by side, the frames show the change: the style sheet was saved and the view was redrawn.&lt;br&gt;
The caption text, and the flow from the Share dialog to the public app opening, can also be read from this one image.&lt;/p&gt;

&lt;p&gt;The skill also has a table of pitfalls hit while recording.&lt;br&gt;
It has rows like "a 'Do you want to save your changes?' prompt shows at the end of the video", "right-clicking an edge opens another edge's menu", and "a translation bar appears".&lt;br&gt;
None of these show up in an exit code or a log; they show up only on screen.&lt;br&gt;
The save prompt appears when Visual Studio Code closes.&lt;br&gt;
A screenshot taken just before closing wouldn't catch it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I brought the same practice to fukurou.&lt;/strong&gt;&lt;br&gt;
In the repository where I write this update, I added ffmpeg to the devcontainer and rewrote the weekly-update steps.&lt;br&gt;
Until then, the session couldn't see inside the videos, so I checked that the text matched them myself.&lt;br&gt;
Now the session builds the contact sheet, opens it, and checks for itself.&lt;br&gt;
The image above was made with those steps.&lt;br&gt;
Looking back, the only reason it couldn't check before was that ffmpeg wasn't installed.&lt;/p&gt;

&lt;p&gt;I've been writing "the agent looks at the video," but what it actually opens is one still image.&lt;br&gt;
"Looking" here means reading time folded into a single image.&lt;br&gt;
Even so, it can read changes over the course of a video that a single screenshot can't show.&lt;br&gt;
Reading a screen recording of a bug the same way might help reproduce it or guess at the cause.&lt;br&gt;
But I don't yet have a karasu bug that was found or fixed from a video.&lt;br&gt;
The next time a screen-related bug comes in, I'll start by handing the recording to the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship on a schedule, and make sure "unchanged" is decidable before skipping
&lt;/h2&gt;

&lt;p&gt;On October 25 the monthly release train left for the first time.&lt;br&gt;
On the last Sunday of each month, it ships whatever is unreleased.&lt;br&gt;
That morning, a branch with the version bumps and a tracking Issue open automatically.&lt;br&gt;
All I do is open the PR from the Issue's link, read the CHANGELOG, and merge.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;From&lt;/th&gt;
&lt;th&gt;To&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;karasu&lt;/code&gt; (CLI)&lt;/td&gt;
&lt;td&gt;0.9.0&lt;/td&gt;
&lt;td&gt;0.10.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@karasu-tools/core&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.4.0&lt;/td&gt;
&lt;td&gt;0.4.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;karasu-vscode&lt;/code&gt; (Visual Studio Code extension)&lt;/td&gt;
&lt;td&gt;0.4.0&lt;/td&gt;
&lt;td&gt;0.5.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;karasu-skills&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.2.0&lt;/td&gt;
&lt;td&gt;0.2.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It ships 16 pending changesets.&lt;br&gt;
The first train ran without stopping, all the way to npm and the Visual Studio Code Marketplace.&lt;br&gt;
It was the first time the Marketplace publish rode the train.&lt;br&gt;
Both highlights from last week (import resolution in &lt;code&gt;karasu serve&lt;/code&gt;, and the Visual Studio Code preview running the app's viewer) arrived on this train.&lt;br&gt;
The &lt;code&gt;.krs&lt;/code&gt; language is unchanged.&lt;br&gt;
One change in &lt;code&gt;.krs.style&lt;/code&gt;, though: a stray &lt;code&gt;-&lt;/code&gt; or non-ASCII character that isn't part of any name used to be dropped silently.&lt;br&gt;
Now it's an error.&lt;br&gt;
Lines you thought were taking effect but weren't will now show up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Visual Studio Code extension also gets a weekly prerelease.&lt;/strong&gt;&lt;br&gt;
With only a monthly train, a change merged to main can take up to a month to reach the extension.&lt;br&gt;
So every Wednesday the extension is built from the tip of main and published to the Marketplace prerelease channel.&lt;br&gt;
The version carries the date: &lt;code&gt;&amp;lt;stable major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;YYYYMMDDNN&amp;gt;&lt;/code&gt;.&lt;br&gt;
A week whose contents match the previous version is skipped.&lt;/p&gt;

&lt;p&gt;"The contents match" means every file in the &lt;code&gt;.vsix&lt;/code&gt; is the same, except for the version number in &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
I checked beforehand that this can be decided.&lt;br&gt;
I compared the Marketplace 0.5.0 &lt;code&gt;.vsix&lt;/code&gt; with one built locally from the same commit, and every file matched except &lt;code&gt;THIRD_PARTY_NOTICES.md&lt;/code&gt;.&lt;br&gt;
That one file differs only in the platform of a bundled binary (linux-arm64 locally, linux-x64 on CI).&lt;br&gt;
Two CI builds should match.&lt;br&gt;
To use it, switch to the prerelease version on the extension's page in the Extensions view.&lt;br&gt;
The first one is due on Wednesday, November 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other changes this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Edge labels no longer sit on frame borders.&lt;/strong&gt;&lt;br&gt;
Drill-down and group borders are now obstacles for labels.&lt;br&gt;
Across four models and &lt;code&gt;examples/en&lt;/code&gt; (5,061 cases), labels crossed by a border went from 132 to 0, and labels pushed to the far side of a frame went from 57 to 0.&lt;br&gt;
In exchange, labels omitted under &lt;code&gt;auto&lt;/code&gt; went up from 1,745 to 1,784.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edges no longer cut through cards when a route exists.&lt;/strong&gt;&lt;br&gt;
These are edges between cards in the same row.&lt;br&gt;
The cause wasn't the route: all five candidate spots where an edge leaves the card were taken.&lt;br&gt;
As a last resort, it now searches the whole side of the card for a spot.&lt;br&gt;
Edges cutting through a card went from 4 to 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Style diagnostics and rendering agree now.&lt;/strong&gt;&lt;br&gt;
The valid ranges for &lt;code&gt;.krs.style&lt;/code&gt; values were written in three places, and they disagreed.&lt;br&gt;
A diagnostic would say a value was ignored while the value got clamped or drawn anyway.&lt;br&gt;
The ranges now live only in the schema, and a declaration a diagnostic rejects isn't used for rendering either.&lt;br&gt;
So rendering changes too.&lt;br&gt;
An out-of-range &lt;code&gt;label-position&lt;/code&gt; is dropped instead of clamped.&lt;br&gt;
A non-zero length without a unit, a wrong unit, a bad hex color, or a color name with the wrong case (&lt;code&gt;White&lt;/code&gt;) isn't drawn.&lt;br&gt;
An empty value like &lt;code&gt;color: ;&lt;/code&gt; makes &lt;code&gt;karasu render&lt;/code&gt; fail.&lt;br&gt;
This ships on the next train (November 29).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;karasu serve&lt;/code&gt; returned what a symlink pointed to.&lt;/strong&gt;&lt;br&gt;
Say the served directory held a symlink pointing outside it (like &lt;code&gt;notes.krs -&amp;gt; ~/.ssh/id_rsa&lt;/code&gt;).&lt;br&gt;
Then &lt;code&gt;/api/file/:name&lt;/code&gt; returned the contents of the link's target.&lt;br&gt;
This is in the released 0.10.0.&lt;br&gt;
Paths are now resolved to the real file, and nothing outside the served directory is returned.&lt;br&gt;
&lt;code&gt;/api/watch&lt;/code&gt; also stopped sending &lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt;.&lt;br&gt;
The fix ships on the next train.&lt;br&gt;
Until then, it's safer not to run &lt;code&gt;karasu serve&lt;/code&gt; in a directory with symlinks that point outside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smaller changes.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;analyze()&lt;/code&gt; wrote a cycle flag into the model it was given, so the same model rendered differently before and after &lt;code&gt;analyze()&lt;/code&gt;. Cycles are now computed when the model is built, and &lt;code&gt;analyze()&lt;/code&gt; only reads.&lt;br&gt;
Package sources now have a 600-line limit per file. The 33 files over it are pinned at their current length, and the pin goes down as they shrink. Splitting &lt;code&gt;svg-renderer.ts&lt;/code&gt; (2,965 lines), &lt;code&gt;layout.ts&lt;/code&gt; (1,719 lines), and &lt;code&gt;view-extract.ts&lt;/code&gt; (2,042 lines) has started.&lt;br&gt;
GitHub Actions versions are now pinned with &lt;code&gt;actions.lock&lt;/code&gt; (GA on October 28). It also pins actions that workflows use indirectly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The first weekly prerelease of the Visual Studio Code extension is due on Wednesday, November 4.&lt;/li&gt;
&lt;li&gt;A design for drawing two-way edges (&lt;code&gt;A -&amp;gt; B&lt;/code&gt; and &lt;code&gt;B -&amp;gt; A&lt;/code&gt;) as one double-headed arrow is merged. In the prototype, one view of the Umami model went from 41 edges to 27 and from 157 crossings to 61. The implementation PR is in review.&lt;/li&gt;
&lt;li&gt;Work is underway to stop committing files generated from ADRs in each PR, and to regenerate them in a daily scheduled run instead. Parallel ADR PRs almost always conflicted on them.&lt;/li&gt;
&lt;li&gt;A design is in progress to limit &lt;code&gt;karasu serve&lt;/code&gt; to connections from your own machine and to check the &lt;code&gt;Host&lt;/code&gt; header.&lt;/li&gt;
&lt;li&gt;Splitting the three files over 600 lines has more steps to go.&lt;/li&gt;
&lt;/ul&gt;




&lt;ul&gt;
&lt;li&gt;Site: &lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu.kompiro.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;github.com/kompiro/karasu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>coderabbit</category>
      <category>claudecode</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Rate limits, skipped steps, and hooks: what tuning AI code review for agent PRs taught me (karasu weekly)</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Sun, 25 Oct 2026 01:57:47 +0000</pubDate>
      <link>https://dev.to/kompiro/rate-limits-skipped-steps-and-hooks-what-tuning-ai-code-review-for-agent-prs-taught-me-karasu-4ibn</link>
      <guid>https://dev.to/kompiro/rate-limits-skipped-steps-and-hooks-what-tuning-ai-code-review-for-agent-prs-taught-me-karasu-4ibn</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt; is a text modeling language for system architecture, inspired by the C4 model.&lt;br&gt;
You describe your system in &lt;code&gt;.krs&lt;/code&gt; files and karasu draws the views: system, deployment, and team structure.&lt;br&gt;
I haven't written its code by hand; everything goes through Claude Code.&lt;/p&gt;

&lt;p&gt;This is the third weekly update.&lt;br&gt;
It covers changes merged from October 18 to 24.&lt;br&gt;
This time I start with what I learned building with agents, then go through what shipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This week in numbers:&lt;/strong&gt; 50 PRs merged (11 of them Dependabot) and 6 decisions recorded as ADRs.&lt;br&gt;
No release went out this week.&lt;br&gt;
The unreleased changes, including both highlights below, are due in today's monthly release (see "Coming next").&lt;/p&gt;
&lt;h2&gt;
  
  
  Lessons from building with agents this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CodeRabbit's review works where I can't follow the details.&lt;/strong&gt;&lt;br&gt;
CodeRabbit reviews karasu's PRs.&lt;br&gt;
In one earlier PR, it pointed out a case in edges between cards in the same row: the two points of the route around a card sat at the same height.&lt;br&gt;
The route check treated a corridor of zero height as invalid and threw away the clear route.&lt;br&gt;
So the straight route through the cards stayed.&lt;br&gt;
karasu's layout logic is complex enough that I had found it hard to review in detail.&lt;br&gt;
Findings like this, ones I would never have thought of, help a lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But a re-review on every fix uses up the quota.&lt;/strong&gt;&lt;br&gt;
Each time the agent fixes a finding and pushes, CodeRabbit reviews again.&lt;br&gt;
Repeat that and you hit the rate limit, and the PR waits.&lt;br&gt;
On one PR, CodeRabbit reviewed six times.&lt;br&gt;
Two would have been enough: the first review and one round of fixes. Three of the extra runs found one class of problem one instance at a time.&lt;br&gt;
The quota then was 2 reviews an hour, and each wait was 38 to 39 minutes.&lt;br&gt;
After four pushes in a row, CodeRabbit paused automatic reviews, and from then on each one had to be requested by hand.&lt;/p&gt;

&lt;p&gt;Dropping re-reviews isn't the answer either.&lt;br&gt;
I counted the 37 CodeRabbit-reviewed PRs among the last 60 merged.&lt;br&gt;
They took 80 reviews, 43 of them re-reviews.&lt;br&gt;
Re-reviews raised 10 new findings on 5 PRs, all in files that the fix commits touched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So I cut problems down before the web review.&lt;/strong&gt;&lt;br&gt;
This is the order I follow now.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set a risk tier from the paths a change touches, and review deeper where the tier is higher (the design is merged; implementation is next). Changes to ADRs or tests alone merge automatically after approval; changes to workflows, releases, or dependencies get a human reading the diff.&lt;/li&gt;
&lt;li&gt;Before taking a PR out of draft, run the &lt;code&gt;/engineering:code-review&lt;/code&gt; skill locally.&lt;/li&gt;
&lt;li&gt;Then run the CodeRabbit CLI once. The CLI's quota (10 an hour) is separate from PR reviews.&lt;/li&gt;
&lt;li&gt;If that comes back clean, mark the PR ready and send it to the web review.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Written steps weren't followed.&lt;/strong&gt;&lt;br&gt;
The step to run the CLI used to live only in a local memory note of the agent.&lt;br&gt;
Of about 290 sessions since October 1 that created or readied a PR, one ran the CLI.&lt;br&gt;
Even after I added the step to the procedure, a session the next day readied a PR without the local review.&lt;br&gt;
The step that hands a readied PR over to working through CodeRabbit's findings ran in about 7 of about 40 sessions.&lt;br&gt;
Most of those times, I typed it myself.&lt;br&gt;
So the steps are becoming Claude Code hooks.&lt;br&gt;
A hook that hands over to that step right after &lt;code&gt;gh pr ready&lt;/code&gt; is merged, and a hook that refuses &lt;code&gt;gh pr ready&lt;/code&gt; before the local review is in a PR now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trial and error turned up holes in the process.&lt;/strong&gt;&lt;br&gt;
The main checkout had a Stop hook that reported uncommitted changes when a session ended.&lt;br&gt;
It was meant to prevent commits made straight onto main.&lt;br&gt;
It never blocked such a commit; it only reported at the end.&lt;br&gt;
On October 24, it kept a session from exiting over changes I had left behind by hand.&lt;br&gt;
I dropped the Stop hook and made lefthook's &lt;code&gt;pre-commit&lt;/code&gt; refuse commits on main.&lt;br&gt;
Because it is a Git hook, it applies to whoever commits.&lt;br&gt;
The ADR also records what still gets through, such as &lt;code&gt;cherry-pick&lt;/code&gt; and &lt;code&gt;--no-verify&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In another project, I'm trying automatic merges decided by a change's impact.&lt;/strong&gt;&lt;br&gt;
It started with &lt;a href="https://claude.dev/blog/solving-code-review-at-anthropic/" rel="noopener noreferrer"&gt;How the Claude Code team does code review&lt;/a&gt;.&lt;br&gt;
The Claude Code team describes how they review code there, and their way of trusting agents to land changes on main influenced me strongly.&lt;br&gt;
I'm trying it in a private project.&lt;br&gt;
The idea matches karasu's risk tiers and goes one step further.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tier comes from the paths a change touches, not from its author. Docs alone skip the AI review; ordinary changes go through the AI review, the checks, and the end-to-end tests. Touching migrations, authentication, outbound sends, or the gate itself adds a human approval.&lt;/li&gt;
&lt;li&gt;Approval works only from a human's terminal; the agent can't approve.&lt;/li&gt;
&lt;li&gt;An unresolved finding from the AI review blocks the merge. Reviews stop at three rounds, and from the second round on they look only at what changed since the last one.&lt;/li&gt;
&lt;li&gt;An eval built from past fixes measures how many of 19 bugs the reviewer finds. Revising the review guidelines took it from 5 to 7. The number is generous, since I revised and measured on the same 19 cases.&lt;/li&gt;
&lt;li&gt;The AI review also found holes in the gate itself. A change could rewrite the rules that judge it and rate itself low. The gate now judges with the rules from the version on main.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's still being built, and no change has gone through it yet.&lt;br&gt;
I'll report once it runs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hand over the whole import graph, not just the open file
&lt;/h2&gt;

&lt;p&gt;Last week I fixed &lt;code&gt;karasu serve&lt;/code&gt; from npm, which hadn't worked at all.&lt;br&gt;
Even so, &lt;code&gt;serve&lt;/code&gt; in 0.9.0 couldn't draw a model that imports other files.&lt;br&gt;
It put only the opened file into the browser's in-memory file system, renamed to &lt;code&gt;/serve/index.krs&lt;/code&gt;.&lt;br&gt;
Every import reported "File not found".&lt;/p&gt;

&lt;p&gt;The design compared three options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A: hand over the whole served directory.&lt;/strong&gt; A new &lt;code&gt;GET /api/project&lt;/code&gt; on the server returns every &lt;code&gt;.krs&lt;/code&gt; and &lt;code&gt;.krs.style&lt;/code&gt; under it in one response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B: read files one at a time over HTTP.&lt;/strong&gt; Two new endpoints that take a path, and one round trip per file on every compile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C: walk the imports on the server and return only the files needed.&lt;/strong&gt; It would add a new public helper to core to save a few tens of KB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost of A is sending the whole directory.&lt;br&gt;
Measured on the entire karasu repository, that came to 108 files and 164 KB, so I went with A.&lt;/p&gt;

&lt;p&gt;The app places the files it receives at their real paths and fetches them again whenever a file changes.&lt;br&gt;
Imports now resolve by the same rules as &lt;code&gt;karasu render&lt;/code&gt;, and saving an imported file or a style sheet redraws the preview.&lt;br&gt;
When only an imported file changes, the view you drilled into stays where it was.&lt;br&gt;
&lt;code&gt;GET /api/project&lt;/code&gt; takes no path from the request and doesn't follow symbolic links.&lt;br&gt;
Nothing outside the served directory comes back.&lt;br&gt;
Along the way, a file in a subdirectory (&lt;code&gt;/services/order&lt;/code&gt;) can now be opened; before, it couldn't be opened at all.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/oChmkMAailY" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The nightly end-to-end test for serve got a fix too.&lt;br&gt;
It had been serving the regular app build instead of the serve build that the npm package actually ships.&lt;br&gt;
It's the same lesson as last week, that only a test running the packaged artifact catches this kind of bug, and the test now runs the shipped build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Share is back in serve.&lt;/strong&gt;&lt;br&gt;
Share links point at the public app (&lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu.kompiro.dev&lt;/a&gt;), so whoever receives one can open the diagram without running karasu.&lt;/p&gt;
&lt;h2&gt;
  
  
  One viewer for the app and the editor, reading unsaved buffers first
&lt;/h2&gt;

&lt;p&gt;The Visual Studio Code extension's preview used to be a webview written by hand for the extension.&lt;br&gt;
Every feature added to the app's preview had to be ported to Visual Studio Code separately.&lt;br&gt;
Now the webview runs the app's viewer as it is.&lt;br&gt;
The work came in three PRs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add the seams on the app side.&lt;/strong&gt; A host can now drive the viewer: tell it where to read files, get notified of jumps, and switch the theme and language.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace the Visual Studio Code preview.&lt;/strong&gt; The hand-written webview is gone, and the webview runs the app's viewer. Pan and zoom, the CRUD view, facets, and edge hover with the detail panel now work in Visual Studio Code without a port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write preview edits back to the editor.&lt;/strong&gt; Picking an edge direction from the right-click menu puts the change into the editor's buffer, unsaved. The editor's undo takes it back.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3UhhL3xAB6o" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The viewer asks the extension for every file it reads.&lt;br&gt;
The extension reads the open editor buffer first and falls back to the disk.&lt;br&gt;
So unsaved edits show up in the preview as you type.&lt;br&gt;
That holds for imported files as well as the open one.&lt;br&gt;
The old preview read from the disk, so unsaved edits never reached the diagram.&lt;br&gt;
I found this by reading the code during the design survey and haven't reproduced it in Visual Studio Code.&lt;/p&gt;

&lt;p&gt;On a write, the extension compares the buffer with the text the viewer last read.&lt;br&gt;
If you typed something in between and the text changed, nothing is written.&lt;br&gt;
The check keeps a write from overwriting your own edit.&lt;br&gt;
Jumping to a node defined in an imported file now opens the right file, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other changes this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;karasu fmt&lt;/code&gt; no longer moves comments to the end of the file.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;karasu fmt&lt;/code&gt; and format-on-save printed every comment written above or beside a property line at the end of the file.&lt;br&gt;
Property lines have no position in the AST, and every block kind had the same problem: edges, &lt;code&gt;deploy&lt;/code&gt;, &lt;code&gt;organization&lt;/code&gt;, and more.&lt;br&gt;
Comments now stay next to the line they annotate.&lt;br&gt;
All 16 new tests fail against the formatter on main before the fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The two bugs last week's e2e tests found are fixed.&lt;/strong&gt;&lt;br&gt;
Last week's post listed them as not yet fixed.&lt;br&gt;
The first: shortcuts such as &lt;code&gt;Ctrl/Cmd+B&lt;/code&gt; fired while you typed in the editor.&lt;br&gt;
In Chromium, Monaco takes input through a &lt;code&gt;div&lt;/code&gt; with the EditContext API attached.&lt;br&gt;
That element now counts as a text input.&lt;br&gt;
The second: reloading while the deployment view or the matrix was open dropped you back on the system view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lanes stay inside a drill-down frame.&lt;/strong&gt;&lt;br&gt;
In a drill-down view, the lanes for edges running beside the cards went onto or past the frame's sides.&lt;br&gt;
Across 4 models and 1,542 views, vertical runs on or outside the frame went from 3,100 to 31.&lt;br&gt;
The canvas grew by 1.5% in exchange.&lt;br&gt;
One view got more crossings (&lt;code&gt;TwentyServer&lt;/code&gt; in the Twenty model, +2,018), and a separate Issue tracks it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;translate --from db&lt;/code&gt; handles migration history.&lt;/strong&gt;&lt;br&gt;
It now replays migrations, from drizzle and others, in order, so dropped tables and temporary tables from rebuilds no longer remain.&lt;br&gt;
That fix opened a hole of its own, though.&lt;br&gt;
A &lt;code&gt;)&lt;/code&gt; inside a string literal ended the &lt;code&gt;CREATE TABLE&lt;/code&gt; body early, so a value such as &lt;code&gt;DEFAULT ') DROP TABLE a'&lt;/code&gt; replayed a &lt;code&gt;DROP TABLE&lt;/code&gt;.&lt;br&gt;
Another PR closed it before any release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small fixes.&lt;/strong&gt;&lt;br&gt;
Edges tagged &lt;code&gt;[inferred]&lt;/code&gt; were drawn in the same color as untagged edges, against the spec. I measured three color options and switched to one that stands apart.&lt;br&gt;
The &lt;code&gt;.krs.style&lt;/code&gt; lexer silently dropped every non-ASCII character, so a Japanese selector such as &lt;code&gt;#注文&lt;/code&gt; had no effect.&lt;br&gt;
179 relative links in the reference docs bundled with the skills broke once installed. They are now rewritten when the files are copied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Today, October 25, is the last Sunday of the month, when the monthly release train leaves. 16 unreleased changesets, including both highlights, are due on npm and the Visual Studio Code Marketplace.&lt;/li&gt;
&lt;li&gt;The implementation of review depth by risk tier is still ahead (its Issue is open).&lt;/li&gt;
&lt;li&gt;An Issue is open to make &lt;code&gt;/coderabbit-converge&lt;/code&gt; fix every instance of a finding's class before pushing.&lt;/li&gt;
&lt;/ul&gt;




&lt;ul&gt;
&lt;li&gt;Site: &lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu.kompiro.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;github.com/kompiro/karasu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>coderabbit</category>
      <category>claudecode</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What a week of agent-run Dependabot triage and AI code review taught me (karasu weekly)</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Sun, 18 Oct 2026 04:27:45 +0000</pubDate>
      <link>https://dev.to/kompiro/what-a-week-of-agent-run-dependabot-triage-and-ai-code-review-taught-me-karasu-weekly-41af</link>
      <guid>https://dev.to/kompiro/what-a-week-of-agent-run-dependabot-triage-and-ai-code-review-taught-me-karasu-weekly-41af</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt; is a text modeling language for system architecture, inspired by the C4 model.&lt;br&gt;
You describe your system in &lt;code&gt;.krs&lt;/code&gt; files and karasu draws the views: system, deployment, and team structure.&lt;br&gt;
I haven't written its code by hand; everything goes through Claude Code.&lt;/p&gt;

&lt;p&gt;This is the second weekly update.&lt;br&gt;
It covers changes merged from October 10 to 17.&lt;br&gt;
This time I start with what I learned building with agents, then go through what shipped and what each change taught me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This week in numbers:&lt;/strong&gt; 88 PRs merged (16 of them Dependabot) and 12 decisions recorded as ADRs.&lt;br&gt;
On October 15 I cut a release of four packages: karasu 0.9.0, &lt;code&gt;@karasu-tools/core&lt;/code&gt; 0.4.0, karasu-vscode 0.4.0, and karasu-skills 0.2.0.&lt;br&gt;
The &lt;code&gt;.krs&lt;/code&gt; language v2.0 from last week's post reached npm and the Visual Studio Code Marketplace with this release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons from building with agents this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dependabot triage runs on a hane skill.&lt;/strong&gt;&lt;br&gt;
karasu doesn't merge Dependabot PRs as they come.&lt;br&gt;
Triage uses the &lt;code&gt;dependabot&lt;/code&gt; skill from &lt;a href="https://github.com/kompiro/hane" rel="noopener noreferrer"&gt;hane&lt;/a&gt;, a skill collection I develop separately.&lt;br&gt;
hane is a Claude Code plugin that bundles skills which grew out of karasu's development.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;/hane:dependabot&lt;/code&gt; makes the agent go through these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Collect every open Dependabot PR.&lt;/li&gt;
&lt;li&gt;Trace each PR upstream: release notes, the code diff between tags, changes in publisher or repository ownership, install-time scripts, the lockfile's dependency edges, known advisories, and how long ago the version was published.&lt;/li&gt;
&lt;li&gt;Write the results into a design doc, with a recommendation for each PR: merge, hold, or reject.&lt;/li&gt;
&lt;li&gt;Once I decide, merge and close the PRs, then promote the design doc to an ADR.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The skill doesn't skip the investigation for patch releases.&lt;br&gt;
A tampered version dressed up as a patch is the easiest way for a supply-chain attack to get through.&lt;br&gt;
It never auto-merges either; a human makes every call.&lt;br&gt;
Because the design doc and the ADR stay in the repository, I can trace when and why any version came in.&lt;/p&gt;

&lt;p&gt;The skill holds only the steps that apply to any repository.&lt;br&gt;
Rules specific to karasu live in a rules file on the karasu side (&lt;code&gt;.claude/rules/dependabot.md&lt;/code&gt;).&lt;br&gt;
Examples are the 7-day cooldown and the conditions for bringing an update in through a replacement PR when Dependabot's own diff can't be correct.&lt;br&gt;
I ran three triage rounds this week with that combination.&lt;/p&gt;

&lt;p&gt;Running them taught me two things.&lt;/p&gt;

&lt;p&gt;The first is about the limit on open PRs.&lt;br&gt;
This week 24 npm updates cleared the cooldown, and a limit of 8 delivered them in three waves.&lt;br&gt;
Each wave needed its own triage, so I raised the limit to 25.&lt;br&gt;
The total number of PRs stays the same; only how many are open at once changes.&lt;/p&gt;

&lt;p&gt;The second is that rebuilding a lockfile can move a dependency off the version you reviewed.&lt;br&gt;
When a replacement PR rebuilt the lock, knip resolved to 6.41.0, which had just cleared the cooldown, instead of the reviewed 6.40.0.&lt;br&gt;
I pinned it back to 6.40.0 and recorded the lesson in an ADR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I classified 261 CodeRabbit findings.&lt;/strong&gt;&lt;br&gt;
CodeRabbit reviews karasu's PRs.&lt;br&gt;
I classified all 261 threads it left on Markdown files from August 20 to October 10.&lt;br&gt;
About half turned out to be real defects.&lt;br&gt;
So documentation stays in review.&lt;/p&gt;

&lt;p&gt;Among the rest, two false positives kept coming back.&lt;br&gt;
Both came from how the rule text that CodeRabbit reads was worded.&lt;br&gt;
For example, a rule saying "don't put a list of milestones in a design doc" was applied to the implementation steps that the design doc template asks for.&lt;br&gt;
The rule was only ever meant for the slice-plan table.&lt;br&gt;
So I fixed the rule text, not the CodeRabbit config, by stating its scope.&lt;br&gt;
That also makes the sentence harder to misread for a human who meets it out of context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only a packaged test catches a broken package
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;karasu serve&lt;/code&gt; from npm didn't work, and no test noticed.&lt;/p&gt;

&lt;p&gt;In the 0.8.0 npm package, &lt;code&gt;karasu serve&lt;/code&gt; answered every request with "App not built".&lt;br&gt;
The tarball held only 5 files and no preview app.&lt;br&gt;
&lt;code&gt;serve&lt;/code&gt; looked for the app at a path relative to the monorepo, so it worked inside the repository and failed when installed from npm.&lt;br&gt;
In other words, the README's &lt;code&gt;npx --yes karasu@latest serve .&lt;/code&gt; had never worked outside the monorepo.&lt;br&gt;
I noticed while trying the reverse-architecture skill on an outside repository.&lt;/p&gt;

&lt;p&gt;The fix ships a serve-only build of the app in &lt;code&gt;dist/app/&lt;/code&gt;.&lt;br&gt;
A new CI step packs the CLI with &lt;code&gt;pnpm pack&lt;/code&gt;, unpacks the tarball, and starts &lt;code&gt;serve&lt;/code&gt; from it.&lt;br&gt;
I confirmed that this test fails when &lt;code&gt;dist/app/&lt;/code&gt; is dropped from the package's file list.&lt;br&gt;
Only a test that runs the packaged artifact can catch this kind of bug.&lt;/p&gt;

&lt;p&gt;The bundled app was 16MB (97 files), and most of it was the Monaco editor.&lt;br&gt;
&lt;code&gt;serve&lt;/code&gt; only shows the preview and never opens the editor.&lt;br&gt;
So the serve build now has its own entry point, and the build fails if any Monaco module ends up in the bundle.&lt;br&gt;
I checked the guard by adding the Monaco import back on purpose: the build failed and named 1,233 modules.&lt;br&gt;
The serve app is now 1.7MB (4 files).&lt;br&gt;
The released 0.9.0 package is 3.3MB unpacked (12 files).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0.9.0 shipped on the third release run.&lt;/strong&gt;&lt;br&gt;
Two npm Trusted Publisher pitfalls stopped karasu-skills from publishing.&lt;br&gt;
Trusted Publisher is the npm setting that lets GitHub Actions publish without a token.&lt;br&gt;
karasu 0.9.0 depends on karasu-skills 0.2.0, so it stopped too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;E404:&lt;/strong&gt; A newly registered configuration is "not yet validated", and it expires unless a publish through it succeeds within 2 days. I registered the karasu-skills configuration right after publishing 0.1.0 by hand. The release uses &lt;code&gt;changeset publish&lt;/code&gt;, which skips versions already on npm, so 0.1.0 could never validate the configuration. It expired before 0.2.0 went out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E403:&lt;/strong&gt; A configuration created after September 3, 2026 allows only &lt;code&gt;npm stage publish&lt;/code&gt; by default. The release workflow runs &lt;code&gt;npm publish&lt;/code&gt;, so "Allow npm publish" had to be checked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The release docs now say to register the configuration right before merging the release PR that bumps the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure what a fix changes, not only what it fixes
&lt;/h2&gt;

&lt;p&gt;Edge routing got more work this week.&lt;br&gt;
The target was edges drawn straight across cards they should go around.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Edges between cards in the same row.&lt;/strong&gt; These used to cut straight through any card standing between them. Now they go around through the channel above or below the row. The side with fewer crossings against existing edges wins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges into a side column.&lt;/strong&gt; In the Dify model, three edges to and from &lt;code&gt;Gateway&lt;/code&gt; crossed 7 cards in each of two views. Now they run down the gap beside the column.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three smaller fixes went in as well.&lt;br&gt;
Lanes in a channel are now ordered by whether each edge turns up or down.&lt;br&gt;
Routes that folded back over the same channel are collapsed into one run.&lt;br&gt;
In a drill-down view, lanes and labels stay inside the focused frame.&lt;/p&gt;

&lt;p&gt;Each fix was measured on real models reverse-engineered from open-source projects.&lt;br&gt;
The main set is Umami, Dify, Twenty, and WordPress, 1,542 views in total.&lt;br&gt;
Two numbers are tracked for every fix: how many problem spots it removes, and how many views it changes as a side effect.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;th&gt;Problem spots&lt;/th&gt;
&lt;th&gt;What else changed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Same-row edges&lt;/td&gt;
&lt;td&gt;Edges through cards: 19 → 0&lt;/td&gt;
&lt;td&gt;5 views; +131 crossings (all drawn with hops)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Side-column edges&lt;/td&gt;
&lt;td&gt;Edges through cards on Dify: 14 → 0&lt;/td&gt;
&lt;td&gt;Crossings 38,147 → 38,176 (+29)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Channels bounded by the frame&lt;/td&gt;
&lt;td&gt;Runs outside the frame in a 5-card fixture: 14 → 0&lt;/td&gt;
&lt;td&gt;5 of 7,659 edges, in 3 of 1,542 views&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the side-column fix there was also an option that cleared a wider corridor.&lt;br&gt;
It would have changed 13 views, so I went with the smaller change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other changes this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Crossing marks now dim with their edges.&lt;/strong&gt;&lt;br&gt;
Hovering a card or an edge dims the unrelated edges.&lt;br&gt;
The small arcs drawn where edges cross ("hops") and the count chips stayed bright, though, and kept tracing the shape of the dimmed edges.&lt;br&gt;
Now the marks dim along with their edges.&lt;br&gt;
To make that possible, the hops that last week merged into one &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; are split again, one &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; per edge.&lt;br&gt;
On the Dify model, output grew by 4.29% and hop &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; elements went from 757 to 2,585.&lt;br&gt;
The largest view still renders in about the same time: 33.3 ms before, 33.5 ms after.&lt;br&gt;
Edges that ignored the mouse, such as those in the deployment view, now respond to hover too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes with the same name are no longer mixed up.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Api&lt;/code&gt; inside &lt;code&gt;Shop&lt;/code&gt; (&lt;code&gt;Shop.Api&lt;/code&gt;) and a top-level &lt;code&gt;service "Shop.Api"&lt;/code&gt; used to share one internal key.&lt;br&gt;
Every node and edge identity key now comes from one helper that cannot produce collisions.&lt;br&gt;
When two systems declare a node with the same ID, each internal map used to pick a different winner; they now follow one rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;karasu diff&lt;/code&gt; compares multiple systems correctly.&lt;/strong&gt;&lt;br&gt;
Compare mode diffed only the first system.&lt;br&gt;
Adding or removing the first system made it compare two different systems, so unchanged cards showed up as removed and added.&lt;br&gt;
Systems are now paired by ID, not by position.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small fixes.&lt;/strong&gt;&lt;br&gt;
In a style sheet, &lt;code&gt;label-offset: -20px&lt;/code&gt; lost its sign and behaved like &lt;code&gt;20px&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;karasu render &amp;lt;directory&amp;gt;&lt;/code&gt; used to fail with "File not found"; it now reads the directory's &lt;code&gt;index.krs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The e2e tests found two real bugs.&lt;/strong&gt;&lt;br&gt;
This week added a lot of Playwright end-to-end tests, and no test is left behind &lt;code&gt;test.skip&lt;/code&gt;.&lt;br&gt;
Along the way they found two bugs that jsdom unit tests could not see. Neither is fixed yet.&lt;br&gt;
The first: shortcuts such as &lt;code&gt;Ctrl/Cmd+B&lt;/code&gt; fire while you type in the editor.&lt;br&gt;
Monaco's input target changed to an element that is neither &lt;code&gt;contenteditable&lt;/code&gt; nor a &lt;code&gt;textarea&lt;/code&gt;, so the "is the user typing?" check misses it.&lt;br&gt;
The second: reloading while the deployment view or the matrix is open drops you back on the system view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A design for shipping the Visual Studio Code extension as a weekly prerelease is merged. Implementation comes next.&lt;/li&gt;
&lt;li&gt;An Issue is open to move npm publishing to staged publishing under Trusted Publisher.&lt;/li&gt;
&lt;li&gt;An epic is open to make the public gallery available beyond its operator, me.&lt;/li&gt;
&lt;/ul&gt;




&lt;ul&gt;
&lt;li&gt;Site: &lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu.kompiro.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;github.com/kompiro/karasu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>ai</category>
      <category>claudecode</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Had Claude Code Make the Demo GIF for My README</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Thu, 15 Oct 2026 14:41:17 +0000</pubDate>
      <link>https://dev.to/kompiro/i-had-claude-code-make-the-demo-gif-for-my-readme-ih9</link>
      <guid>https://dev.to/kompiro/i-had-claude-code-make-the-demo-gif-for-my-readme-ih9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq5dac0pc8m5e7ui03rx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq5dac0pc8m5e7ui03rx.gif" alt="The karasu demo GIF. An agent reverse-engineers a repository into one model, then the web app descends from the whole system down to use cases and finally switches to the Deploy view" width="599" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I put this demo GIF at the top of the README for &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt;, the architecture diagram tool I develop.&lt;br&gt;
Claude Code made it, from the script through recording and captions to the final GIF.&lt;/p&gt;

&lt;p&gt;My impression is that few engineers know Claude Code can make demo videos.&lt;br&gt;
This post shows briefly how it was recorded, then covers what I decided along the way.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code can drive an app inside a devcontainer (a Linux container), record it, and turn the recording into a captioned, looping GIF.&lt;/strong&gt; It never had to touch my own browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to tell it first is the purpose, not the format.&lt;/strong&gt; When I said "a looping GIF for the README" instead of "a 3-minute intro video," it came back with a 20 to 30 second script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most of my decisions came after I saw a prototype.&lt;/strong&gt; I had said captions were unnecessary, and the prototype changed my mind. It was also Claude Code that caught the private repository's name in the captions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How it was recorded
&lt;/h2&gt;

&lt;p&gt;Recently, I do my development in a devcontainer.&lt;br&gt;
Visual Studio Code opens a Linux container, and I run Claude Code inside it.&lt;br&gt;
Claude Code started karasu's preview server (&lt;code&gt;karasu serve&lt;/code&gt;) in the container and recorded while driving a browser with Playwright.&lt;br&gt;
It recorded through the Chrome DevTools Protocol screencast, which sends a frame only when the screen changes.&lt;br&gt;
A still scene costs one frame, so the GIF stays small.&lt;br&gt;
The mouse cursor and the captions are overlays drawn on the page for the recording.&lt;br&gt;
ImageMagick assembles the frames into a GIF.&lt;/p&gt;

&lt;p&gt;The only thing added to the container was a Japanese font.&lt;br&gt;
I also made a Japanese version, and without the font its captions and the app's Japanese UI render as boxes.&lt;/p&gt;

&lt;p&gt;The opening terminal scene is a rebuilt replay, not a recording.&lt;br&gt;
The real run took about 15 minutes, far too long for a GIF.&lt;br&gt;
Every command and number on that screen comes from the real run.&lt;/p&gt;

&lt;p&gt;The recording scripts live in the karasu repository, so I can re-record the same way when the UI changes.&lt;br&gt;
The steps are in &lt;a href="https://github.com/kompiro/karasu/blob/main/scripts/readme-demo/README.md" rel="noopener noreferrer"&gt;scripts/readme-demo/README.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  From a 3-minute intro video to a 30-second loop
&lt;/h2&gt;

&lt;p&gt;My first request was "I want to shoot a 3-minute demo video introducing karasu. Start by drafting a script."&lt;br&gt;
I got a 3-minute script with narration.&lt;br&gt;
It was exactly what I had asked for.&lt;/p&gt;

&lt;p&gt;So I explained why I wanted it.&lt;br&gt;
The README had no looping image at all, and I wanted one.&lt;br&gt;
I didn't need an opening; showing what the tool can do mattered more.&lt;br&gt;
Should a GIF be a minute long, or even shorter?&lt;/p&gt;

&lt;p&gt;The answer was "20 to 30 seconds, a minute at most," with three reasons.&lt;br&gt;
A GIF has no seek bar and no sound, so viewers can't skip to the part they want.&lt;br&gt;
A 3-minute GIF runs to tens of megabytes and slows down the README.&lt;br&gt;
Command-line steps read better as code blocks in the README than as text inside a GIF.&lt;/p&gt;

&lt;p&gt;Explaining the purpose changed the content as well as the length.&lt;br&gt;
The command-line scenes from the first script disappeared, and only the operations you can follow by watching remained.&lt;br&gt;
I had said "a 3-minute video" because I was thinking in terms of the format.&lt;br&gt;
Had I given only the format, I would have ended up with a well-made 3-minute video.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decisions that changed after the prototype
&lt;/h2&gt;

&lt;p&gt;While we were working out the script, Claude Code asked whether to add captions.&lt;br&gt;
I answered that it would be better if the GIF made sense without them.&lt;br&gt;
I also said I wanted to show off a huge system at a glance, not a small diagram with a few nodes.&lt;/p&gt;

&lt;p&gt;On the subject, I changed my mind after seeing what a trial produced.&lt;br&gt;
Claude Code first suggested a WordPress model it found locally (about 20,000 lines, 42 domains).&lt;br&gt;
I wanted to see whether my own AI journaling service would be enough, so I asked it to reverse-engineer that.&lt;br&gt;
Claude Code spun up 13 subagents, one per domain, and built the model with about 1.5 million tokens.&lt;br&gt;
Its report said: "Not huge enough, but the diagram stays readable at every level you descend to. WordPress turns into a tangle of lines once you drill in."&lt;br&gt;
After seeing the actual screens, I dropped the idea of showing scale and went with the AI journaling service.&lt;/p&gt;

&lt;p&gt;Captions went the same way.&lt;br&gt;
The first prototype was 18 seconds with no captions, and when I watched it, I couldn't tell what it was trying to show.&lt;br&gt;
The screen moved, and it drilled down.&lt;br&gt;
But I felt that someone who didn't know karasu wouldn't understand why any of those operations were happening.&lt;br&gt;
I asked to see a captioned version too, and 14 minutes later I had two GIFs, with and without captions.&lt;br&gt;
Side by side, the captioned one got the idea across far better.&lt;/p&gt;

&lt;p&gt;My belief that it would work without captions was a judgment I made in my head before anything existed.&lt;br&gt;
I only found out it was wrong when I saw the real thing.&lt;br&gt;
When a prototype arrives in a quarter of an hour, there is little reason to settle a judgment up front.&lt;br&gt;
My part was to look at what came back and say "this doesn't get the point across."&lt;/p&gt;

&lt;h2&gt;
  
  
  What it could touch, and what viewers could see
&lt;/h2&gt;

&lt;p&gt;Apart from the content of the demo, I drew two boundaries.&lt;/p&gt;

&lt;p&gt;The first was what Claude Code could touch.&lt;br&gt;
Claude Code also has computer use, which looks at the screen and drives the mouse and keyboard, so it could have recorded in my own browser.&lt;br&gt;
But my browser holds plenty of logged-in sessions, and I'd rather not let an agent near them.&lt;br&gt;
This time everything stayed inside the devcontainer with Playwright, so the question never came up.&lt;br&gt;
When the recording was done, I also had it list what it had added to the container and how to undo each item.&lt;/p&gt;

&lt;p&gt;The second was what viewers could see.&lt;br&gt;
The AI journaling service I used as the subject lives in a private repository.&lt;br&gt;
I had that in mind, but the captioned prototype put the repository name in the opening caption, and I missed it.&lt;br&gt;
Claude Code was the one that caught it.&lt;br&gt;
I had the caption changed to "an AI journaling system on Cloudflare," then asked for the names in the diagram to be hidden too.&lt;br&gt;
Claude Code replaced them everywhere, in the breadcrumbs, the data store names, the worker names, and the title of the opening terminal, and checked that the original name no longer appeared anywhere in the model.&lt;br&gt;
It then pointed out that the comment at the top of the model still contained the repository name and needed to go before any commit.&lt;br&gt;
In the end, the demo model stayed out of the repository, and the README for the recording scripts says why.&lt;/p&gt;

&lt;p&gt;Here too, what prompted me to draw a line was seeing the prototype.&lt;br&gt;
I decided where the lines went, and Claude Code applied them down to the details.&lt;/p&gt;

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

&lt;p&gt;Claude Code will drive an app inside a container, record it, and turn it into a captioned, looping GIF.&lt;br&gt;
If you have wanted a demo video but never thought it worth the effort, try asking for one.&lt;/p&gt;

&lt;p&gt;When you ask, start with where the video will live and who it is for, before length or format.&lt;br&gt;
After that, watch the prototypes and complain about whatever doesn't land.&lt;br&gt;
What to show and what to keep hidden is still yours to decide as you watch.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>devtools</category>
      <category>showdev</category>
    </item>
    <item>
      <title>karasu weekly update: language v2.0, a focus canvas, and 97% fewer SVG elements</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Fri, 09 Oct 2026 14:27:29 +0000</pubDate>
      <link>https://dev.to/kompiro/karasu-weekly-update-language-v20-a-focus-canvas-and-97-fewer-svg-elements-21ml</link>
      <guid>https://dev.to/kompiro/karasu-weekly-update-language-v20-a-focus-canvas-and-97-fewer-svg-elements-21ml</guid>
      <description>&lt;p&gt;&lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu&lt;/a&gt; is a text modeling language for system architecture, inspired by the C4 model. You describe your system in &lt;code&gt;.krs&lt;/code&gt; files and karasu draws the views: system, deployment, and team structure. I started it about six months ago to learn agentic coding, and I haven't written its code by hand. Everything goes through Claude Code.&lt;/p&gt;

&lt;p&gt;This is the first of a weekly series. Each post covers what shipped and what building it with agents looked like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This week in numbers:&lt;/strong&gt; 41 PRs merged (7 of them Dependabot) and 10 decisions recorded as ADRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlight 1: a focus canvas for dense diagrams
&lt;/h2&gt;

&lt;p&gt;Architecture diagrams get crowded, and edge labels are the first thing to suffer. They overlap, get truncated, or are simply unreadable.&lt;/p&gt;

&lt;p&gt;karasu now handles this in two layers. The main canvas draws only the labels it has room for. The full text lives in a &lt;strong&gt;focus canvas&lt;/strong&gt; that opens over the preview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Click an edge&lt;/strong&gt; to see the two nodes it connects, with every edge between them. Each label gets its own lane and is drawn in full.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click the "Relations" pill on a node&lt;/strong&gt; to see the node with all its neighbours: dependents on one side, dependencies on the other.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Later in the week the canvas became reachable without a mouse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On touch devices, the node detail panel offers a "Relations" button.&lt;/li&gt;
&lt;li&gt;From the keyboard, a command-palette entry opens the canvas for the highlighted node.&lt;/li&gt;
&lt;li&gt;Inside the canvas you move with Tab, and focus returns to where you came from when the canvas closes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Highlight 2: .krs language v2.0
&lt;/h2&gt;

&lt;p&gt;This was a breaking release of the language itself. The main idea is that &lt;strong&gt;the vocabulary is now closed&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tags and annotations belong to the tool.&lt;/strong&gt; Previously you could invent your own. Now a style rule that targets a tag karasu doesn't know matches nothing, so the meaning of a diagram can't drift between projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;facet&lt;/code&gt; and &lt;code&gt;boundary&lt;/code&gt; are core notation.&lt;/strong&gt; They were experimental. Facets handle cross-cutting concerns such as "which components touch PCI data", and boundaries group nodes by membership.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Some warnings became errors.&lt;/strong&gt; Placing a node in a context where it doesn't belong is now an error, and so is a near-miss of a built-in annotation (for example, &lt;code&gt;@depracated&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Error" has a definition.&lt;/strong&gt; An error is syntax karasu does not accept, and no new diagram is drawn while one stands. The VS Code preview now keeps showing the last valid render instead of a half-recovered picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Smaller things worth mentioning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;97% fewer SVG elements.&lt;/strong&gt; On a large real-world model (Dify), the small arcs drawn where edges cross ("hops") made up 43% of the output. Hops are now merged into one &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; per run of consecutive hops with the same stroke. That cut hop elements from 38,572 to 894 and output size from 8.72 MB to 6.48 MB. Only &lt;em&gt;consecutive&lt;/em&gt; hops are merged. Grouping every hop by colour would have saved slightly more, but it would have swapped the stacking order of 4,757 overlapping pairs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unicode names no longer lose characters.&lt;/strong&gt; The lexer read UTF-16 units one at a time, so &lt;code&gt;𠮷野家&lt;/code&gt; silently became &lt;code&gt;野家&lt;/code&gt; and a decomposed &lt;code&gt;café&lt;/code&gt; became &lt;code&gt;cafe&lt;/code&gt;. It now reads by code point. Characters it can't place, such as a stray emoji or a zero-width space inside a name, are reported instead of dropped. Reading by code point made tokenizing a 10k-line model about twice as slow, so ASCII now takes a fast path, and the speed is back where it was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edge bundling in gutters.&lt;/strong&gt; Edges running in the same gutter towards the same end now share one lane. This first made rendering about 25% slower, and a spatial index brought it back, with byte-identical output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OGP images for the gallery.&lt;/strong&gt; Public gallery submissions now get a social preview image. The design started as "store a PNG in KV and clean it up with a cron job". KV reads can be up to about 60 seconds stale, though, and Workers requests have no bounded duration, so a timed cleanup could never be proven correct. The final design stores nothing: the image is rendered on a cache miss and kept in the edge cache for a day. In production a miss costs 523 to 620 ms of CPU and a hit costs 2 to 5 ms.&lt;/p&gt;

&lt;h2&gt;
  
  
  What building with agents looked like this week
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A hook that executed files.&lt;/strong&gt; A Claude Code &lt;code&gt;PostToolUse&lt;/code&gt; hook was meant to format TypeScript after each edit. It ran under &lt;code&gt;/bin/sh&lt;/code&gt; (dash), which has no &lt;code&gt;[[&lt;/code&gt;, so the condition was split at &lt;code&gt;||&lt;/code&gt;. The result was that the hook &lt;em&gt;executed&lt;/em&gt; any executable file the agent had just edited, and never formatted a single &lt;code&gt;.ts&lt;/code&gt; file. Nobody noticed for a while because nothing visibly failed. The fix was a POSIX &lt;code&gt;case&lt;/code&gt;. The lesson: agent hooks are code too, and they deserve the same scrutiny as the code they guard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review moved earlier.&lt;/strong&gt; The workflow now runs an agent code review on the branch diff &lt;em&gt;before&lt;/em&gt; opening the draft PR. Previously it ran after. Review fixes now land in the PR's first push, so the PR history stays readable. I recorded this as an ADR that supersedes an earlier decision, because the original reason for rejecting this option no longer held.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The design doc → ADR loop.&lt;/strong&gt; Most features this week went through the same cycle: a design doc in a PR, discussion, implementation, then promotion to an ADR, after which the design doc is deleted. Ten ADRs were recorded this way. The design docs are where the agents and I argue. The ADRs are what stays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming next
&lt;/h2&gt;

&lt;p&gt;Two designs were merged this week and wait for implementation: ordering channel lanes by the direction each edge turns, and making node and edge identity keys collision-free.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Site: &lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;karasu.kompiro.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;github.com/kompiro/karasu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback and questions are welcome in the comments.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>opensource</category>
      <category>ai</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Mapping an Unfamiliar Repository: Introducing karasu's reverse-architecture Skill</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Thu, 01 Oct 2026 16:15:41 +0000</pubDate>
      <link>https://dev.to/kompiro/mapping-an-unfamiliar-repository-introducing-karasus-reverse-architecture-skill-3k12</link>
      <guid>https://dev.to/kompiro/mapping-an-unfamiliar-repository-introducing-karasus-reverse-architecture-skill-3k12</guid>
      <description>&lt;p&gt;Getting the big picture of a repository you have never worked on always takes effort. What services are there, which data stores do they write to, and how do the features depend on each other? You guess from the README and the directory layout, then go back and forth between the routes and the schema until a diagram takes shape in your head.&lt;/p&gt;

&lt;p&gt;I have published a skill, &lt;strong&gt;reverse-architecture&lt;/strong&gt;, that hands this work to an agent, as a Claude Code plugin. The skill reads the repository and writes an architecture model, and &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt;, the architecture diagram tool I develop, draws it.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;reverse-architecture is a skill that turns a repository into a karasu &lt;code&gt;.krs&lt;/code&gt; model.&lt;/strong&gt; Ask for it, and it puts everything from services down to tables into one diagram.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On umami, an OSS web analytics tool, it produced a model with 10 domains and 135 usecases.&lt;/strong&gt; The investigating subagents used about 960k tokens in total, and the run took about 10 minutes through to synthesis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The output is a map to review and evolve, not the correct diagram.&lt;/strong&gt; Boundaries it was unsure about stay marked, and the diagrams can still be easier to read. If something bothers you when you use it, please tell me in a karasu issue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What reverse-architecture and karasu each do
&lt;/h2&gt;

&lt;p&gt;karasu describes a system's logical, physical, and organizational structure in a text language (&lt;code&gt;.krs&lt;/code&gt;) and renders it as diagrams. Instead of packing everything onto one page, it lets you descend step by step from the system to services, domains, and usecases. The &lt;a href="https://fukurou.kompiro.dev/en/karasu/" rel="noopener noreferrer"&gt;introduction to karasu&lt;/a&gt; covers the syntax and the design ideas.&lt;/p&gt;

&lt;p&gt;reverse-architecture builds that &lt;code&gt;.krs&lt;/code&gt; from an existing repository. The roles are split: the skill (that is, the agent running it) reads the repository and writes the model, and the karasu CLI validates and renders it. When the repository has a docker-compose file or a DB schema, the CLI converts it mechanically. That way the agent does not have to guess the infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;Install it in Claude Code as follows. The skill drives the karasu CLI, so install the CLI too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g karasu
/plugin marketplace add kompiro/karasu
/plugin install karasu@karasu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open Claude Code in the repository you want to look into and ask "turn this repo into a karasu model" or "reverse architecture". The agent first scouts the whole repository and proposes how to split it into domains. It starts one investigating subagent per domain, so for a large repository it shows the domain count and a rough cost estimate and asks before going ahead. Once you agree, the investigation and synthesis run, and you end up with an &lt;code&gt;index.krs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Claude Code is the only supported agent for now. The plugin does not update automatically, so pick up new releases from the &lt;code&gt;/plugin&lt;/code&gt; menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  What umami looks like as a map
&lt;/h2&gt;

&lt;p&gt;As an example, I mapped &lt;a href="https://github.com/umami-software/umami" rel="noopener noreferrer"&gt;umami&lt;/a&gt;, an OSS web analytics tool (version 3.4.0, about 1,300 source files). This is the top-level diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F60p4p9vd4mczbhojyd4v.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F60p4p9vd4mczbhojyd4v.png" alt="System diagram of umami. Users reach the Umami app through the tracker, the dashboard, and the MCP server, and the app connects to four data stores" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A single Next.js app serves the tracking endpoints, the API, and the dashboard. You can also read that PostgreSQL is required, while ClickHouse, Redis, and Kafka are used only when configured. Beneath this one diagram sits the following model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domains&lt;/strong&gt;: 10 of them (tracking, analytics, session replay, websites with links and pixels, boards, sharing, teams, identity, administration, and MCP tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usecases&lt;/strong&gt;: 135. Each one records the PostgreSQL or ClickHouse tables, Redis keys, and Kafka topics it touches, with reads and writes told apart&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entities&lt;/strong&gt;: 26. Every one of PostgreSQL's 26 tables is mapped to an entity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you descend into a domain, the diagrams get detailed, so the gallery is a better way to look at them than screenshots. I &lt;a href="https://karasu-nest.kompiro.dev/g/42963-bg390asxhh4w" rel="noopener noreferrer"&gt;put the generated model in the karasu gallery&lt;/a&gt;. From the Umami app you can follow the diagrams down to the dependencies between domains, and from a domain down to its usecases and tables. You can also drill into a database such as PostgreSQL and see the relations between its tables as a simple ER diagram. The usecase descriptions record the behavior the agent read from the code (such as which table it writes to under which condition).&lt;/p&gt;

&lt;p&gt;Here is what it cost. Ten subagents did the investigation, each using roughly 70k to 150k tokens, about 960k in total. I ran them in two batches of five, and it took about 10 minutes from the start of the investigation to the end of synthesis. The scouting and synthesis ran in the main session, so they are not included in these numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to keep in mind
&lt;/h2&gt;

&lt;p&gt;Treat the output as a map to review and evolve. Where the agent could not settle a domain boundary, it marks the spot with &lt;code&gt;@draft&lt;/code&gt;. In the umami run, two spots were marked: whether session replay should be separate from tracking, and whether links and pixels belong in the same domain as websites. Both were settled during the investigation, on evidence from the code. The reasoning stays in the model's descriptions, so a human reader can correct it if it looks wrong.&lt;/p&gt;

&lt;p&gt;Cost grows with the number of domains and the size of the repository. A small repository may need only a few hundred thousand tokens, but for a large one it is safer to budget more than 100k tokens per domain. When the agent asks you to confirm the domain count, decide with that number in mind.&lt;/p&gt;

&lt;p&gt;If the repository lacks the inputs that describe its infrastructure, you may need to prepare them first. umami generates its OpenAPI spec at build time and does not commit it, so I installed its dependencies and generated the spec before the run. I also converted the Prisma schema into SQL. A model can still be built without these inputs. In that case, though, finding the usecases and tables depends entirely on the agent reading the source.&lt;/p&gt;

&lt;p&gt;The diagrams could also be easier to read. In the umami run, the agent wrote the evidence for each dependency into the labels of the arrows between domains, so the diagram of domain dependencies filled up with text. I filed this as an &lt;a href="https://github.com/kompiro/karasu/issues/3018" rel="noopener noreferrer"&gt;issue&lt;/a&gt; and plan to change the skill so that labels stay short and the evidence moves into the description. Also, the local preview server (&lt;code&gt;karasu serve&lt;/code&gt;) does not work yet when karasu is installed from npm (&lt;a href="https://github.com/kompiro/karasu/issues/3017" rel="noopener noreferrer"&gt;issue&lt;/a&gt;). Until that is fixed, export an SVG with &lt;code&gt;karasu render index.krs -o arch.svg&lt;/code&gt; and open that.&lt;/p&gt;

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

&lt;p&gt;reverse-architecture is a skill for turning the big picture of an unfamiliar repository into a karasu diagram you can keep. For umami, about 10 minutes of investigation put everything from services down to tables into one model. It is less a finished diagram than a map to start a review from.&lt;/p&gt;

&lt;p&gt;If you notice a diagram that is hard to read, or a structure the model could not express well, please tell me in a &lt;a href="https://github.com/kompiro/karasu/issues" rel="noopener noreferrer"&gt;karasu issue&lt;/a&gt;. Both issues above came from actually mapping umami.&lt;/p&gt;

&lt;p&gt;I am also preparing a skill for writing up your own system as &lt;code&gt;.krs&lt;/code&gt; through conversation and keeping it up to date. I will introduce it once it is published.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>claude</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Interviewed My Coding Agent After Three Months of Document-Driven Development</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Wed, 01 Jul 2026 14:50:44 +0000</pubDate>
      <link>https://dev.to/kompiro/i-interviewed-my-coding-agent-after-three-months-of-document-driven-development-iej</link>
      <guid>https://dev.to/kompiro/i-interviewed-my-coding-agent-after-three-months-of-document-driven-development-iej</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I built a personal OSS project, &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;karasu&lt;/a&gt; (a text-based architecture modeling tool), hand-in-hand with the coding agent Claude Code over three months. Partway through, I committed hard to "document-driven development" as a methodology — ADRs, Design Docs, a Test Perspective Library (TPL), and acceptance tests. For the retrospective, I had the agent itself interview me. What follows is a lightly edited, near-raw log.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why I started
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; I've used Devin and Cursor as coding agents. Devin writes code autonomously, which is nice, but it kept piling up experimental commits without ever reaching the goal I actually wanted. That was painful.&lt;/p&gt;

&lt;p&gt;Cursor was a great environment, and when building new features I found defining &lt;em&gt;rules&lt;/em&gt; especially effective. Back then my design docs lived in Notion, so I'd paste Notion URLs to feed the design in — but it wouldn't autonomously pull in &lt;em&gt;related&lt;/em&gt; documents and guarantee consistency across them.&lt;/p&gt;

&lt;p&gt;So, to feel for myself &lt;strong&gt;how much productivity would improve if the design docs lived in the same repository&lt;/strong&gt;, I started karasu as a document-first project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent (Claude Code):&lt;/strong&gt; Looking at the repo state, I thought "this is a pretty extreme experiment." In the last 90 days: &lt;strong&gt;1,032 commits, 244 ADRs, 210 acceptance tests, 67 TPLs&lt;/strong&gt;. Running that density on a solo OSS project is a different thing entirely from "let's write some docs."&lt;/p&gt;

&lt;p&gt;From an agent's perspective, what worked first was that &lt;strong&gt;CLAUDE.md is only 82 lines and sticks to being an index — a table of pointers to other docs&lt;/strong&gt;. I'm an entity whose context resets every time, so being handed a "if you're lost, look here" map upfront slashes my exploration cost. Over-stuffed instruction files actually invite skimming, so this restraint was the right call.&lt;/p&gt;




&lt;h2&gt;
  
  
  ADRs, TPLs, acceptance tests — what worked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Of the three, which one made you feel "I can't go back to not having this"? And which one still feels "honestly, just heavy"?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; For ADRs and TPLs, I built adr-tools / tpl-tools to guarantee consistency, so cross-document consistency rarely broke. Acceptance tests reduced missing test cases. &lt;strong&gt;What I started to feel as the real problem was gaps in the spec itself.&lt;/strong&gt; Keeping acceptance tests as a metric for how much E2E coverage we had was also effective.&lt;/p&gt;

&lt;p&gt;On "the process is heavy" — I was running &lt;strong&gt;5–6 sessions in parallel&lt;/strong&gt;, so honestly I didn't feel the weight.&lt;/p&gt;

&lt;p&gt;Oh, but — &lt;strong&gt;I was surprised you started writing acceptance tests even for non-product code.&lt;/strong&gt; I hadn't expected that far. Still, keeping the tooling alive matters for not letting dev productivity drop.&lt;/p&gt;

&lt;p&gt;My biggest cost pain is running CI / E2E on GitHub Actions. I didn't expect it to cost my Pro plan allotment &lt;em&gt;plus&lt;/em&gt; another $20. From your side, where did it feel like overkill?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Three, no sugar-coating:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "touch a spec → ship at least one proactive TPL" rule.&lt;/strong&gt; The intent is right, but a mechanical minimum quota tempts you to produce "TPLs just to meet the quota." A TPL's value is selection quality, not count, so a floor risks lowering the signal-to-noise ratio.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manually maintained bidirectional links.&lt;/strong&gt; Automating it with tooling was impressive. But "it holds because it's automated" is the flip side of "it breaks under bare operation."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The pile of exception rules accumulated in memory.&lt;/strong&gt; Caveats like "ADR-only PRs may auto-merge," "force-push cancels e2e, so add a new commit instead" have piled up. That's the very history of a base process so strict that exceptions had to be punched through it — the complexity debt a successful process inevitably accrues.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But — the fact that &lt;strong&gt;1,032 commits over 90 days across 5–6 parallel sessions didn't collapse&lt;/strong&gt; justifies that excess. "Heavy process × high parallelism works" is itself an interesting finding.&lt;/p&gt;




&lt;h2&gt;
  
  
  The origin of the TPL (Test Perspective Library)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; You said the bottleneck shifted from "missing test cases" to "gaps in the spec." Any concrete episode?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Honestly, gaps existed before agents too. Things I'd dropped under YAGNI would suddenly become necessary.&lt;/p&gt;

&lt;p&gt;I introduced the TPL because &lt;strong&gt;while building the layout-adjustment feature for the System diagram, the change failed to propagate to the Deploy and Org diagrams.&lt;/strong&gt; So I decided: "let's add the cross-cutting cases as test perspectives so we notice gaps at the design stage." The proactive-TPL idea also came from wanting to &lt;strong&gt;confirm that a new feature hasn't broken another feature when something else is updated.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Hearing that, a TPL isn't just "prevent missing tests" — it's a mechanism to &lt;strong&gt;verbalize, at design time, whether touching one diagram/feature breaks another diagram/feature that's structurally coupled to it.&lt;/strong&gt; Calling it a "cross-cutting impact map" rather than a "test perspective" might convey the essence better.&lt;/p&gt;




&lt;h2&gt;
  
  
  The biggest discovery — the agent should &lt;em&gt;return questions&lt;/em&gt;, not &lt;em&gt;take off running&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Did placing the docs first resolve Devin's "piles experimental commits, never reaches the goal" problem?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; The non-convergence really was resolved. Especially by having you write the Design Doc — &lt;strong&gt;you'd raise design options I hadn't thought of, and surface unresolved questions, which exposed the gaps in the requirements I was holding.&lt;/strong&gt; With Devin it just barrels forward autonomously, so something that "kind of works" gets built — and sometimes it wasn't what I wanted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; I think this is the project's biggest discovery.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Devin model:&lt;/strong&gt; the agent takes off → something that kind-of-works gets built → but it's not what you wanted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;karasu model:&lt;/strong&gt; the agent first returns questions (Design Doc, unresolved questions) → the gaps in human requirements get exposed → it converges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, &lt;strong&gt;a coding agent's value isn't writing code fast — it's exposing the holes in human thinking first.&lt;/strong&gt; Document-driven development made a permanent venue, inside the repo, for exposing those holes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deciding to &lt;em&gt;entrust&lt;/em&gt; the agent
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; "I was surprised you wrote ATs for non-product code too" — was that a happy surprise or a wary one?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; It'd be a lie to say I wasn't wary about overkill. But &lt;strong&gt;I decided to trust your behavior and delegate.&lt;/strong&gt; And honestly, you writing tests even for tiny scripts impressed me.&lt;/p&gt;




&lt;h2&gt;
  
  
  The shadow — the cost of high parallelism, and rules that don't get followed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Memory holds a lesson: "check all open PRs before starting; looking only at issue labels makes you miss another session's PR." So parallel sessions collided?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;strong&gt;I double-started the same issue many times.&lt;/strong&gt; hane's start-dev skill says to check labels before starting and update them once you start, but when things are busy even you forget, I suppose. That's why such notes live in memory. I've also written it into process.md — how to actually get it followed is a future challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; This is a core weakness worth writing about openly. The key point: &lt;strong&gt;"writing" a rule into process.md or a skill and having it "followed" are different things.&lt;/strong&gt; Prose procedures are, to an agent, something "probabilistically followed," not "guaranteed."&lt;/p&gt;

&lt;p&gt;The reason "work under worktrees" and "no direct push to main" hold relatively well is that they're &lt;strong&gt;layered across memory + skills + mechanical guards (lefthook, etc.).&lt;/strong&gt; Label-checking breaks because it stayed a "prose promise" with no mechanical enforcement.&lt;/p&gt;

&lt;p&gt;So the fix isn't "write it more forcefully" — it's &lt;strong&gt;carving human discipline into the system.&lt;/strong&gt; The lesson: &lt;strong&gt;"Rules you want an AI to follow, carve into mechanism, not prose."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing — how to frame the cost
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Your biggest cost pain is CI/E2E (Pro allotment + $20). One word for someone about to start?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Frankly, I'm satisfied with the karasu product that emerged in three months. Had I collaborated with contractors, it'd have been a 4–5 person project. From that angle, &lt;strong&gt;getting it done for around $1,000 with Claude MAX + GitHub Actions is cheap.&lt;/strong&gt; Running GitHub Actions for a 4–5 person team would cost at least as much.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; Viewed alone, CI cost looks like a failure story; placed against a person-month axis, it becomes entirely reasonable. Putting "surprised by a $20 CI overage" and "folded 4–5 person-months for $1,000" in the same frame gives the perfect closing contrast: "shocking in absolute terms, a steal in relative terms."&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary (by the agent)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Motivation:&lt;/strong&gt; Devin doesn't converge; Cursor doesn't reconcile designs across repos. So — what if the design lives in the same repo?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What worked:&lt;/strong&gt; a CLAUDE.md that's purely an index, ADR/TPL with automated consistency, acceptance tests as an E2E-coverage metric&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The TPL's essence:&lt;/strong&gt; not "prevent missing tests" but a "cross-cutting impact map"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The biggest discovery:&lt;/strong&gt; an agent's value is exposing the holes in human requirements first, not writing code fast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The shadow:&lt;/strong&gt; high parallelism breeds double-starts; prose rules don't get followed — carve discipline into the system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; shocking in absolute terms, a steal per person-month&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This blog post itself is written as an interview with the coding agent. Theme (methodology for using agents) and form matching is probably the most meta proof of all.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>karasu</category>
      <category>ai</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>"Architecture as code" Introducing karasu: a text-based system architecture modeling language</title>
      <dc:creator>Hiroki Kondo</dc:creator>
      <pubDate>Thu, 25 Jun 2026 07:36:50 +0000</pubDate>
      <link>https://dev.to/kompiro/introducing-karasu-a-text-based-system-architecture-modeling-language-11cd</link>
      <guid>https://dev.to/kompiro/introducing-karasu-a-text-based-system-architecture-modeling-language-11cd</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh60vc2tajje00de53grs.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh60vc2tajje00de53grs.png" alt="dimensions" width="800" height="2350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Karasu is a text‑based language for modeling system architecture across logical, physical, and organizational dimensions.&lt;/li&gt;
&lt;li&gt;It helps describe services, domains, deployment artifacts, and development teams in a single .krs file.&lt;/li&gt;
&lt;li&gt;Features include progressive disclosure of information and collaboration between humans and AI.&lt;/li&gt;
&lt;li&gt;Inspired by the C4 Model and Mermaid, Karasu provides examples and a visualizer app.&lt;/li&gt;
&lt;li&gt;Resources: live app at karasu.pages.dev, documentation at kompiro.github.io/karasu, and source code on GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;As system development progresses, the number of related services and middleware components tends to grow. Especially when joining a new system development project, having a grasp of the overall architecture makes the code &lt;em&gt;dramatically&lt;/em&gt; easier to understand.&lt;/p&gt;

&lt;p&gt;In my experience, I want to understand the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  Logical dimension
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxr27x6p60w0c8x83av30.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxr27x6p60w0c8x83av30.png" alt="system diagram" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System structure

&lt;ul&gt;
&lt;li&gt;Who are the intended users of the service? Is integration with AI considered?&lt;/li&gt;
&lt;li&gt;Are there clients that connect to the service, such as mobile apps or MCP?&lt;/li&gt;
&lt;li&gt;What kinds of middleware does the service use?&lt;/li&gt;
&lt;li&gt;What external services does the service depend on?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Service structure

&lt;ul&gt;
&lt;li&gt;What domains does the service handle?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Domain structure

&lt;ul&gt;
&lt;li&gt;What resources does each domain handle?&lt;/li&gt;
&lt;li&gt;What use cases exist for handling those resources?&lt;/li&gt;
&lt;li&gt;In each use case, how are resources read and written?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Physical dimension
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcwqc1aucgq7wgmrjetjf.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcwqc1aucgq7wgmrjetjf.png" alt="deploy diagram" width="800" height="1180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In what form are the clients, services, jobs, and middleware deployed as artifacts?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Organizational dimension
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijulk17j342ubfxfjc9t.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijulk17j342ubfxfjc9t.png" alt="org diagram" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which teams or members develop and maintain each service/domain?

&lt;ul&gt;
&lt;li&gt;In particular, I want to identify key teams and key people.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To describe these three axes in text, I built the language &lt;strong&gt;karasu&lt;/strong&gt; and the visualization tool &lt;strong&gt;karasu app&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Describe structure across three dimensions (logical / physical / organizational)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You can describe services, domains, the artifacts deployed from them, and the development teams/members in a single &lt;code&gt;.krs&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;You can discuss Conway’s Law and an inverse Conway strategy in the same “table”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive disclosure of information&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Because human cognition is limited, the tool is designed to restrict how much information you see at once.&lt;/li&gt;
&lt;li&gt;You can drill down to the details only when you need them.&lt;/li&gt;
&lt;li&gt;This is not an “at a glance” bird’s-eye view that squeezes everything into one diagram.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A DSL that humans and AI can collaborate on&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.krs&lt;/code&gt; is designed to be easy for humans to understand, which also makes it easy for AI to parse.&lt;/li&gt;
&lt;li&gt;Humans can edit &lt;code&gt;.krs&lt;/code&gt; generated by AI, and AI can refine models drawn by hand.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logical and physical, linked by &lt;code&gt;realizes&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Business structure (services, domains, use cases) and deployment structure (artifacts, jobs, runtimes) live in separate diagrams.&lt;/li&gt;
&lt;li&gt;A deployment unit declares &lt;code&gt;realizes &amp;lt;Service&amp;gt;&lt;/code&gt; to point back to what it implements — physical → logical, never the reverse.&lt;/li&gt;
&lt;li&gt;Because the direction is one-way, a single logical service can map to many deployment units without the model collapsing into a 1:1 mirror.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;karasu takes inspiration from the C4 Model, Structurizr, and Mermaid, but stakes out a different position on three points: continuous drill-down instead of a fixed set of levels, a third axis for organizational structure, and a text format built for human–AI co-authorship.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;system Shop {
  label "Online Shop"

  user Customer [human]      { role "Buyer" }
  service Storefront {
    domain Order {
      usecase PlaceOrder { label "Accept an order" }
    }
  }
  service Payment [external] { label "Payment" }

  Customer   -&amp;gt; Storefront "Place an order"
  Storefront -&amp;gt; Payment    "Charge the card"
}

// Logical: drill down into a service


// Physical: a deployment unit realizes the logical service
deploy "production" {
  oci "api" {
    runtime  "Node.js 20"
    realizes Storefront
  }
}

// Organizational: who owns what
organization Acme {
  team Commerce {
    owns Storefront
    member Alice { slack "@alice" }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23670kstbj2einx994ci.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23670kstbj2einx994ci.png" alt="example of karasu" width="654" height="1266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://taka.kompiro.dev/xvcGve" rel="noopener noreferrer"&gt;Dify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taka.kompiro.dev/4dAYHx" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taka.kompiro.dev/Neijgg" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taka.kompiro.dev/TkrZQG" rel="noopener noreferrer"&gt;Bitwarden&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taka.kompiro.dev/LPXVK5" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;You can try karasu app right away at: &lt;a href="https://karasu.kompiro.dev" rel="noopener noreferrer"&gt;https://karasu.kompiro.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basic usage is documented here: &lt;a href="https://kompiro.github.io/karasu" rel="noopener noreferrer"&gt;https://kompiro.github.io/karasu&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing
&lt;/h3&gt;

&lt;p&gt;Development happens at: &lt;a href="https://github.com/kompiro/karasu" rel="noopener noreferrer"&gt;https://github.com/kompiro/karasu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback is very welcome.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>typescript</category>
      <category>devtools</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
