開発環境
Kamaeスキルに従うアプリケーション crate をローカルで立ち上げる手順である。スキルパッケージ本体の編集は スキルリポジトリの開発 を読む。
日常のチェックは 品質ゲート、フィクスチャの組み立ては テストデータ、CIへの反映は CI セットアップ を参照する。
Kamaeが想定する方法でドメインコードを実装・テストできるワークスペースを整える。型付きドメインモデル、ポートベースのユースケース、コンストラクタ経由のフィクスチャを揃え、レビュアとCIが同じチェックに依存できる状態を目指す。
スキルに従う application crate 向けガイド。スキルパッケージ自体の編集はリポジトリルート DEVELOPMENT.md を参照。
テンプレートからの初回ブートストラップ
Section titled “テンプレートからの初回ブートストラップ”gh skill または npx skills でインストールした場合、リポジトリルートの Cargo.toml、rust-toolchain.toml、.github/workflows/ci.yml、scripts/validate_package.py などは同梱されない。プロジェクトブートストラップには ../assets/templates/ 配下のテンプレートを使う。
最も手早い方法は、同梱スクリプトを使うことである。
python3 path/to/kamae-rs/skills/kamae-rs/scripts/apply_templates.py --target . --ci backendスキル/プラグインリポジトリ:
python3 path/to/kamae-rs/skills/kamae-rs/scripts/apply_templates.py --target . --ci skill-package--force なしでは既存ファイルを上書きしない。既存リポジトリに適用するときは先に --dry-run を使う。
review probe の健全性チェック
Section titled “review probe の健全性チェック”ブートストラップ後、ドメインディレクトリで同梱review probeを実行し、レビュー前に一般的なKamaeスタンス問題を捕捉する:
cargo run -q --manifest-path path/to/kamae-rs/Cargo.toml -p kamae-review-probe -- src/domain/ src/application/review probeは既定では助言(advisory)モードである。出力はpanic、unsafe境界、serde derive、PII用語、rustdocの不足をレビューの手がかりとして扱い、チームが明示的に配線しない限り、失敗を伴うゲートにはしない。
推奨ローカルファイル:
../assets/templates/Cargo.toml->Cargo.tomlまたは既存workspace manifestにマージ../assets/templates/rust-toolchain.toml-> チームがMSRVまたはstable pinを共有するときrust-toolchain.toml../assets/templates/gitignore->.gitignoreまたは既存ファイルにマージ../assets/templates/validate_package.py-> スキル/プラグインリポジトリのみscripts/validate_package.py
コミット前に package.name、workspace members、[workspace.dependencies] を調整する。アプリケーションリポジトリでは単一crateまたは 開発環境 のworkspaceレイアウトから始める。
初回セットアップ
Section titled “初回セットアップ”フォーマットとlintコンポーネント付きでRustをインストール:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shrustup component add rustfmt clippyCargo.toml がまだないプロジェクトでは、先に同梱テンプレートをコピーしてから:
cargo checkcargo testrustc --versionチームがバージョンを共有するときはtoolchainをpin:
cp path/to/kamae-rs/skills/kamae-rs/assets/templates/rust-toolchain.toml .ローカルチェックループ
Section titled “ローカルチェックループ”ブートストラップ後、品質ゲート のベースラインコマンドを実行する。スキル/プラグインリポジトリでは python3 scripts/validate_package.py も実行する。
クレートレイアウト、フェイクポート、テスト層、高速ループとフルpre-pushループの詳細は、本稿の後述セクションを参照する。
ツールチェーン
Section titled “ツールチェーン”フォーマット、lint、ドキュメントcomponent付きRust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shrustup component add rustfmt clippyチームがMSRVまたはstableを共有するときtoolchainをpin:
[toolchain]channel = "1.85.0"components = ["rustfmt", "clippy"]profile = "minimal"domain作業向けoptionalだが有用:
| ツール | 用途 |
|---|---|
| cargo-nextest | 大 workspace での高速 test |
| cargo-watch | domain 編集中の test 再実行 |
| cargo-llvm-cov | 移行中触った module のカバレッジ |
domain crateビルドは速く保つ。遷移やvalue object反復中はworkspace全体より cargo test -p domain-crate を優先。
推奨 crate レイアウト
Section titled “推奨 crate レイアウト”責務を分割し、domainロジックをI/Oとframework型から解放。
my-service/ Cargo.toml # workspace root crates/ domain/ # entities, value objects, transitions, domain errors application/ # use cases, port traits, use-case errors infrastructure/ # SQL/HTTP/queue adapters, outbox, telemetry wiring api/ # Axum/tonic handlers, DTOs, composition root tests/ # optional workspace integration tests単一crateプロジェクトはcrateの代わりにmodule:
src/ domain/ application/ infrastructure/ api/ main.rs # composition rootルール:
domainはsqlx、axum、tonicなどI/O crateに依存しない- handlerと
mainがadapterを配線。ユースケースはport traitのみ(アプリケーション配線) - DTOは所有境界(
api、infrastructure)の近く。domain内に置かない
ベースライン Cargo.toml 依存
Section titled “ベースライン Cargo.toml 依存”既存利用から始める。Kamaeスタイルbootstrap時のcommon pairing:
[dependencies]thiserror = "2"serde = { version = "1", features = ["derive"] }tracing = "0.1"
[dev-dependencies]tokio = { version = "1", features = ["macros", "rt-multi-thread"] }proptest = "1"trybuild = "1"依存があるとき crate-guides/ からcrate guideを読み込む。guideがあるからといって domain にcrateを追加しない。
スキルトピック別 dev-dependencies
Section titled “スキルトピック別 dev-dependencies”| Topic | Typical dev-dependencies | Notes |
|---|---|---|
| Async use cases | tokio, tokio-test | #[tokio::test] で async port をテスト |
| Property tests | proptest, proptest-regressions | プロパティベーステスト |
| Compile-fail state safety | trybuild | テストデータ |
| HTTP boundary tests | axum, tower, http-body-util | fake use case で handler テスト |
| Persistence integration | testcontainers, sqlx (test feature) | 任意。大半 domain test は fake |
| Fake time | time + injected clock trait | wall-clock flakiness 回避 |
integration-test依存はadapterを所有するcrateに。domain には置かない。
不変条件を証明できる最下層でtest。
| 層 | テスト対象 | I/O |
|---|---|---|
| Domain unit | constructors, transitions, domain errors | None |
| Use case | orchestration with fake ports | None |
| Adapter unit | SQL mapping, DTO TryFrom, redaction | Fake or in-memory |
| API/integration | handler -> use case -> adapter | Test DB or container optional |
| Property | input-wide laws | None in the property body |
# Fast loop while editing domain codecargo test -p domain --lib
# Use case tests with fakescargo test -p application --lib
# Full workspace before pushcargo test --all-targets --all-featuresドメイン層とユースケース層のテストにDockerは不要である。PostgreSQLやRedisなどが本当に必要なのは、アダプター層の統合テストに限る。
Fake port とテストフィクスチャ
Section titled “Fake port とテストフィクスチャ”test用composition rootにfakeを注入。本番と同じconstructorでフィクスチャ構築(テストデータ)。
pub struct FakeRequestStore { pub saved: Mutex<Vec<(EnRouteRequest, Vec<TaxiRequestEvent>)>>,}
impl RequestStore for FakeRequestStore { async fn save_assigned( &self, state: &EnRouteRequest, events: &[TaxiRequestEvent], ) -> Result<(), RepositoryError> { self.saved.lock().unwrap().push((state.clone(), events.to_vec())); Ok(()) }}
pub fn assign_driver_use_case() -> AssignDriver<FakeResolver, FakeRequestStore> { AssignDriver::new(FakeResolver::default(), FakeRequestStore::default())}ガイドライン:
tests/support/または#[cfg(test)] mod test_supportでhelper共有- fixtureの
expectのみ。メッセージにfixture不変条件を述べる - 欠けた振る舞いを隠すmega-mockよりportごと1 fake
任意ローカルサービス
Section titled “任意ローカルサービス”アダプター統合テストが実際のインフラを要する場合、チームで共有する推奨手順を1つに決め、文書化する。
docker-compose(シンプル、repoにcheck-in):
services: postgres: image: postgres:16 environment: POSTGRES_PASSWORD: dev POSTGRES_DB: my_service_test ports: - "5432:5432"testcontainers(test内完結):
- composeがないCI parityにgood
- 遅い。
infrastructureintegrationに限定
test前にmigration SQLまたはschemaをload。ローカルdev DBを本番credentialに向けない。
環境と secret
Section titled “環境と secret”- 非secret placeholderの
.env.exampleをcommit。.envはgit外 - domain内ではなくstartupのconfig crate経由でsecret読み取り
- ローカルlog前に PII 保護 ルール
DATABASE_URL=postgres://postgres:dev@localhost:5432/my_service_testRUST_LOG=info,my_service=debugローカルtracingには RUST_LOG + main の tracing-subscriber layerで足りる。domain開発中OpenTelemetry exporterはoptional。
ローカル check ループ
Section titled “ローカル check ループ”品質ゲート と CI セットアップ に合わせる。編集中fast path、PR前full path。
Fast path(触ったcrate):
cargo fmt --allcargo clippy -p domain -p application --all-targets -- -D warningscargo test -p domain -p applicationFull path(pre-push):
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all-targets --all-featuresRUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-featureskamae-rs pluginをvendored/インストールしているプロジェクトは、レビュー依頼前に変更Rustファイルでreview probe:
cargo run -q --manifest-path path/to/kamae-rs/Cargo.toml -p kamae-review-probe -- src/domain/ src/application/probe出力はreview lead。自動失敗ではない。初回ブートストラップは本稿の「テンプレートからの初回ブートストラップ」を参照。
エディタとエージェント
Section titled “エディタとエージェント”rust-analyzer
- マシンが許せば
rust-analyzer.check.commandをclippy - プロジェクトが文書化したときだけ
rust-analyzer.rustfmt.extraArgs
Kamae skill
- domain実装/refactor時Claude/Codexで
kamae-rsskillをload - crate嗜好は kamae-rs リポジトリ の
rules/を参照 - エージェントを最初
Cargo.tomlへ。crate guideとtopicが正しくloadされる
Watch mode(optional):
cargo watch -x 'test -p domain --lib'新 domain module の bootstrap チェックリスト
Section titled “新 domain module の bootstrap チェックリスト”domain/applicationcrate(またはmodule)を作成または特定thiserrordomain errorとvalue-object constructorを追加- ユースケース前にvalid/invalid構築の単体test
- DB schemaではなく1ユースケース形のport trait
- generic port fieldとtest内fake adapterでユースケース実装
- APIまたはinfrastructure境界にDTO
TryFrom mainまたはtest bootstrapのみでユースケース配線- fast check loop。push前full path
- diffに
kamae-rs-review(またはprobe + 関連checklist)
レガシー codebaseでは全体再構成前に 段階的導入 の導入ラダーを登る。
ローカルと CI が異なるとき
Section titled “ローカルと CI が異なるとき”READMEまたは CONTRIBUTING.md に差分を明示:
- CIではtestするがローカルではないfeature flag
- optional Docker-only integration job
- MSRV job vs開発者stable toolchain
- advisory Miri/fuzz job
どの失敗がマージをブロックし、どれがスケジュール実行の助言(advisory)にとどまるのかを、開発者がREADMEや CONTRIBUTING.md で確認できるようにする(CI セットアップ を参照)。
レビューでは、ドメインcrateのインフラ依存、fake portで足りるのに実DB必須のテスト、不変条件を迂回するテストヘルパ、文書化されていないローカル品質ゲート、コミットされた秘密や生PIIログ、ドメインテストのHTTP / DB直結を指摘する。
レビュー観点
Section titled “レビュー観点”シークレットと PII はコミット済み env ファイルから除外されているか — High
Section titled “シークレットと PII はコミット済み env ファイルから除外されているか — High”PII 保護 も照合する。コミットされた .env、例の実認証情報、デバッグのため生PIIをログするよう促すローカルセットアップドキュメントを指摘する。
ドメインコードは I/O 依存がないか — High
Section titled “ドメインコードは I/O 依存がないか — High”チームがKamae型の分割を掲げているのに、domain クレートやモジュールが sqlx、axum、tonic などのインフラクレートに依存している場合は指摘する。
テスト構成はクレート境界と一致しているか — Medium
Section titled “テスト構成はクレート境界と一致しているか — Medium”ユースケース層のフェイクやインフラ層のアダプタではなく、ドメインテストがHTTPサーバやDBプールを直接引き込む場合は指摘する。
ドメインとユースケースのテストは Docker なしで走るか — Medium
Section titled “ドメインとユースケースのテストは Docker なしで走るか — Medium”基本的な遷移やユースケーステストにフェイクポートで足りるのに、ライブDBや外部サービスを要求するワークフローを指摘する。
フィクスチャはコンストラクタ経由で構築されているか — Medium
Section titled “フィクスチャはコンストラクタ経由で構築されているか — Medium”テストデータ も照合する。ドメイン / ユースケーステストでpublicフィールドリテラルや生ORM行により不変条件を迂回するテストヘルパを指摘する。
文書化されたローカルチェックループがあるか — Low
Section titled “文書化されたローカルチェックループがあるか — Low”Kamae慣習を採用しているのに、CI セットアップ と揃った高速パスとフルpre-pushコマンド一覧がないプロジェクトを指摘する。