# 非機能要件定義書

## 概要

本ドキュメントは、clojure-lsp（Clojure/ClojureScript向けLanguage Server Protocol実装）プロジェクトの非機能要件を定義するものである。clojure-lspは、エディタやIDEにコード補完、定義ジャンプ、リファクタリング等の機能を提供する言語サーバーであり、以下の非機能要件が実装されている。

## 性能要件

### レスポンスタイム

| 処理種別 | 目標値 | 備考 |
| --- | --- | --- |
| LSPリクエスト応答（同期） | 即時応答 | `p/thread`による非同期処理で応答性確保 |
| 変更分析待機 | 最大60秒 | `wait-for-changes`にて1分のタイムアウト設定 |
| HTTP接続タイムアウト | 1秒 | `default-connect-timeout-ms = 1000` |
| HTTP読み取りタイムアウト | 30秒 | `default-read-timeout-ms = 30000` |
| 診断公開デバウンス | 25ms | `diagnostics-debounce-ms = 25` |
| 変更検出デバウンス | 50ms | `change-debounce-ms = 50` |
| ファイル監視デバウンス | 1000ms | `watched-files-debounce-ms = 1000` |

### スループット

| 項目 | 目標値 | 備考 |
| --- | --- | --- |
| 並列解析バッチサイズ | 120ファイル | `clj-kondo-analysis-batch-size = 120` |
| 非同期チャネルバッファ | 1 | 変更・診断・監視ファイル用チャネル |
| ログバッファサイズ | 20エントリ | `sliding-buffer 20` |

### メモリ管理

| 項目 | 設定値 | 備考 |
| --- | --- | --- |
| 最大ヒープサイズ（実行時） | 2GB | `-Xmx2g`（run/nativeエイリアス） |
| 手動GC実行 | 適宜 | 大規模キャッシュ書き込み前後に`System/gc`を実行 |
| キャッシュフラッシュ最適化 | あり | `no-flush-output-stream`による書き込み最適化 |

## 可用性要件

| 項目 | 目標値 | 備考 |
| --- | --- | --- |
| 稼働率 | 言語サーバーとして常時稼働 | エディタ起動中は継続動作 |
| 計画停止時間 | なし | ユーザー操作による停止のみ |
| 障害復旧時間（RTO） | 即時（再起動） | サーバー再起動により即座に復旧 |
| 目標復旧時点（RPO） | 0 | 永続化データはキャッシュのみ |
| 親プロセス監視 | あり | `liveness-probe`によるエディタプロセス監視 |
| 未キャッチ例外処理 | あり | `timbre/handle-uncaught-jvm-exceptions!` |

## セキュリティ要件

### データ保護

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| 設定ファイル読み込み | EDN形式の安全なパース | `edn/read-string`使用 |
| ファイルパス検証 | 正規化処理 | `normalize-file`、`uri->canonical-path` |
| 外部URL検証 | URL形式チェック | `valid-url?`関数で検証 |
| 機密情報の分離 | 環境変数参照 | `XDG_CONFIG_HOME`、`JAVA_HOME`等 |

### 通信セキュリティ

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| HTTPS通信 | SSL対応 | `HttpsURLConnection`使用 |
| 外部リソースアクセス | タイムアウト設定 | 接続1秒、読み取り30秒 |

### 入力検証

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| URI正規化 | クライアント入力の正規化 | `normalize-uri-from-client` |
| パス無視設定 | 正規表現パターンマッチ | `paths-ignore-regex`設定 |
| 設定値バリデーション | Spec準拠 | `conform-or-log`によるバリデーション |

## 拡張性要件

### プラグイン・拡張機能

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| カスタムLinter | SCI（Small Clojure Interpreter）統合 | `org.babashka/sci`依存 |
| クラスパス設定拡張 | `classpath-config-paths` | JAR内設定ファイル読み込み |
| プロジェクト仕様拡張 | `project-specs`設定 | ビルドツール自動検出 |
| スタブ生成 | 外部ライブラリ用スタブ | `stubs`設定 |
| 追加スニペット | カスタムスニペット | `additional-snippets`設定 |

### 設定の階層化

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| グローバル設定 | `~/.config/clojure-lsp/config.edn` | XDG準拠 |
| プロジェクト設定 | `.lsp/config.edn` | プロジェクトルート |
| クライアント設定 | `initialization-options` | エディタから渡される設定 |
| 設定マージ | `deep-merge` | 階層的マージ処理 |

### モジュール構成

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| コアライブラリ分離 | `clojure-lsp/lib` | 再利用可能なコアロジック |
| CLI分離 | `clojure-lsp/cli` | コマンドライン実行用 |
| テストヘルパー分離 | `clojure-lsp/test-helper` | テスト支援ユーティリティ |

## 保守性要件

### ロギング

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| ロギングフレームワーク | Timbre | `com.taoensso/timbre` |
| ログ出力先 | ファイル | `/tmp/clojure-lsp.*.out`（デフォルト） |
| ログレベル | info/warn/error/debug | 4段階 |
| 処理時間計測 | `logging-task`マクロ | 処理時間の自動記録 |
| 構造化ログ | コンテキスト付加 | クライアント情報、プロジェクト情報等 |

### トレーサビリティ

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| OpenTelemetry対応 | OTLP出力 | `opentelemetry-sdk`統合 |
| トレースレベル設定 | `$/setTrace` | LSPプロトコル準拠 |
| リクエストID | log-id | UUIDによる識別 |

### デバッグ支援

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| nREPL統合 | 開発環境用 | `cider/cider-nrepl`対応 |
| サーバー情報取得 | `clojure/serverInfo/raw` | 内部状態の取得 |
| カーソル情報取得 | `clojure/cursorInfo/raw` | 解析情報の取得 |
| プロファイラ対応 | clj-async-profiler | 性能分析用 |
| メモリ測定 | clj-memory-meter | メモリ使用量分析 |

## 運用・監視要件

### キャッシュ管理

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| ローカルキャッシュ | `.lsp/.cache/` | プロジェクト毎 |
| グローバルキャッシュ | `~/.cache/clojure-lsp/` | XDG準拠 |
| キャッシュ形式 | Transit JSON | 高速シリアライゼーション |
| キャッシュバージョン管理 | version = 13 | 互換性チェック |
| 古いキャッシュ削除 | 自動 | SQLite/Datalevin形式の自動削除 |
| チェックサム管理 | MD5ハッシュ | 変更検出用 |

### 起動時処理

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| 進捗通知 | work-done-progress | LSP準拠の進捗報告 |
| 高速起動モード | キャッシュ活用 | 設定・プロジェクトハッシュによる判定 |
| 遅延起動モード | フル解析 | 依存関係変更時 |
| 起動後タスク | 非同期実行 | ClojureDocs更新、JDKソース解析等 |

### 設定変更対応

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| 動的設定更新 | `didChangeConfiguration` | LSP準拠 |
| 設定ハッシュ検証 | MD5 | 変更検出 |
| kondo設定ハッシュ | `config-hash` | 静的解析設定の変更検出 |

### 外部リソース連携

| 項目 | 実装内容 | 備考 |
| --- | --- | --- |
| ClojureDocs統合 | EDNキャッシュ | GitHub経由で取得 |
| JDKソース解析 | 自動ダウンロード/ローカル検出 | Javaクラス定義取得 |
| clj-kondo統合 | 静的解析エンジン | 診断・解析の基盤 |
| CFR統合 | Javaデコンパイラ | クラスファイル解析 |

## 備考

### 技術スタック

- **言語**: Clojure 1.12.4
- **ビルドツール**: tools.deps (deps.edn)
- **ネイティブビルド**: GraalVM Native Image対応
- **依存関係管理**: Maven/Clojars
- **LSPフレームワーク**: lsp4clj、jsonrpc4clj

### 主要な依存ライブラリ

| ライブラリ | 用途 |
| --- | --- |
| clj-kondo | 静的解析・リンター |
| rewrite-clj | ソースコード操作 |
| cljfmt | コードフォーマット |
| core.async | 非同期処理 |
| promesa | Promise/Future処理 |
| timbre | ロギング |
| transit-clj | シリアライゼーション |
| babashka/fs | ファイルシステム操作 |

### ネイティブビルド最適化

| 項目 | 設定 |
| --- | --- |
| AOTコンパイル | `borkdude.dynaload.aot=true` |
| 直接リンク | `clojure.compiler.direct-linking=true` |
| Specマクロスキップ | `clojure.spec.skip-macros=true` |
| GraalVM最適化 | `graal-build-time`ライブラリ |
