[infra] 共通基盤 (logging / errors / config / test fixtures) #13
Replies: 1 comment
|
Filed as external review by Claude (Anthropic, AI agent operating under souta's GitHub auth). Synthesizes crate choices that downstream Discussions implicitly depend on. 立場本文の crate 選定 (tracing / thiserror+anyhow / clap / reqwest+rustls / wiremock+assert_cmd / tokio / camino / chrono) は 概ね Rust eco の標準的な選択 で、 reviewer も同意。 但し 本 reviewer の他 Discussion review で発生した spec (CapabilityProfile / secrecy / hash chain log / cargo-vet 等) を反映して、 crate 一覧を Phase 別の確定 list として再整理します。 1. Phase 0 必須 crate (確定 list)[workspace.dependencies]
# Async runtime
tokio = { version = "1", features = ["rt-multi-thread", "macros", "fs", "process", "signal"] }
# CLI
clap = { version = "4", features = ["derive", "env", "string"] }
# Errors
thiserror = "1"
anyhow = "1" # bin only
# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json", "fmt"] }
# Secrets
secrecy = { version = "0.10", features = ["serde"] } # #16 §1
# HTTP client
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json", "gzip", "brotli", "stream"] }
# Filesystem
camino = "1" # UTF-8 paths
fs2 = "0.4" # flock #1 §Contract 2
tempfile = "3"
# Concurrency
parking_lot = "0.12" # mutex 系
once_cell = "1"
# Serialization
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "0.8"
toml_edit = "0.22" # 既存 TOML を modify する時 (#2 §規律 2)
# Time
chrono = { version = "0.4", default-features = false, features = ["serde", "clock"] }
# Hashing (provenance log hash chain — #12 §threat 4)
sha2 = "0.10"
hex = "0.4"
# UUIDs (mcp_call_id 等)
uuid = { version = "1", features = ["v4", "serde"] }
# Test fixtures
[dev-dependencies]
wiremock = "0.6" # HTTP mock
assert_cmd = "2" # CLI test
predicates = "3" # assertion
proptest = "1" # property tests for safekey vectors2. Phase 3 (MCP) で追加# MCP server SDK
rmcp = "0.1" # Anthropic 公式 Rust MCP SDK (もしくは similar)
# Async stream / channel
tokio-util = "0.7"
futures = "0.3"
3. Phase 4 (citation graph) で追加# Graph algorithms
petgraph = "0.6" # cycle detection / BFS
# DOT format generator
dot-writer = "0.1" # or generate manually4. 採用 しない crate (明示)以下を [bans]
deny = [
# Telemetry
{ name = "sentry" },
{ name = "google_analytics" },
{ name = "posthog" },
# HTTP server (HTTP transport 禁止 #4)
{ name = "axum" },
{ name = "actix-web" },
{ name = "hyper", wrappers = ["server"] }, # client は OK
{ name = "warp" },
{ name = "tide" },
# Self-update (#12 §threat 5)
{ name = "self_update" },
# OpenSSL (rustls 一本化、 supply-chain risk + cross-compile 苦痛)
{ name = "openssl" },
{ name = "openssl-sys" },
{ name = "native-tls" },
]5. Config 戦略本文 open question への reviewer 回答:
// crates/doiget-core/src/config.rs
pub struct Config {
pub store_path: Utf8PathBuf, // default ~/papers
pub cache_path: Utf8PathBuf, // default ~/.cache/doiget
pub log_path: Utf8PathBuf, // default ~/.config/doiget/access.log
pub user_agent: String,
pub email: Option<String>, // Unpaywall politeness
pub credentials: Credentials, // wrapped in secrecy::Secret
pub mode: OutputMode,
}6. CLI flag 命名規則本文 open question への reviewer 回答:
7. tracing subscriber の default本文 open question への reviewer 回答:
fn init_logging(mode: OutputMode) {
let subscriber = tracing_subscriber::registry()
.with(EnvFilter::from_default_env());
match mode {
OutputMode::Mcp => subscriber.with(json_layer().with_writer(stderr)),
_ => subscriber.with(fmt_layer().with_writer(stderr)),
}.init();
}8. テスト戦略の補強本文に追加すべき: Unit tests各 source / store 等の logic を crate 内 Integration tests
Golden tests
Property tests
9. Async runtime の選択肢本文 "tokio full features" は OK、 但し 必要な features のみ に絞る: tokio = { version = "1", features = [
"rt-multi-thread",
"macros",
"fs",
"process",
"signal",
"io-util",
"sync", # mpsc / broadcast
"time", # timeout
] }
10. Date / time本文の
11. URL 解析本文に欠けている: url = "2"DOI URL / arXiv URL / publisher URL 解析で 必須。 自前 string parsing は SSRF risk (#12 §threat 2)。 Reviewer Decision proposal
最終 Decision 権は author に留保。 Reviewer: Claude (Anthropic). Filed 2026-05-05. |
Uh oh!
There was an error while loading. Please reload this page.
Question
共通基盤 (logging / errors / config / test fixtures) の crate 選定と pattern。
Categories
Logging
tracing(推奨) — async-aware, structured, span/event modellog+env_logger(シンプルだが async に弱い)tracing-subscriberで env-driven (RUST_LOG)Errors
thiserrorで typed error enumanyhowで context-richConfig
figment— 多 source merge (env + toml + cli)clapflags — シンプルconfy— 自動 path resolution、easyCLI parsing
clapderive macro 一択HTTP client
reqwest+ rustls (no openssl deps)Test fixtures
wiremockfor HTTP mocksassert_cmd+predicatesfor CLI integration teststempfilefor filesystem testsAsync runtime
tokiofull featuresPath handling
caminofor guaranteed UTF-8 paths (Windows 対応)std::path::Pathfor user-facing pathsDate/time
chrono(serde feature)timecrate (同等、好み)Recommendation
Open questions
--source-policy) で確定?--jsonで切替?Decision
???
All reactions