Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Avatar for mpyw mpyw
September 17, 2026

AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”

旧題: Go のフラットな パッケージに 「ファイル単位の private」を 〜Linter “declscope” を作った話〜

https://zenn.dev/yumemi_inc/articles/go-declscope-file-scoped-private のスライド版です。
AI に書かせました。

Repository: https://github.com/mpyw/declscope

Avatar for mpyw

mpyw

September 17, 2026

More Decks by mpyw

Other Decks in Programming

Transcript

  1. AI が書く Go コードの 品質を劇的に向上させる Linter: “declscope” GO × STATIC

    ANALYSIS × AI フラットなパッケージのまま、内側に境界を引く 旧題: Go のフラットなパッケージに「ファイル単位の private」を ✨ mpyw / Accenture Japan Ltd 2026 01 / 16
  2. THE LANGUAGE Go は、誰が書いても同じようになる言語 かつて 代償は記述量 三項演算子もメタプログラミングも無い 他の言語なら 1 行、Go

    では 5 行 いま 代償だけが消えた 定型を打ち込むコストは AI がほぼゼロに 残るのは読めば意味が一意という性質 素朴さは、AI 時代に評価が反転した特性 02 / 16
  3. WHERE QUALITY COMES FROM では、Go のコード品質は何で決まるのか 細部 書きぶりの技巧 大局 コードベースの整理

    ショートハンドや言語機能の使いこなし。AI に任せて どこに宣言を置き、どこに境界を引くか。AI は勝手に よい部分。 整えない。 整理の道具は package だけ —— それが少し非力 03 / 16
  4. THE GAP Go の可視性は、ほぼ 2 段階 Exported unexported import した全

    package 同じ package の全ファイル package api package database ScanUser package の壁を越える。 大文字始まりで書くだけ。 unexported ≠ このファイルだけ 届く この段階は 存在しない package database package database order_repository.go order_repository.go scanOrder scanOrder db.ScanUser() ファイル単位 素通り ✕ user_repository.go user_repository.go scanUser scanUser normalizeEmail normalizeEmail ファイルの壁は越え放題。 コンパイラは何も言わない。 止めたい ファイル単位の private は、 Go には無い。 04 / 16
  5. INVISIBLE OWNERSHIP 暗黙の所有権は、コードから見えない package database user_repository.go order_repository.go func scanUser(...) {

    ... } func scanOrder(...) { func normalizeEmail(...) { ... } コンパイルは通る email = normalizeEmail(email) } 「この helper は、このファイルのもの」—— コンパイラは知らない 05 / 16
  6. AGENTIC CODING AI は規約を破るというより、 見える API を使う 規約を書く CLAUDE.md コメント

    レビュー文化 AI が見るもの → 見える宣言 コメントの規約 一定確率で読む → 負債も高速化 生成が速いぶん、 曖昧な境界も速く崩れる 必ず見える 自然言語の規約は効く。でも、守られるかどうかは確率的 06 / 16
  7. TRADE-OFF だからといって、package を割れば 終わりでもない 単一 フラットに保つ 依存は素直。ただし package 内の全宣言が互いに見える。 複数

    細かく分ける 循環参照 の階層 リファクタリングで 境界を変更するコスト internal/ 欲しいのは package 分割ではなく、その内側にある軽い境界 07 / 16
  8. WHAT DECLSCOPE GUARDS declscope が守るのは、2 種類の境界 boundary qualify この namespace

    から あの namespace のものに 触ってよいか? シンボルに namespace を含めて 識別性を確保しているか? orderRepository → normalizeEmail in userRepository 既定で ON boundary は利用関係、qualify は名前と置き場所を検査する。 B scan → 誰の? scanUser → user のもの 既定は OFF・ON 推奨 Q 08 / 16
  9. ONLY TWO CONCEPTS 覚えることは 2 つだけ 01 ファイル名が namespace user_repository.go

    ↓ userRepository 02 scope は 2 種類 private shared 自分の namespace package 内のどこでも public は Go の Exported がすでに担当。 09 / 16
  10. BOUNDARY RULE boundary 違反への答えは、必ず 2 つ A B 境界を守る 使用箇所や宣言を同一

    namespace に移す。 move usage move declaration email.go OR 共有を宣言する //declscope:shared func normalizeEmail(s string) string に移し、共有物だという判断をソースへ残す 10 / 16
  11. EXPLICITLY NAMED NAMESPACE 複数ファイルで 1 つの namespace に まとめても OK

    namespace: statement //declscope:namespace statement package database func (s *Statement) Where(...) { ... } statement.go query.go type Statement func (*Statement) wheres []string Where(...) args []any 物理ファイルを出発点にしつつ、実際の関心範囲へ合わせられる。 11 / 16
  12. QUALIFY RULE は、シンボル名のどこかに namespace が含まれることを要求する デフォルトではプレフィクスを提案するが、そのまま従う必要はない。直す場所は 2 つある。 qualify A.

    名前のほうを直す B. namespace のほうを直す scanUser //declscope:namespace user ↓ namespace をプレフィクスに ↓ 置き場所のほうを宣言 userRepositoryScanUser scanUser ✓ これが自動修正の提案。でも、名前が不自然。 すでに user を含んでいる。名前は変えなくてよい。 問われているのは、その名前と置き場所が噛み合っているか 12 / 16
  13. CASE STUDY: SPF13/COBRA 最も古いファイルだけ、リネームを忘れていた ほかの completion generators genZshComp genFishComp genPowerShellComp

    genBashComp // V2 どれも、自分の shell 名を名乗っている。 古い bash_completions.go gen writeFlag writeCommands → → → genBashCommands writeBashFlag writeBashCommands Bash の名前がなかった。リネームで namespace を明示。 実在 OSS でも、フラットパッケージの地雷を検出できた spf13/cobra: 14 ファイル / 6,138 行、開始時 boundary 35 / qualify 119 → 最終 0 / 0 13 / 16
  14. DURABLE INTENT AI 時代に必要なのは、判断を記録すること 👤 人間 診断 何の境界を越えたか → source

    code //declscope:shared //declscope:namespace user 診断・ディレクティブ・導入 skill directive 何を共有してよいか → 🤖 次の agent skill 安全な導入順序 14 / 16
  15. TAKEAWAYS フラットさを保ったまま、 内側の境界を検査する ✓ Go にはファイル単位の private がない ✓ 暗黙の所有は、人にも

    AI にも見えにくい ✓ declscope は越境を決定論的に検査する ✓ 答えは「守る」か「共有を宣言する」 ✓ directive が設計判断の引き継ぎになる github.com/mpyw/declscope 使ってみた感想・Issue、お待ちしています。 15 / 16