feat(scaffold): create product workspace + Rust crates + Flutter app
Implements the canonical implementation directory layout adopted by
DEC-022 (register v0.9.5). Closes the scaffolding phase; no PoC code
has been promoted in yet (per proof-of-concept-plan.md §4 a PoC is
not product code unless explicitly promoted).
Rust workspace
==============
Top-level Cargo.toml declares seven workspace members:
core/chanora_core top-level Rust API + orchestration
crates/chanora_protocol tsclientlib isolation (SAD-067, SysDes-011/029)
crates/chanora_state state sync, reducers, deltas
crates/chanora_audio capture, DSP, Opus, jitter, mixer, playback
crates/chanora_storage non-secret DB + platform secure store
crates/chanora_diagnostics logs, redaction, export
crates/chanora_bridge typed Flutter/Rust DTOs
Workspace-wide pins:
license = "MIT OR Apache-2.0" (DEC-020)
rust-version = "1.95"
edition = "2021"
The Flutter app (apps/chanora_flutter) is NOT a Cargo workspace
member; it is owned by the Flutter / Gradle toolchain and is in the
workspace exclude array along with every poc/* spike.
Each crate ships:
* a Cargo.toml referring to workspace.dependencies pins;
* a lib.rs with #![forbid(unsafe_code)] + #![warn(missing_docs)],
a typed Error enum, and the public types relevant to the
subsystem's role per SAD §7.2;
* minimal unit tests so
running 1 test
test tests::defaults_match_decisions ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::it_compiles ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::session_can_be_constructed ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::marker_matches_poc ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::it_compiles ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::state_transitions_compile ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 1 test
test tests::it_compiles ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s is non-empty.
chanora_core's CoreError type-wraps every subsystem error via
#[from] so callers can match on origin without parsing strings.
chanora_audio's AudioEffects struct defaults all four effects to
true, matching DEC-007 (AEC), DEC-008 (AGC), DEC-009 (NS),
DEC-010 (HPF). A unit test pins this so a future regression that
flips a default fails immediately.
chanora_diagnostics exports REDACTION_MARKER = "[REDACTED]",
identical to the PoC's marker so audit grep patterns survive the
promotion.
chanora_bridge's BridgeError is Serialize + Deserialize so it can
flow across the FRB 2.x boundary (DEC-014).
Empirical verification: cargo check --workspace clean, cargo test
--workspace clean (7 unit tests + 7 doc-test runners, all passing)
against Rust 1.95.0 stable.
Flutter app
===========
apps/chanora_flutter created with .
DEC-004 applied: minSdk overridden to 28 in
android/app/build.gradle.kts with a comment that points back at the
decision register and forbids lowering it without re-opening DEC-004.
DEC-015 applied: shipped English + Simplified Chinese at MVP.
- pubspec.yaml gains flutter_localizations + intl + generate:true.
- l10n.yaml emits lib/l10n/generated/AppL10n (no synthetic package
— that was removed in Flutter 3.41+).
- lib/l10n/app_en.arb is the source of truth; lib/l10n/app_zh.arb
mirrors the key set in zh-Hans. ARB metadata explicitly
reaffirms ADR-008: server-provided content (channel names,
nicknames, welcome banners) is preserved verbatim and never
translated.
lib/main.dart and test/widget_test.dart were rewritten from the
template counter into a minimal localized scaffold that proves
both locales render correctly.
Empirical verification: reports no issues;
runs the two locale smoke tests and both pass.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
//! # `chanora_storage`
|
||||
//!
|
||||
//! Two strictly separated repositories per SAD-067:
|
||||
//!
|
||||
//! * [`LocalDatabaseRepository`] — non-secret state (bookmarks,
|
||||
//! settings, identity *references*) via SQLite. Crate choice:
|
||||
//! `rusqlite` bundled (DEC-013.1).
|
||||
//! * [`SecretStorageRepository`] — secret material (identity private
|
||||
//! keys, server passwords) via platform secure storage. Linux
|
||||
//! policy: Secret Service preferred, kernel keyutils fallback
|
||||
//! (DEC-013.2). Other platforms TBD per SS-TC-001/002/004/005.
|
||||
//!
|
||||
//! Secret values **never** appear in the local DB (SS-AUD-001/002);
|
||||
//! bookmarks store only an `identity_ref` lookup name into the
|
||||
//! secure store.
|
||||
//!
|
||||
//! ## Status
|
||||
//!
|
||||
//! Scaffold only. `poc/secure-storage-spike` and
|
||||
//! `poc/sqlite-storage-spike` will be promoted here.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Errors raised by either storage repository.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StorageError {
|
||||
/// Looked-up entry does not exist.
|
||||
#[error("not found")]
|
||||
NotFound,
|
||||
/// Schema migration error.
|
||||
#[error("migration: {0}")]
|
||||
Migration(String),
|
||||
/// Underlying SQLite error.
|
||||
#[error("sqlite: {0}")]
|
||||
Sqlite(String),
|
||||
/// Platform secure-storage backend rejected an operation.
|
||||
#[error("secure-store: {0}")]
|
||||
SecureStore(String),
|
||||
}
|
||||
|
||||
/// Marker trait for the non-secret database side. Concrete impl will
|
||||
/// land alongside the `BookmarkRepository` / `SettingsRepository`
|
||||
/// traits promoted from the SQLite PoC.
|
||||
pub trait LocalDatabaseRepository: Send + Sync {}
|
||||
|
||||
/// Marker trait for the platform secure-storage side. Concrete impl
|
||||
/// will land alongside the `Secret` newtype + per-platform adapters
|
||||
/// promoted from the secure-storage PoC.
|
||||
pub trait SecretStorageRepository: Send + Sync {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_compiles() {}
|
||||
}
|
||||
Reference in New Issue
Block a user