CLAUDE LABEN
MEMORY — Claude Codeの長時間セッションのメモリリークが一掃されました。MCP stdioサーバのstderrが最大64MB蓄積する問題やLSPドキュメントの開きっぱなしが修正されていますTABLES — 非常に大きなmarkdownテーブルが描画を止める不具合を修正。200行を超えるテーブルは先頭200行と「… N more rows」表示になりますSPEED — deny/askルールを多く抱えたセッションで毎ターン数秒遅くなる問題を修正。ルールマッチャがコンパイルして再利用されますTOOLS — MCPツールが多いprint/SDKセッションでは、ツールプールの組み立てをキャッシュし最大7倍速いラウンドになりましたARTIFACTS — Claude CodeのArtifactsは、セッションの作業をその場で更新される共有Webページに変えます。PR解説やダッシュボードに使えますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。speed: "fast" はエラーになるため、Opus 4.8のfastモードへ移行が必要ですMEMORY — Claude Codeの長時間セッションのメモリリークが一掃されました。MCP stdioサーバのstderrが最大64MB蓄積する問題やLSPドキュメントの開きっぱなしが修正されていますTABLES — 非常に大きなmarkdownテーブルが描画を止める不具合を修正。200行を超えるテーブルは先頭200行と「… N more rows」表示になりますSPEED — deny/askルールを多く抱えたセッションで毎ターン数秒遅くなる問題を修正。ルールマッチャがコンパイルして再利用されますTOOLS — MCPツールが多いprint/SDKセッションでは、ツールプールの組み立てをキャッシュし最大7倍速いラウンドになりましたARTIFACTS — Claude CodeのArtifactsは、セッションの作業をその場で更新される共有Webページに変えます。PR解説やダッシュボードに使えますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。speed: "fast" はエラーになるため、Opus 4.8のfastモードへ移行が必要です
記事一覧/Claude Code
Claude Code/2026-07-16上級

許可ルールを積み上げたセッションが毎ターン重くなる — ルールセットの棚卸しと、安全性を保ったまま数を減らす設計

deny/ask ルールを増やすほど毎ターン遅くなる問題が 2.1.209 で修正されました。ただしルール設計そのものの負債は残ります。棚卸しスクリプト・被覆検出・ターン時間の実測手順と、列挙型から接頭辞型へ移す設計をまとめます。

Claude Code194パーミッションsettings.json2MCP44パフォーマンス3

プレミアム記事

個人開発で回している自動投稿パイプラインの settings.json を開いたら、deny の配列が 140 行を超えていました。

一つひとつは覚えがあります。夜間に走らせて肝を冷やしたコマンドを足し、うっかり読まれたくないパスを足し、新しい MCP サーバを入れるたびに念のための行を足す。半年でこうなりました。

そして、そのセッションはどれも「なんとなく重い」のです。原因が分からないまま、モデルが遅いのだろうと片付けていました。

2.1.209 のリリースノートに、その正体が書いてありました。deny/ask ルールが多いセッションで、毎ターン数秒遅くなる問題が修正された、と。マッチャをコンパイルしてキャッシュするようになったそうです。安全側に倒すつもりで積み上げた設定が、そのまま速度を削っていたことになります。

修正で消えたコストと、手元に残るコスト

まず切り分けておきたいことがあります。2.1.209 で消えたのは実行時の再コンパイルであって、ルールセットの設計負債ではありません。

コストの種類2.1.209 以降誰の責任か
ルール文字列のマッチャ化(毎ターン)キャッシュされ解消Claude Code 側
MCP ツールプールの組み立て(毎ラウンド)キャッシュされ最大7倍速Claude Code 側
ルール数そのもの(照合の母数)変わらず線形に増える私たち
被覆・矛盾したルールの判断ゆれ変わらず残る私たち
接続する MCP サーバの本数変わらず増える私たち

上の2行はアップデートで受け取れます。下の3行は、こちらが片付けないかぎり残ります。

しかも厄介なことに、コンパイルコストが消えたおかげで「重さ」の体感は薄れます。痛みが消えると、負債は静かに増えていきます。今のうちに数えておくのが得だと考えました。

まず数える — ルールセットの棚卸し

推測で削るのは危険なので、機械に数えさせます。settings.json を読んで、ルール数・重複・ツール別の分布を出すスクリプトです。

#!/usr/bin/env python3
"""audit_permissions.py — settings.json のパーミッションルールを棚卸しする。
 
使い方:
    python3 audit_permissions.py ~/.claude/settings.json .claude/settings.json
"""
import json
import re
import sys
from collections import Counter, defaultdict
from pathlib import Path
 
BUCKETS = ("allow", "ask", "deny")
 
# "Bash(rm -rf:*)" → ("Bash", "rm -rf:*") / "Read" → ("Read", None)
RULE_RE = re.compile(r"^(?P<tool>[A-Za-z_][\w-]*)(?:\((?P<arg>.*)\))?$")
 
 
def parse_rule(rule: str):
    m = RULE_RE.match(rule.strip())
    if not m:
        return None, rule.strip()
    return m.group("tool"), m.group("arg")
 
 
def load(path: Path) -> dict:
    if not path.exists():
        print(f"  skip (not found): {path}")
        return {}
    with path.open(encoding="utf-8") as fh:
        return json.load(fh)
 
 
def audit(paths):
    total = Counter()
    by_tool = defaultdict(lambda: defaultdict(list))
    seen = defaultdict(list)  # rule -> [(bucket, file), ...]
 
    for p in paths:
        data = load(Path(p).expanduser())
        perms = data.get("permissions", {})
        for bucket in BUCKETS:
            for rule in perms.get(bucket, []):
                total[bucket] += 1
                tool, arg = parse_rule(rule)
                by_tool[tool][bucket].append(arg)
                seen[rule].append((bucket, str(p)))
 
    print("=== 合計 ===")
    for b in BUCKETS:
        print(f"  {b:5s}: {total[b]:4d}")
    print(f"  total: {sum(total.values())}")
 
    print("\n=== ツール別(多い順) ===")
    rows = sorted(by_tool.items(), key=lambda kv: -sum(len(v) for v in kv[1].values()))
    for tool, buckets in rows:
        counts = " ".join(f"{b}={len(buckets[b])}" for b in BUCKETS if buckets[b])
        print(f"  {tool:28s} {counts}")
 
    print("\n=== 完全重複・バケット衝突 ===")
    dup = 0
    for rule, hits in seen.items():
        if len(hits) < 2:
            continue
        dup += 1
        buckets = {b for b, _ in hits}
        mark = "⚠ 衝突" if len(buckets) > 1 else "重複"
        print(f"  [{mark}] {rule}")
        for b, f in hits:
            print(f"        {b:5s}{f}")
    if dup == 0:
        print("  なし")
    return sum(total.values())
 
 
if __name__ == "__main__":
    args = sys.argv[1:] or ["~/.claude/settings.json", ".claude/settings.json"]
    n = audit(args)
    sys.exit(0 if n else 1)

私の環境で走らせたところ、deny 141・ask 22・allow 63 の計 226 でした。完全重複が 9 件、ユーザー設定とプロジェクト設定でバケットが食い違っている衝突が 2 件。衝突の 2 件は、プロジェクト側で allow に入れたものをユーザー側で deny していたもので、動作としては安全側に倒れていたため気づけていませんでした。

数える前に「たぶん 60 行くらい」と見積もっていたので、桁が違いました。ここが出発点になります。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
自分の settings.json のルール数・重複・被覆を機械的に洗い出す棚卸しスクリプト
ターンあたりのオーバーヘッドを claude -p で測る計測ハーネスと、比較の取り方
列挙型ルールを接頭辞型へ畳み込みつつ、危険な穴を開けない書き換えの手順
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

Claude Code2026-07-16
夜間セッションの常駐メモリが朝には数GB — 蓄積の四つの出どころと、RSS を刻んで切り分ける
夜間に回した Claude Code のプロセスを朝に見ると、常駐メモリが数GBまで膨らんでいました。2.1.209 で塞がれた四つの蓄積源と、自分の構成に残る分を RSS の傾きで切り分ける方法、しきい値で畳む運用までを個人開発の目線で整理します。
Claude Code2026-06-28
ストリーミングを並行で束ねると、ノートPCの CPU が先に音を上げる — 実測値で並行本数を絞る適応スロットルの設計
ストリーミングのCPU使用が軽くなっても、複数セッションを1台で束ねるとホストのCPUが先に飽和します。固定セマフォの限界と、実測CPUに応じて並行本数を上下させる適応ゲートの実装を、動くコードと実測値で解説します。
Claude Code2026-06-27
OAuthトークンが切れた瞬間に無人実行が手詰まりになる — リモートMCPを止めないトークンライフサイクル設計
リモートMCPコネクタはOAuthで認可されますが、アクセストークンは短命です。対話実行ではブラウザで再認可できても、無人のスケジュール実行では誰もダイアログを押せません。期限を自分で持ち、先読みで更新するトークンライフサイクル設計をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →