{"slug": "from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for", "title": "From requests to mechanisms: a week of risk-tiered review and a gh wrapper for agent PRs (karasu weekly)", "summary": "A developer building karasu, a C4-inspired text modeling language for system architecture, shipped risk-tiered code review in the project's October 25–31 weekly update, classifying each pull request into one of four tiers by the paths it touches and requiring a local review record in the PR body for every tier except High. Of 76 PRs closed that week, 70 merged (92%), and 10 Low-tier PRs were auto-merged without reading the diff, 9 of them ADR-only. The developer also trimmed the always-read development guide from 46 KB to 14,876 bytes, moving the rest into topic files under docs/process/, and flagged 4 High PRs that CodeRabbit never reviewed for follow-up.", "body_md": "[karasu](https://github.com/kompiro/karasu) is a text modeling language for system architecture, inspired by the C4 model.\n\nYou describe your system in `.krs` files and karasu draws the views: system, deployment, and team structure.\n\nI haven't written its code by hand; everything goes through Claude Code.\n\nThis is the fourth weekly update.\n\nIt covers changes merged from October 25 to 31.\n\nThis time I start with what I learned building with agents, then go through what shipped.\n\n**This week in numbers:** 70 PRs merged (12 of them Dependabot) and 18 decisions recorded as ADRs.\n\n15 of the ADRs came in ADR-only PRs, and 3 were added inside implementation PRs.\n\nOn 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.\n\n**Risk tiers that set how deep a review goes are now running.**\n\nLast week I wrote that the design was merged and the implementation was still to come; it landed on October 27.\n\nEach PR falls into one of four tiers by the paths it touches.\n\nEvery tier except High puts a local review record in the PR body.\n\nIt's a table of who reviewed and, for each finding, whether it was fixed or declined.\n\nA required check confirms the record is for the PR's latest commit.\n\nThis week 76 PRs were closed and 70 of them merged (a 92% merge rate).\n\nOf the 50 merged with a tier label, 18 were High, 10 Design, 12 Medium, and 10 Low.\n\nI merged the 10 Low PRs without reading the diff, so the auto-merge rate is 20%.\n\n9 of the 10 were ADR PRs, and the other was the monthly review of test perspectives.\n\n9 were merged within 3 minutes of leaving draft.\n\nThe 22 Medium and Low PRs were merged without going through CodeRabbit.\n\nHigh is common because much of this week's work touched the review and process machinery itself.\n\nChanges to that machinery are set to land in High.\n\nIt'll take a few more weeks of counting to see how the tiers split in everyday development.\n\nWhile counting, I found 4 High PRs that CodeRabbit never reviewed.\n\nI haven't checked yet whether they slipped through or were left out for a reason.\n\nI'll look into it before the next update.\n\n**Over the past week I came across several talks and posts on not reading code** (all in Japanese).\n\nI never kept reading all the code of the systems I build at work.\n\nEven in reviews, I don't read much of the surrounding code.\n\nSince I started using AI, I have it check the surrounding situation while I read the parts that concern me in depth.\n\nThe parts that don't concern me, I now skim.\n\nI think I can do that because I trust AI about as much as a capable contractor.\n\nThe trust I mean is close to Minodriven's \"using it without caring about its insides.\"\n\nBut what I want to get right is less the code itself than the ground the code is written on.\n\nEven a capable contractor, not knowing the team's agreements and not following its steps, writes code full of places that concern me.\n\nAgents are the same.\n\nIf the material to work without hesitation arrives before writing starts, and the steps are followed while writing, I should be able to read less.\n\nIn karasu, I set up those two like this.\n\n**Before writing: leave the agent less room to get lost.**\n\nIn karasu, a large change merges a design document first and is implemented after.\n\nThis week's risk tiers (#3358 → #3365) and the `docs/process.md` split described in this section (#3394 → #3402) both went in that order.\n\nPast decisions are recorded as ADRs, and a step to check them before designing is in the skills.\n\nOn top of that, I cut down how much has to be read.\n\n`docs/process.md` is the development guide every session reads in full first.\n\nIt had grown to 46 KB.\n\nWhen all of it is read every time, the step needed right now gets buried in the others.\n\nSo I kept only the flow that's always needed, at 14,876 bytes, and moved the rest into topic files under `docs/process/`.\n\nThe guide has an index that says when to read each file.\n\nFor example, the review tiers and how to write the record are read in the step just before a PR leaves draft.\n\nI measured how far this read-it-when-needed approach (Progressive Disclosure) reaches current models in [a September post](https://fukurou.kompiro.dev/en/progressive-disclosure/).\n\nThen, path-scoped rules that load when a file is opened almost never fired, while steps written into skills got through.\n\nThis split doesn't rely on loading on file open either.\n\nThe always-read guide names which file to read at which step.\n\n**While writing: move \"requests\" into mechanisms.**\n\nI had shrunk `docs/process.md` to 12.7 KB once before.\n\nIt had grown back to 46 KB.\n\nTidying by hand was undone as steps were added.\n\nThis time I added `pnpm lint:process-index`, which checks the index-to-file mapping, the links, and the guide's size in lefthook and CI.\n\nLast week I wrote that a check refusing `gh pr ready` before the local review was in a PR. That's merged too.\n\nThe first version was a Claude Code hook that inspected the text of the command about to run.\n\nBut each CodeRabbit review found another way around it: `gh` after a heredoc, `gh` behind `env -u` or `timeout -s`, `gh` through `eval` or `xargs`.\n\nThe command text can't tell you what will finally run.\n\nAfter 20 CodeRabbit reviews, it was rebuilt as a `gh` wrapper placed first on the session's PATH, deciding from the arguments `gh` actually receives.\n\nWhat wasn't followed when it was written in the guide, I'm moving into lint, the `gh` wrapper, and required checks.\n\nThat's Watanabe's move from \"request\" to mechanical check.\n\nLow's auto-merge sits on top of these two.\n\nI'll keep counting the merge rate and the auto-merge rate in the coming weeks.\n\nI also plan to track whether bugs later turn up in PRs merged without reading.\n\nI'll write about \"ground that lets me read less\" in a separate post.\n\nThe two demo videos in last week's update were recorded by an agent.\n\nThis week added the skill behind them (`demo-video`) and `pnpm demo-video:record <scenario> --lang en|ja`.\n\nIt works like this:\n\n`karasu serve`), or Visual Studio Code with the extension, on an Xvfb virtual display.\nCaptions and title cards are kept per language, so one scenario produces both an English and a Japanese video.\n\nVisual Studio Code is driven over CDP (Chrome DevTools Protocol).\n\nExTester, a UI testing tool for Visual Studio Code extensions, isn't used, because its ChromeDriver doesn't run in the arm64 devcontainer.\n\n**Once the video is made, the agent looks at it.**\n\nThe agent can open images with Read, but not videos.\n\nSo the recording is cut into a frame every 3 seconds and tiled into one image (a contact sheet), which the agent opens with Read.\n\nThe skill's end state says: don't report \"done\" without having looked at what's in the video.\n\nBelow is last week's `serve-import` video (71 seconds), cut every 3 seconds.\n\nThe cards are blue up to the first frame of the second row and green in the second frame.\n\nThe code panel at the top right of that same frame shows the diff that changed the colors in `theme.krs.style`.\n\nA single frame with the green cards only tells you the cards are green.\n\nLaid side by side, the frames show the change: the style sheet was saved and the view was redrawn.\n\nThe caption text, and the flow from the Share dialog to the public app opening, can also be read from this one image.\n\nThe skill also has a table of pitfalls hit while recording.\n\nIt 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\".\n\nNone of these show up in an exit code or a log; they show up only on screen.\n\nThe save prompt appears when Visual Studio Code closes.\n\nA screenshot taken just before closing wouldn't catch it.\n\n**I brought the same practice to fukurou.**\n\nIn the repository where I write this update, I added ffmpeg to the devcontainer and rewrote the weekly-update steps.\n\nUntil then, the session couldn't see inside the videos, so I checked that the text matched them myself.\n\nNow the session builds the contact sheet, opens it, and checks for itself.\n\nThe image above was made with those steps.\n\nLooking back, the only reason it couldn't check before was that ffmpeg wasn't installed.\n\nI've been writing \"the agent looks at the video,\" but what it actually opens is one still image.\n\n\"Looking\" here means reading time folded into a single image.\n\nEven so, it can read changes over the course of a video that a single screenshot can't show.\n\nReading a screen recording of a bug the same way might help reproduce it or guess at the cause.\n\nBut I don't yet have a karasu bug that was found or fixed from a video.\n\nThe next time a screen-related bug comes in, I'll start by handing the recording to the agent.\n\nOn October 25 the monthly release train left for the first time.\n\nOn the last Sunday of each month, it ships whatever is unreleased.\n\nThat morning, a branch with the version bumps and a tracking Issue open automatically.\n\nAll I do is open the PR from the Issue's link, read the CHANGELOG, and merge.\n\n| Package | From | To | \n|---|---|---|\n| `karasu` (CLI) | 0.9.0 | 0.10.0 | \n| `@karasu-tools/core` | 0.4.0 | 0.4.1 | \n| `karasu-vscode` (Visual Studio Code extension) | 0.4.0 | 0.5.0 | \n| `karasu-skills` | 0.2.0 | 0.2.1 | \n\nIt ships 16 pending changesets.\n\nThe first train ran without stopping, all the way to npm and the Visual Studio Code Marketplace.\n\nIt was the first time the Marketplace publish rode the train.\n\nBoth highlights from last week (import resolution in `karasu serve`, and the Visual Studio Code preview running the app's viewer) arrived on this train.\n\nThe `.krs` language is unchanged.\n\nOne change in `.krs.style`, though: a stray `-` or non-ASCII character that isn't part of any name used to be dropped silently.\n\nNow it's an error.\n\nLines you thought were taking effect but weren't will now show up.\n\n**The Visual Studio Code extension also gets a weekly prerelease.**\n\nWith only a monthly train, a change merged to main can take up to a month to reach the extension.\n\nSo every Wednesday the extension is built from the tip of main and published to the Marketplace prerelease channel.\n\nThe version carries the date: `<stable major>.<minor>.<YYYYMMDDNN>`.\n\nA week whose contents match the previous version is skipped.\n\n\"The contents match\" means every file in the `.vsix` is the same, except for the version number in `package.json`.\n\nI checked beforehand that this can be decided.\n\nI compared the Marketplace 0.5.0 `.vsix` with one built locally from the same commit, and every file matched except `THIRD_PARTY_NOTICES.md`.\n\nThat one file differs only in the platform of a bundled binary (linux-arm64 locally, linux-x64 on CI).\n\nTwo CI builds should match.\n\nTo use it, switch to the prerelease version on the extension's page in the Extensions view.\n\nThe first one is due on Wednesday, November 4.\n\n**Edge labels no longer sit on frame borders.**\n\nDrill-down and group borders are now obstacles for labels.\n\nAcross four models and `examples/en` (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.\n\nIn exchange, labels omitted under `auto` went up from 1,745 to 1,784.\n\n**Edges no longer cut through cards when a route exists.**\n\nThese are edges between cards in the same row.\n\nThe cause wasn't the route: all five candidate spots where an edge leaves the card were taken.\n\nAs a last resort, it now searches the whole side of the card for a spot.\n\nEdges cutting through a card went from 4 to 1.\n\n**Style diagnostics and rendering agree now.**\n\nThe valid ranges for `.krs.style` values were written in three places, and they disagreed.\n\nA diagnostic would say a value was ignored while the value got clamped or drawn anyway.\n\nThe ranges now live only in the schema, and a declaration a diagnostic rejects isn't used for rendering either.\n\nSo rendering changes too.\n\nAn out-of-range `label-position` is dropped instead of clamped.\n\nA non-zero length without a unit, a wrong unit, a bad hex color, or a color name with the wrong case (`White`) isn't drawn.\n\nAn empty value like `color: ;` makes `karasu render` fail.\n\nThis ships on the next train (November 29).\n\n`karasu serve` returned what a symlink pointed to.\n\nSay the served directory held a symlink pointing outside it (like `notes.krs -> ~/.ssh/id_rsa`).\n\nThen `/api/file/:name` returned the contents of the link's target.\n\nThis is in the released 0.10.0.\n\nPaths are now resolved to the real file, and nothing outside the served directory is returned.\n\n`/api/watch` also stopped sending `Access-Control-Allow-Origin: *`.\n\nThe fix ships on the next train.\n\nUntil then, it's safer not to run `karasu serve` in a directory with symlinks that point outside it.\n\n**Smaller changes.**\n\n`analyze()` wrote a cycle flag into the model it was given, so the same model rendered differently before and after `analyze()`. Cycles are now computed when the model is built, and `analyze()` only reads.\n\nPackage 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 `svg-renderer.ts` (2,965 lines), `layout.ts` (1,719 lines), and `view-extract.ts` (2,042 lines) has started.\n\nGitHub Actions versions are now pinned with `actions.lock` (GA on October 28). It also pins actions that workflows use indirectly.\n\n`A -> B` and `B -> A`) 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.`Host` header.", "url": "https://wpnews.pro/news/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for", "canonical_source": "https://dev.to/kompiro/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for-agent-prs-karasu-36d0", "published_at": "2026-11-01 00:13:52+00:00", "updated_at": "2026-11-01 00:22:09.505009+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools"], "entities": ["karasu", "Claude Code", "CodeRabbit", "GitHub", "Visual Studio Code", "kompiro"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for", "markdown": "https://wpnews.pro/news/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for.md", "text": "https://wpnews.pro/news/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for.txt", "jsonld": "https://wpnews.pro/news/from-requests-to-mechanisms-a-week-of-risk-tiered-review-and-a-gh-wrapper-for.jsonld"}}