RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).
日本語の概要は準備中です。原文の説明を表示しています。
Reserved-field rules and field-number lookup for evolving AppSettings, plus the Rust/Kotlin diagnostics wire contract. Use before assigning or removing a proto field. DataStore mapping: protobuf-datastore.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
AppSettings is serialized as protobuf bytes and persisted on disk via Jetpack DataStore. When the app updates, new code must read bytes written by every older version. A field-number collision silently corrupts data -- the user loses their configuration with no error and no recovery path.
The diagnostics engine adds a second dimension: Kotlin and Rust exchange JSON wire messages whose schemas must stay in lockstep. A field mismatch causes silent data loss or deserialization failures at runtime.
Schema: core/data/model/src/main/proto/app_settings.proto
Never trust a cached reserved-number list or highest-field-number in this skill, in a prior PR, or from memory -- both grow with every schema change and a stale number is exactly the silent-corruption risk this skill exists to prevent. Before assigning any new field number, run both of these against the live schema:
grep -n reserved core/data/model/src/main/proto/app_settings.proto
grep -oE '= [0-9]+;' core/data/model/src/main/proto/app_settings.proto | grep -oE '[0-9]+' | sort -n | tail -1
The first command prints every reserved block (there may be more than one, each with a numbers line and a names line); the second prints the highest field number currently declared anywhere in the file. Assign the next number strictly above that highest number, and confirm it does not fall inside any reserved range first.
Never reuse a field number. Proto3 identifies fields by number. If
field 15 was desync_method and you assign 15 to something new, existing
persisted bytes silently decode as the wrong field.
Reserve removed fields. Add both the number AND name to reserved.
This makes protoc reject future reuse at compile time.
Use the next available number. Do not fill gaps from past removals.
Set defaults in AppSettingsSerializer. Every new field needs a default
in AppSettingsSerializer.defaultValue (core/data/.../AppSettingsSerializer.kt).
Proto3 zero-values (0, false, "") are implicit; if the real default differs
(e.g., proxy_port = 1080), the serializer is the only place it gets set.
Validate string enums on read. Proto stores enum-like fields as plain strings ("vpn", "proxy"). Fall back to a safe default on unrecognized values.
Rust (ripdpi-diagnostics-contracts, re-exported by ripdpi-monitor-engine) and Kotlin exchange JSON wire messages. Schema version
is tracked by a constant that must be equal on both sides:
DIAGNOSTICS_ENGINE_SCHEMA_VERSION in native/rust/crates/ripdpi-diagnostics-contracts/src/wire.rsDiagnosticsEngineSchemaVersion in core/diagnostics/.../contract/engine/EngineContract.ktDiagnosticsContractGovernanceTest enforces equality by parsing the Rust
source with Regex("""DIAGNOSTICS_ENGINE_SCHEMA_VERSION:\s*u32\s*=\s*(\d+)""").
Wire types (all in wire.rs / EngineContract.kt):
| Rust | Kotlin | Direction |
|---|---|---|
EngineScanRequestWire | EngineScanRequestWire | Kotlin -> Rust |
EngineScanReportWire | EngineScanReportWire | Rust -> Kotlin |
EngineProgressWire | EngineProgressWire | Rust -> Kotlin |
Three test files enforce Kotlin/Rust wire compatibility using shared fixtures
in diagnostics-contract-fixtures/:
diagnostics_progress_fields.json, diagnostics_scan_report_fields.json)
match Kotlin wire classes.serde_json, asserts schema version, verifies outcome taxonomy covers all
emitted native outcome tokens.After a wire change: update structs in Rust/Kotlin, run Rust tests to
regenerate golden files (assert_contract_fixture writes on mismatch in
update mode), then run Kotlin tests. Commit updated fixtures with the code.
app_settings.proto.AppSettingsSerializer.defaultValue.toUiState(), toConfigDraft()).app_settings.proto.reserved numbers list.reserved names list.#[serde(default)] in Rust wire struct.@Serializable data class.DIAGNOSTICS_ENGINE_SCHEMA_VERSION in both Rust and Kotlin.app_settings.protoreserved lines (numbers AND names)AppSettingsSerializer.defaultValue#[serde(default)] / Kotlin defaultscargo test --locked -p ripdpi-monitor-engine) and Kotlin contract tests passまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).
日本語の概要は準備中です。原文の説明を表示しています。
ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.
日本語の概要は準備中です。原文の説明を表示しています。
Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).
日本語の概要は準備中です。原文の説明を表示しています。