Merge pull request #12 from EdisonJwa/chore/rename-prefetch-crate-pr
chore(prefetch): rename server prefetch crate
This commit is contained in:
Generated
+11
-11
@@ -470,8 +470,8 @@ version = "0.2.0-beta.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chanora_audio",
|
"chanora_audio",
|
||||||
"chanora_diagnostics",
|
"chanora_diagnostics",
|
||||||
|
"chanora_prefetch",
|
||||||
"chanora_protocol",
|
"chanora_protocol",
|
||||||
"chanora_server_prefetch",
|
|
||||||
"chanora_state",
|
"chanora_state",
|
||||||
"chanora_storage",
|
"chanora_storage",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
@@ -489,6 +489,16 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chanora_prefetch"
|
||||||
|
version = "0.2.0-beta.1"
|
||||||
|
dependencies = [
|
||||||
|
"chanora_resolver",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chanora_protocol"
|
name = "chanora_protocol"
|
||||||
version = "0.2.0-beta.1"
|
version = "0.2.0-beta.1"
|
||||||
@@ -521,16 +531,6 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chanora_server_prefetch"
|
|
||||||
version = "0.2.0-beta.1"
|
|
||||||
dependencies = [
|
|
||||||
"chanora_resolver",
|
|
||||||
"thiserror 2.0.18",
|
|
||||||
"tokio",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chanora_state"
|
name = "chanora_state"
|
||||||
version = "0.2.0-beta.1"
|
version = "0.2.0-beta.1"
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@
|
|||||||
# crates/chanora_audio/ — capture, DSP, Opus, jitter, mixer
|
# crates/chanora_audio/ — capture, DSP, Opus, jitter, mixer
|
||||||
# crates/chanora_storage/ — bookmarks, settings, identity refs
|
# crates/chanora_storage/ — bookmarks, settings, identity refs
|
||||||
# crates/chanora_diagnostics/ — logs, redaction, export
|
# crates/chanora_diagnostics/ — logs, redaction, export
|
||||||
# crates/chanora_server_prefetch — server-resolution prefetch cache/policy
|
# crates/chanora_prefetch — server-resolution prefetch cache/policy
|
||||||
# crates/chanora_bridge/ — Flutter/Rust typed DTOs + glue
|
# crates/chanora_bridge/ — Flutter/Rust typed DTOs + glue
|
||||||
#
|
#
|
||||||
# The Flutter app is not part of this Cargo workspace; it is owned by
|
# The Flutter app is not part of this Cargo workspace; it is owned by
|
||||||
@@ -31,7 +31,7 @@ members = [
|
|||||||
"crates/chanora_audio",
|
"crates/chanora_audio",
|
||||||
"crates/chanora_storage",
|
"crates/chanora_storage",
|
||||||
"crates/chanora_diagnostics",
|
"crates/chanora_diagnostics",
|
||||||
"crates/chanora_server_prefetch",
|
"crates/chanora_prefetch",
|
||||||
"crates/chanora_bridge",
|
"crates/chanora_bridge",
|
||||||
"crates/chanora_resolver",
|
"crates/chanora_resolver",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ chanora_state = { path = "../../crates/chanora_state" }
|
|||||||
chanora_audio = { path = "../../crates/chanora_audio" }
|
chanora_audio = { path = "../../crates/chanora_audio" }
|
||||||
chanora_storage = { path = "../../crates/chanora_storage" }
|
chanora_storage = { path = "../../crates/chanora_storage" }
|
||||||
chanora_diagnostics = { path = "../../crates/chanora_diagnostics" }
|
chanora_diagnostics = { path = "../../crates/chanora_diagnostics" }
|
||||||
chanora_server_prefetch = { path = "../../crates/chanora_server_prefetch" }
|
chanora_prefetch = { path = "../../crates/chanora_prefetch" }
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tokio = { version = "1", features = ["sync", "rt", "macros"] }
|
tokio = { version = "1", features = ["sync", "rt", "macros"] }
|
||||||
@@ -23,6 +23,6 @@ tokio = { version = "1", features = ["sync", "rt", "macros"] }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# Used by integration tests to inspect the bookmark DB row layout
|
# Used by integration tests to inspect the bookmark DB row layout
|
||||||
# without going through the public repository API.
|
# without going through the public repository API.
|
||||||
chanora_server_prefetch = { path = "../../crates/chanora_server_prefetch", features = ["test-support"] }
|
chanora_prefetch = { path = "../../crates/chanora_prefetch", features = ["test-support"] }
|
||||||
rusqlite = { version = "0.32", features = ["bundled"] }
|
rusqlite = { version = "0.32", features = ["bundled"] }
|
||||||
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] }
|
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] }
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ use tokio::sync::{broadcast, oneshot, watch, Mutex};
|
|||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
use chanora_server_prefetch::ServerPrefetcher;
|
use chanora_prefetch::ServerPrefetcher;
|
||||||
use chanora_state::channel_join::{
|
use chanora_state::channel_join::{
|
||||||
self, AuthoritativeSource, ChannelId as JoinChannelId, ChannelJoinEvent, ChannelJoinState,
|
self, AuthoritativeSource, ChannelId as JoinChannelId, ChannelJoinEvent, ChannelJoinState,
|
||||||
ConnectionEpoch, JoinFailureKind,
|
ConnectionEpoch, JoinFailureKind,
|
||||||
@@ -2506,9 +2506,7 @@ mod tests {
|
|||||||
.fail_next_prefetch_setup_for_test("resolver unavailable")
|
.fail_next_prefetch_setup_for_test("resolver unavailable")
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let result = session
|
let result = session.prefetch_server(" Example.COM ".to_string()).await;
|
||||||
.prefetch_server(" Example.COM ".to_string())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "chanora_server_prefetch"
|
name = "chanora_prefetch"
|
||||||
description = "Chanora — server-address prefetch cache and policy built on chanora_resolver."
|
description = "Chanora — server-address prefetch cache and policy built on chanora_resolver."
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
@@ -116,12 +116,12 @@ impl ServerPrefetcher {
|
|||||||
};
|
};
|
||||||
let cache = self.cache.clone();
|
let cache = self.cache.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
info!(target: "chanora_server_prefetch", host = %normalized, "resolution prefetch started");
|
info!(target: "chanora_prefetch", host = %normalized, "resolution prefetch started");
|
||||||
let result = resolve_socket(resolver, &normalized).await;
|
let result = resolve_socket(resolver, &normalized).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
info!(
|
info!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %normalized,
|
host = %normalized,
|
||||||
resolved = %addr,
|
resolved = %addr,
|
||||||
"resolution prefetch result"
|
"resolution prefetch result"
|
||||||
@@ -131,7 +131,7 @@ impl ServerPrefetcher {
|
|||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %normalized,
|
host = %normalized,
|
||||||
error = %err,
|
error = %err,
|
||||||
"resolution prefetch failed"
|
"resolution prefetch failed"
|
||||||
@@ -150,7 +150,7 @@ impl ServerPrefetcher {
|
|||||||
match resolved {
|
match resolved {
|
||||||
Some(addr) => {
|
Some(addr) => {
|
||||||
info!(
|
info!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %host,
|
host = %host,
|
||||||
resolved = %addr,
|
resolved = %addr,
|
||||||
"connect using prefetched resolution"
|
"connect using prefetched resolution"
|
||||||
@@ -158,7 +158,7 @@ impl ServerPrefetcher {
|
|||||||
Some(addr)
|
Some(addr)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!(target: "chanora_server_prefetch", host = %host, "connect prefetch miss or stale");
|
debug!(target: "chanora_prefetch", host = %host, "connect prefetch miss or stale");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ Chanora is a Flutter application with a Rust core. Flutter owns the user-facing
|
|||||||
| Storage | `crates/chanora_storage` | Bookmarks, identities, encrypted local data, platform keyring integration | Rust core, platform secure storage |
|
| Storage | `crates/chanora_storage` | Bookmarks, identities, encrypted local data, platform keyring integration | Rust core, platform secure storage |
|
||||||
| Diagnostics | `crates/chanora_diagnostics` | Redaction, log sink, export bundle, known-secret registry | Rust core, Flutter diagnostics UI |
|
| Diagnostics | `crates/chanora_diagnostics` | Redaction, log sink, export bundle, known-secret registry | Rust core, Flutter diagnostics UI |
|
||||||
| Server resolver | `crates/chanora_resolver` | SRV/TSDNS/DNS fallback resolution | Rust core, prefetch crate |
|
| Server resolver | `crates/chanora_resolver` | SRV/TSDNS/DNS fallback resolution | Rust core, prefetch crate |
|
||||||
| Server prefetch | `crates/chanora_server_prefetch`, Flutter `prefetch_debouncer.dart` | Invisible host-field resolution warming, TTL cache, generation safety | Resolver, Flutter connect UI, Rust core |
|
| Server prefetch | `crates/chanora_prefetch`, Flutter `prefetch_debouncer.dart` | Invisible host-field resolution warming, TTL cache, generation safety | Resolver, Flutter connect UI, Rust core |
|
||||||
|
|
||||||
## 5. Static Architecture View
|
## 5. Static Architecture View
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ Flutter UI/widgets/services
|
|||||||
-> chanora_audio -> platform audio APIs / Opus / DSP
|
-> chanora_audio -> platform audio APIs / Opus / DSP
|
||||||
-> chanora_storage -> platform secure storage / SQLite
|
-> chanora_storage -> platform secure storage / SQLite
|
||||||
-> chanora_diagnostics
|
-> chanora_diagnostics
|
||||||
-> chanora_server_prefetch -> chanora_resolver -> network DNS/TSDNS
|
-> chanora_prefetch -> chanora_resolver -> network DNS/TSDNS
|
||||||
```
|
```
|
||||||
|
|
||||||
The bridge is the trust and type boundary between Flutter and Rust. Flutter must not directly depend on protocol-library internals. Rust core must not expose platform-specific storage or audio details to UI code except through stable DTOs and capability fields.
|
The bridge is the trust and type boundary between Flutter and Rust. Flutter must not directly depend on protocol-library internals. Rust core must not expose platform-specific storage or audio details to UI code except through stable DTOs and capability fields.
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ This Software Detailed Design defines the module-level design details needed for
|
|||||||
| SDD-MOD-011 Audio subsystem | `crates/chanora_audio/src/` | Audio capture/playback, DSP, Opus, PTT, mode stack, platform units | Audio subsystem |
|
| SDD-MOD-011 Audio subsystem | `crates/chanora_audio/src/` | Audio capture/playback, DSP, Opus, PTT, mode stack, platform units | Audio subsystem |
|
||||||
| SDD-MOD-012 Storage | `crates/chanora_storage/src/lib.rs` | Bookmarks, identity storage, encrypted local records, keyring abstraction | Storage |
|
| SDD-MOD-012 Storage | `crates/chanora_storage/src/lib.rs` | Bookmarks, identity storage, encrypted local records, keyring abstraction | Storage |
|
||||||
| SDD-MOD-013 Diagnostics | `crates/chanora_diagnostics/src/lib.rs` | Redaction, log sink, known-secret registry, export bundle | Diagnostics |
|
| SDD-MOD-013 Diagnostics | `crates/chanora_diagnostics/src/lib.rs` | Redaction, log sink, known-secret registry, export bundle | Diagnostics |
|
||||||
| SDD-MOD-014 Resolution and prefetch | `crates/chanora_resolver/src/lib.rs`, `crates/chanora_server_prefetch/src/lib.rs`, `prefetch_debouncer.dart` | SRV/TSDNS/DNS fallback and generation-safe resolution warming | Server resolver / prefetch |
|
| SDD-MOD-014 Resolution and prefetch | `crates/chanora_resolver/src/lib.rs`, `crates/chanora_prefetch/src/lib.rs`, `prefetch_debouncer.dart` | SRV/TSDNS/DNS fallback and generation-safe resolution warming | Server resolver / prefetch |
|
||||||
| SDD-MOD-015 Build and release hooks | `.github/workflows/`, `tools/`, platform project files | CI, unsigned iOS build, benchmark advisory, platform smoke procedures | Release / platform architecture |
|
| SDD-MOD-015 Build and release hooks | `.github/workflows/`, `tools/`, platform project files | CI, unsigned iOS build, benchmark advisory, platform smoke procedures | Release / platform architecture |
|
||||||
|
|
||||||
## 3. Bridge Boundary Design
|
## 3. Bridge Boundary Design
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
| Storage (secrets) | `IdentityFileStore` with platform keyring (Linux Secret Service, macOS Keychain, Windows Credential Manager, iOS Keychain); file fallback with 0600 perms |
|
| Storage (secrets) | `IdentityFileStore` with platform keyring (Linux Secret Service, macOS Keychain, Windows Credential Manager, iOS Keychain); file fallback with 0600 perms |
|
||||||
| Diagnostics | `chanora_diagnostics` — `Redactor` (IP/host/email/token/path/secret scrubbing), `InMemoryLogSink`, `DiagnosticExport` JSON bundle, `KnownSecretRegistry`, panic hook |
|
| Diagnostics | `chanora_diagnostics` — `Redactor` (IP/host/email/token/path/secret scrubbing), `InMemoryLogSink`, `DiagnosticExport` JSON bundle, `KnownSecretRegistry`, panic hook |
|
||||||
| Server address resolution | `chanora_resolver` — SRV/TSDNS/DNS fallback |
|
| Server address resolution | `chanora_resolver` — SRV/TSDNS/DNS fallback |
|
||||||
| Server prefetch | `chanora_server_prefetch` crate + `prefetch_debouncer.dart` — invisible host-field prefetch, TTL cache, generation-safe |
|
| Server prefetch | `chanora_prefetch` crate + `prefetch_debouncer.dart` — invisible host-field prefetch, TTL cache, generation-safe |
|
||||||
| Android platform | `android_voice_unit.rs`, `android_permissions_service.dart`, `MODE_IN_COMMUNICATION` routing, foreground service (`flutter_foreground_task`) |
|
| Android platform | `android_voice_unit.rs`, `android_permissions_service.dart`, `MODE_IN_COMMUNICATION` routing, foreground service (`flutter_foreground_task`) |
|
||||||
| iOS platform | `ios_voice_unit.rs`, `ios_raw_unit.rs`, `ios_permissions_service.dart`, `AVAudioSession` integration, `audio_session` package |
|
| iOS platform | `ios_voice_unit.rs`, `ios_raw_unit.rs`, `ios_permissions_service.dart`, `AVAudioSession` integration, `audio_session` package |
|
||||||
| Permission UX | `permission_state_banner.dart`, pre-request explainers |
|
| Permission UX | `permission_state_banner.dart`, pre-request explainers |
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ This report summarizes the current dependency and supply-chain controls visible
|
|||||||
|
|
||||||
| Area | Examples from current repository | DV status |
|
| Area | Examples from current repository | DV status |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Rust workspace crates | `chanora_protocol`, `chanora_audio`, `chanora_storage`, `chanora_diagnostics`, `chanora_bridge`, `chanora_resolver`, `chanora_server_prefetch`, `chanora_state`, `chanora_core` | In workspace and covered by CI commands |
|
| Rust workspace crates | `chanora_protocol`, `chanora_audio`, `chanora_storage`, `chanora_diagnostics`, `chanora_bridge`, `chanora_resolver`, `chanora_prefetch`, `chanora_state`, `chanora_core` | In workspace and covered by CI commands |
|
||||||
| Flutter app dependencies | `flutter_rust_bridge`, `audio_session`, `flutter_foreground_task`, `package_info_plus`, `share_plus`, `shared_preferences` | Covered by Flutter dependency resolution and license inventory job |
|
| Flutter app dependencies | `flutter_rust_bridge`, `audio_session`, `flutter_foreground_task`, `package_info_plus`, `share_plus`, `shared_preferences` | Covered by Flutter dependency resolution and license inventory job |
|
||||||
| Native/audio dependencies | Opus, platform audio stacks, Android/iOS audio services | Require platform build and license review evidence |
|
| Native/audio dependencies | Opus, platform audio stacks, Android/iOS audio services | Require platform build and license review evidence |
|
||||||
| Patched Rust dependency | `cmake` patched to a pinned git revision for Android build support | Requires DEC-032 tracking and periodic reevaluation |
|
| Patched Rust dependency | `cmake` patched to a pinned git revision for Android build support | Requires DEC-032 tracking and periodic reevaluation |
|
||||||
|
|||||||
@@ -292,9 +292,9 @@ those terms.
|
|||||||
| chanora_audio | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_audio | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| chanora_bridge | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_bridge | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| chanora_diagnostics | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_diagnostics | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
|
| chanora_prefetch | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| chanora_protocol | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_protocol | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| chanora_resolver | 0.1.0 | `Apache License 2.0` | — |
|
| chanora_resolver | 0.1.0 | `Apache License 2.0` | — |
|
||||||
| chanora_server_prefetch | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
|
||||||
| chanora_state | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_state | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| chanora_storage | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
| chanora_storage | 0.2.0-beta.1 | `Apache License 2.0` | <https://github.com/anomalyco/opencode> |
|
||||||
| alsa | 0.11.0 | `Apache License 2.0` | <https://github.com/diwic/alsa-rs> |
|
| alsa | 0.11.0 | `Apache License 2.0` | <https://github.com/diwic/alsa-rs> |
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
**Goal:** Move server-resolution prefetch policy from `chanora_core` into a focused crate named `chanora_server_prefetch` without changing Flutter APIs, resolver behavior, protocol dialing behavior, or Android connect UX.
|
**Goal:** Move server-resolution prefetch policy from `chanora_core` into a focused crate named `chanora_prefetch` without changing Flutter APIs, resolver behavior, protocol dialing behavior, or Android connect UX.
|
||||||
|
|
||||||
**Architecture:** Add `crates/chanora_server_prefetch` as a workspace member. The new crate owns normalization, single-entry TTL cache, generation rejection, resolver-backed async warming, and fresh exact-match lookup. `chanora_core` keeps the trust boundary for `ConnectConfig.resolved_address`, using the prefetcher only to populate one-time dial config while keeping stored/reconnect config sanitized.
|
**Architecture:** Add `crates/chanora_prefetch` as a workspace member. The new crate owns normalization, single-entry TTL cache, generation rejection, resolver-backed async warming, and fresh exact-match lookup. `chanora_core` keeps the trust boundary for `ConnectConfig.resolved_address`, using the prefetcher only to populate one-time dial config while keeping stored/reconnect config sanitized.
|
||||||
|
|
||||||
**Tech Stack:** Rust workspace, `tokio`, `tracing`, `thiserror`, `chanora_resolver`, `chanora_core`, `chanora_protocol`, Flutter Android smoke via ADB.
|
**Tech Stack:** Rust workspace, `tokio`, `tracing`, `thiserror`, `chanora_resolver`, `chanora_core`, `chanora_protocol`, Flutter Android smoke via ADB.
|
||||||
|
|
||||||
@@ -12,28 +12,28 @@
|
|||||||
|
|
||||||
## File Structure
|
## File Structure
|
||||||
|
|
||||||
- Create `crates/chanora_server_prefetch/Cargo.toml`: package metadata and dependencies.
|
- Create `crates/chanora_prefetch/Cargo.toml`: package metadata and dependencies.
|
||||||
- Create `crates/chanora_server_prefetch/src/lib.rs`: public `ServerPrefetcher`, public `ServerPrefetchError`, internal cache entry/state, resolver-backed prefetch logic, and unit tests.
|
- Create `crates/chanora_prefetch/src/lib.rs`: public `ServerPrefetcher`, public `ServerPrefetchError`, internal cache entry/state, resolver-backed prefetch logic, and unit tests.
|
||||||
- Modify `Cargo.toml`: add `crates/chanora_server_prefetch` to workspace members and update the workspace layout comment.
|
- Modify `Cargo.toml`: add `crates/chanora_prefetch` to workspace members and update the workspace layout comment.
|
||||||
- Modify `core/chanora_core/Cargo.toml`: replace the direct `chanora_resolver` dependency with `chanora_server_prefetch`.
|
- Modify `core/chanora_core/Cargo.toml`: replace the direct `chanora_resolver` dependency with `chanora_prefetch`.
|
||||||
- Modify `core/chanora_core/src/lib.rs`: remove private prefetch cache/resolver helpers, add `ServerPrefetcher`, delegate `prefetch_server_resolution`, and keep connect config sanitization tests.
|
- Modify `core/chanora_core/src/lib.rs`: remove private prefetch cache/resolver helpers, add `ServerPrefetcher`, delegate `prefetch_server_resolution`, and keep connect config sanitization tests.
|
||||||
- Modify `Cargo.lock`: generated by `cargo test`/`cargo check` after adding the crate.
|
- Modify `Cargo.lock`: generated by `cargo test`/`cargo check` after adding the crate.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Task 1: Add `chanora_server_prefetch` Crate With Cache Policy Tests
|
### Task 1: Add `chanora_prefetch` Crate With Cache Policy Tests
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `Cargo.toml`
|
- Modify: `Cargo.toml`
|
||||||
- Create: `crates/chanora_server_prefetch/Cargo.toml`
|
- Create: `crates/chanora_prefetch/Cargo.toml`
|
||||||
- Create: `crates/chanora_server_prefetch/src/lib.rs`
|
- Create: `crates/chanora_prefetch/src/lib.rs`
|
||||||
|
|
||||||
- [ ] **Step 1: Add the workspace member and package files**
|
- [ ] **Step 1: Add the workspace member and package files**
|
||||||
|
|
||||||
In top-level `Cargo.toml`, update the layout comment and members:
|
In top-level `Cargo.toml`, update the layout comment and members:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# crates/chanora_server_prefetch — server-resolution prefetch cache/policy
|
# crates/chanora_prefetch — server-resolution prefetch cache/policy
|
||||||
# crates/chanora_bridge/ — Flutter/Rust typed DTOs + glue
|
# crates/chanora_bridge/ — Flutter/Rust typed DTOs + glue
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -45,17 +45,17 @@ members = [
|
|||||||
"crates/chanora_audio",
|
"crates/chanora_audio",
|
||||||
"crates/chanora_storage",
|
"crates/chanora_storage",
|
||||||
"crates/chanora_diagnostics",
|
"crates/chanora_diagnostics",
|
||||||
"crates/chanora_server_prefetch",
|
"crates/chanora_prefetch",
|
||||||
"crates/chanora_bridge",
|
"crates/chanora_bridge",
|
||||||
"crates/chanora_resolver",
|
"crates/chanora_resolver",
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Create `crates/chanora_server_prefetch/Cargo.toml`:
|
Create `crates/chanora_prefetch/Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[package]
|
[package]
|
||||||
name = "chanora_server_prefetch"
|
name = "chanora_prefetch"
|
||||||
description = "Chanora — server-address prefetch cache and policy built on chanora_resolver."
|
description = "Chanora — server-address prefetch cache and policy built on chanora_resolver."
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
@@ -75,7 +75,7 @@ tokio = { version = "1", features = ["sync", "rt", "macros"] }
|
|||||||
test-support = []
|
test-support = []
|
||||||
```
|
```
|
||||||
|
|
||||||
Create `crates/chanora_server_prefetch/src/lib.rs` with the initial crate implementation and tests:
|
Create `crates/chanora_prefetch/src/lib.rs` with the initial crate implementation and tests:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
//! Server-address prefetch cache and policy for Chanora.
|
//! Server-address prefetch cache and policy for Chanora.
|
||||||
@@ -189,13 +189,13 @@ impl ServerPrefetcher {
|
|||||||
};
|
};
|
||||||
let cache = self.cache.clone();
|
let cache = self.cache.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
info!(target: "chanora_server_prefetch", host = %normalized, "resolution prefetch started");
|
info!(target: "chanora_prefetch", host = %normalized, "resolution prefetch started");
|
||||||
let result = resolve_socket(&normalized).await;
|
let result = resolve_socket(&normalized).await;
|
||||||
let mut guard = cache.lock().await;
|
let mut guard = cache.lock().await;
|
||||||
match result {
|
match result {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
info!(
|
info!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %normalized,
|
host = %normalized,
|
||||||
resolved = %addr,
|
resolved = %addr,
|
||||||
"resolution prefetch result"
|
"resolution prefetch result"
|
||||||
@@ -204,7 +204,7 @@ impl ServerPrefetcher {
|
|||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %normalized,
|
host = %normalized,
|
||||||
error = %err,
|
error = %err,
|
||||||
"resolution prefetch failed"
|
"resolution prefetch failed"
|
||||||
@@ -224,7 +224,7 @@ impl ServerPrefetcher {
|
|||||||
match resolved {
|
match resolved {
|
||||||
Some(addr) => {
|
Some(addr) => {
|
||||||
info!(
|
info!(
|
||||||
target: "chanora_server_prefetch",
|
target: "chanora_prefetch",
|
||||||
host = %host,
|
host = %host,
|
||||||
resolved = %addr,
|
resolved = %addr,
|
||||||
"connect using prefetched resolution"
|
"connect using prefetched resolution"
|
||||||
@@ -232,7 +232,7 @@ impl ServerPrefetcher {
|
|||||||
Some(addr)
|
Some(addr)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
info!(target: "chanora_server_prefetch", host = %host, "connect prefetch miss or stale");
|
info!(target: "chanora_prefetch", host = %host, "connect prefetch miss or stale");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,14 +350,14 @@ mod tests {
|
|||||||
|
|
||||||
- [ ] **Step 2: Run new crate tests**
|
- [ ] **Step 2: Run new crate tests**
|
||||||
|
|
||||||
Run: `cargo test -p chanora_server_prefetch --lib`
|
Run: `cargo test -p chanora_prefetch --lib`
|
||||||
|
|
||||||
Expected: the new crate compiles and all 5 tests pass.
|
Expected: the new crate compiles and all 5 tests pass.
|
||||||
|
|
||||||
- [ ] **Step 3: Commit Task 1**
|
- [ ] **Step 3: Commit Task 1**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add Cargo.toml Cargo.lock crates/chanora_server_prefetch
|
git add Cargo.toml Cargo.lock crates/chanora_prefetch
|
||||||
git commit -m "feat(prefetch): add server prefetch crate"
|
git commit -m "feat(prefetch): add server prefetch crate"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -380,7 +380,7 @@ chanora_resolver = { path = "../../crates/chanora_resolver" }
|
|||||||
with:
|
with:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
chanora_server_prefetch = { path = "../../crates/chanora_server_prefetch" }
|
chanora_prefetch = { path = "../../crates/chanora_prefetch" }
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: Remove private prefetch cache implementation from core**
|
- [ ] **Step 2: Remove private prefetch cache implementation from core**
|
||||||
@@ -406,7 +406,7 @@ async fn resolve_prefetch_socket(host: &str) -> Result<std::net::SocketAddr, Cor
|
|||||||
Add this import near the other crate imports:
|
Add this import near the other crate imports:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use chanora_server_prefetch::ServerPrefetcher;
|
use chanora_prefetch::ServerPrefetcher;
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: Replace the session field and constructor initialization**
|
- [ ] **Step 3: Replace the session field and constructor initialization**
|
||||||
@@ -478,7 +478,7 @@ connect_config_without_prefetched_resolution_clears_only_resolved_address
|
|||||||
connect_config_preparation_keeps_prefetched_address_out_of_stored_config
|
connect_config_preparation_keeps_prefetched_address_out_of_stored_config
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace any direct access to `session.resolution_prefetch` with calls to public test-support methods on `ServerPrefetcher`. In `crates/chanora_server_prefetch/src/lib.rs`, keep these methods gated with `#[cfg(any(test, feature = "test-support"))]`:
|
Replace any direct access to `session.resolution_prefetch` with calls to public test-support methods on `ServerPrefetcher`. In `crates/chanora_prefetch/src/lib.rs`, keep these methods gated with `#[cfg(any(test, feature = "test-support"))]`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
@@ -502,7 +502,7 @@ Enable the feature for `chanora_core` tests by adding this dev-dependency in `co
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
chanora_server_prefetch = { path = "../../crates/chanora_server_prefetch", features = ["test-support"] }
|
chanora_prefetch = { path = "../../crates/chanora_prefetch", features = ["test-support"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
Then core test setup should look like:
|
Then core test setup should look like:
|
||||||
@@ -524,7 +524,7 @@ Expected: all core lib tests pass.
|
|||||||
- [ ] **Step 7: Commit Task 2**
|
- [ ] **Step 7: Commit Task 2**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add Cargo.toml Cargo.lock core/chanora_core/Cargo.toml core/chanora_core/src/lib.rs crates/chanora_server_prefetch
|
git add Cargo.toml Cargo.lock core/chanora_core/Cargo.toml core/chanora_core/src/lib.rs crates/chanora_prefetch
|
||||||
git commit -m "refactor(core): use server prefetch crate"
|
git commit -m "refactor(core): use server prefetch crate"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ git commit -m "refactor(core): use server prefetch crate"
|
|||||||
|
|
||||||
- [ ] **Step 1: Remove core tests moved to the prefetch crate**
|
- [ ] **Step 1: Remove core tests moved to the prefetch crate**
|
||||||
|
|
||||||
Delete these tests from `core/chanora_core/src/lib.rs` because they now belong in `chanora_server_prefetch`:
|
Delete these tests from `core/chanora_core/src/lib.rs` because they now belong in `chanora_prefetch`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
resolution_prefetch_cache_returns_fresh_exact_match
|
resolution_prefetch_cache_returns_fresh_exact_match
|
||||||
@@ -564,7 +564,7 @@ Expected: no diff. If there is a diff, revert only accidental protocol edits by
|
|||||||
|
|
||||||
- [ ] **Step 3: Run combined Rust tests**
|
- [ ] **Step 3: Run combined Rust tests**
|
||||||
|
|
||||||
Run: `cargo test -p chanora_server_prefetch -p chanora_core -p chanora_protocol --lib`
|
Run: `cargo test -p chanora_prefetch -p chanora_core -p chanora_protocol --lib`
|
||||||
|
|
||||||
Expected: all tests pass.
|
Expected: all tests pass.
|
||||||
|
|
||||||
@@ -584,7 +584,7 @@ git commit -m "test(core): keep prefetch tests at crate boundary"
|
|||||||
|
|
||||||
- [ ] **Step 1: Run full focused Rust verification**
|
- [ ] **Step 1: Run full focused Rust verification**
|
||||||
|
|
||||||
Run: `cargo test -p chanora_resolver -p chanora_server_prefetch -p chanora_protocol -p chanora_core --lib`
|
Run: `cargo test -p chanora_resolver -p chanora_prefetch -p chanora_protocol -p chanora_core --lib`
|
||||||
|
|
||||||
Expected: all tests pass.
|
Expected: all tests pass.
|
||||||
|
|
||||||
@@ -684,6 +684,6 @@ Expected: only unrelated untracked `config.json` remains, unless the user has ad
|
|||||||
|
|
||||||
## Self-Review
|
## Self-Review
|
||||||
|
|
||||||
- Spec coverage: the plan adds `chanora_server_prefetch`, moves cache policy and resolver-backed warming there, keeps core as trust boundary, preserves Flutter/protocol behavior, and includes Android connect smoke verification.
|
- Spec coverage: the plan adds `chanora_prefetch`, moves cache policy and resolver-backed warming there, keeps core as trust boundary, preserves Flutter/protocol behavior, and includes Android connect smoke verification.
|
||||||
- Placeholder scan: no `TBD`, `TODO`, or unspecified edge handling remains.
|
- Placeholder scan: no `TBD`, `TODO`, or unspecified edge handling remains.
|
||||||
- Type consistency: the plan uses `ServerPrefetcher`, `ServerPrefetchError`, `prefetch`, and `fresh_match` consistently across crate and core tasks.
|
- Type consistency: the plan uses `ServerPrefetcher`, `ServerPrefetchError`, `prefetch`, and `fresh_match` consistently across crate and core tasks.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Date: 2026-05-28
|
|||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
Move server-resolution prefetch policy out of `chanora_core` into a focused Rust crate named `chanora_server_prefetch`, without changing connection behavior, Flutter APIs, or protocol dialing semantics.
|
Move server-resolution prefetch policy out of `chanora_core` into a focused Rust crate named `chanora_prefetch`, without changing connection behavior, Flutter APIs, or protocol dialing semantics.
|
||||||
|
|
||||||
## Non-Goals
|
## Non-Goals
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ Move server-resolution prefetch policy out of `chanora_core` into a focused Rust
|
|||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
Add a workspace member at `crates/chanora_server_prefetch`.
|
Add a workspace member at `crates/chanora_prefetch`.
|
||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ The Flutter bridge keeps calling the same core API, `prefetch_server_resolution(
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Move cache-policy tests from `chanora_core` into `chanora_server_prefetch`:
|
Move cache-policy tests from `chanora_core` into `chanora_prefetch`:
|
||||||
|
|
||||||
- fresh exact match returns the socket address.
|
- fresh exact match returns the socket address.
|
||||||
- stale entries are ignored.
|
- stale entries are ignored.
|
||||||
@@ -100,7 +100,7 @@ Keep core tests for connection trust-boundary behavior:
|
|||||||
|
|
||||||
Run at minimum:
|
Run at minimum:
|
||||||
|
|
||||||
- `cargo test -p chanora_server_prefetch --lib`
|
- `cargo test -p chanora_prefetch --lib`
|
||||||
- `cargo test -p chanora_core --lib`
|
- `cargo test -p chanora_core --lib`
|
||||||
- `cargo test -p chanora_protocol --lib`
|
- `cargo test -p chanora_protocol --lib`
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ For final confidence, rerun the Android server connect smoke path that verifies
|
|||||||
|
|
||||||
- Workspace builds with the new crate member.
|
- Workspace builds with the new crate member.
|
||||||
- `chanora_core` no longer owns the prefetch cache implementation.
|
- `chanora_core` no longer owns the prefetch cache implementation.
|
||||||
- `chanora_server_prefetch` owns prefetch normalization, TTL, generation, storage, and resolver-backed warming.
|
- `chanora_prefetch` owns prefetch normalization, TTL, generation, storage, and resolver-backed warming.
|
||||||
- Public Flutter and Rust protocol behavior is unchanged.
|
- Public Flutter and Rust protocol behavior is unchanged.
|
||||||
- Existing server connect and reconnect safety tests pass.
|
- Existing server connect and reconnect safety tests pass.
|
||||||
- Android connect still reaches the connected server UI and does not get stuck in `Connecting` or `Synchronizing`.
|
- Android connect still reaches the connected server UI and does not get stuck in `Connecting` or `Synchronizing`.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ This plan defines unit verification coverage for the software modules that imple
|
|||||||
| Audio subsystem | `crates/chanora_audio` | DSP, Opus, mixer, gate, PTT logic, baseline examples, benches | Workspace tests and benchmark harnesses; platform loopback evidence is integration/system scope |
|
| Audio subsystem | `crates/chanora_audio` | DSP, Opus, mixer, gate, PTT logic, baseline examples, benches | Workspace tests and benchmark harnesses; platform loopback evidence is integration/system scope |
|
||||||
| Storage | `crates/chanora_storage` | Bookmark repository, identity store, encryption behavior, keyring-disabled CI mode | Workspace tests with `CHANORA_DISABLE_KEYRING=1` in CI |
|
| Storage | `crates/chanora_storage` | Bookmark repository, identity store, encryption behavior, keyring-disabled CI mode | Workspace tests with `CHANORA_DISABLE_KEYRING=1` in CI |
|
||||||
| Diagnostics | `crates/chanora_diagnostics` | Redaction, known-secret registry, diagnostic export JSON, log sink | Workspace tests and security audit plan |
|
| Diagnostics | `crates/chanora_diagnostics` | Redaction, known-secret registry, diagnostic export JSON, log sink | Workspace tests and security audit plan |
|
||||||
| Resolver and prefetch | `crates/chanora_resolver`, `crates/chanora_server_prefetch`, Flutter prefetch debouncer | Resolver fallback, cache TTL, generation safety, debouncer tests | Workspace tests and `apps/chanora_flutter/test/services/prefetch_debouncer_test.dart` |
|
| Resolver and prefetch | `crates/chanora_resolver`, `crates/chanora_prefetch`, Flutter prefetch debouncer | Resolver fallback, cache TTL, generation safety, debouncer tests | Workspace tests and `apps/chanora_flutter/test/services/prefetch_debouncer_test.dart` |
|
||||||
| Flutter services | `apps/chanora_flutter/lib/services` | Dart unit tests | Service tests under `apps/chanora_flutter/test/services/` |
|
| Flutter services | `apps/chanora_flutter/lib/services` | Dart unit tests | Service tests under `apps/chanora_flutter/test/services/` |
|
||||||
| Flutter widgets | `apps/chanora_flutter/lib/widgets` and screen widgets | Widget tests | Widget tests under `apps/chanora_flutter/test/widgets/` |
|
| Flutter widgets | `apps/chanora_flutter/lib/widgets` and screen widgets | Widget tests | Widget tests under `apps/chanora_flutter/test/widgets/` |
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ This plan defines how Chanora verifies that independently tested software compon
|
|||||||
| Audio to platform | `chanora_audio`, OS audio APIs, Flutter voice controls, platform permissions | SRS-062 through SRS-083, SRS-104 through SRS-115, SRS-135 | Audio loopback tests, platform smoke, mobile device tests |
|
| Audio to platform | `chanora_audio`, OS audio APIs, Flutter voice controls, platform permissions | SRS-062 through SRS-083, SRS-104 through SRS-115, SRS-135 | Audio loopback tests, platform smoke, mobile device tests |
|
||||||
| Storage to platform secure storage | `chanora_storage`, keyring adapters, Flutter bookmark/identity UI | SRS-084 through SRS-095, SRS-126, SRS-137 | Storage tests, platform secure-storage audit |
|
| Storage to platform secure storage | `chanora_storage`, keyring adapters, Flutter bookmark/identity UI | SRS-084 through SRS-095, SRS-126, SRS-137 | Storage tests, platform secure-storage audit |
|
||||||
| Diagnostics export | Diagnostics crate, Flutter diagnostics UI, redaction, share/export surface | SRS-095 through SRS-102, SRS-126, SRS-128 | Redaction tests, diagnostic export review, manual export demo |
|
| Diagnostics export | Diagnostics crate, Flutter diagnostics UI, redaction, share/export surface | SRS-095 through SRS-102, SRS-126, SRS-128 | Redaction tests, diagnostic export review, manual export demo |
|
||||||
| Server resolution prefetch | Flutter host-field debouncer, `chanora_server_prefetch`, `chanora_resolver`, connect path | Resolver/prefetch design specs and connection requirements | Unit tests, Android connect smoke, manual connect demo |
|
| Server resolution prefetch | Flutter host-field debouncer, `chanora_prefetch`, `chanora_resolver`, connect path | Resolver/prefetch design specs and connection requirements | Unit tests, Android connect smoke, manual connect demo |
|
||||||
| Packaging and release build | Flutter build, Rust cdylib/framework/DLL/SO packaging, CI workflows | SRS-116 through SRS-123, SRS-127 | CI build evidence, unsigned iOS build, platform-specific smoke |
|
| Packaging and release build | Flutter build, Rust cdylib/framework/DLL/SO packaging, CI workflows | SRS-116 through SRS-123, SRS-127 | CI build evidence, unsigned iOS build, platform-specific smoke |
|
||||||
|
|
||||||
## 3. Required Integration Evidence
|
## 3. Required Integration Evidence
|
||||||
|
|||||||
Reference in New Issue
Block a user