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,20 @@
|
||||
[package]
|
||||
name = "chanora_core"
|
||||
description = "Chanora — top-level Rust API and orchestration. Hosts the connection manager, command dispatcher, and the integration of the protocol, state, audio, storage, and diagnostics subsystems."
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
chanora_protocol = { path = "../../crates/chanora_protocol" }
|
||||
chanora_state = { path = "../../crates/chanora_state" }
|
||||
chanora_audio = { path = "../../crates/chanora_audio" }
|
||||
chanora_storage = { path = "../../crates/chanora_storage" }
|
||||
chanora_diagnostics = { path = "../../crates/chanora_diagnostics" }
|
||||
chanora_bridge = { path = "../../crates/chanora_bridge" }
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
@@ -0,0 +1,96 @@
|
||||
//! # `chanora_core`
|
||||
//!
|
||||
//! Top-level Rust API and orchestration for the Chanora client.
|
||||
//!
|
||||
//! ## Role per SAD §7.2
|
||||
//!
|
||||
//! `chanora_core` is the integration point. It owns no protocol,
|
||||
//! audio, or storage logic directly; instead it composes the
|
||||
//! subsystem crates ([`chanora_protocol`], [`chanora_state`],
|
||||
//! [`chanora_audio`], [`chanora_storage`], [`chanora_diagnostics`])
|
||||
//! behind a stable, typed API consumed by [`chanora_bridge`] (which
|
||||
//! in turn exposes it to Flutter via `flutter_rust_bridge`, per
|
||||
//! DEC-014).
|
||||
//!
|
||||
//! ## Invariants
|
||||
//!
|
||||
//! * Single active server connection at runtime (DEC-006 / SAD-064).
|
||||
//! * Protocol-specific types from `tsclientlib` do not cross out of
|
||||
//! [`chanora_protocol`] (SAD-067).
|
||||
//! * Secret material never lands in [`chanora_storage`]; secrets
|
||||
//! live in [`chanora_diagnostics`]'s `KnownSecretRegistry` *only*
|
||||
//! for redaction and in the platform secure-store (DEC-013.2).
|
||||
//!
|
||||
//! ## Status
|
||||
//!
|
||||
//! This crate is a **scaffold**. No PoC code has been promoted in
|
||||
//! yet. The public surface below is the integration contract; bodies
|
||||
//! are placeholders.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Errors that can arise during top-level orchestration.
|
||||
///
|
||||
/// Each arm wraps a typed error from the subsystem that produced it,
|
||||
/// so callers can match on the originating layer without parsing
|
||||
/// strings. The variants are intentionally narrow at this stage and
|
||||
/// will expand as the subsystems land.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CoreError {
|
||||
/// Protocol-layer error originating from [`chanora_protocol`].
|
||||
#[error("protocol: {0}")]
|
||||
Protocol(#[from] chanora_protocol::ProtocolError),
|
||||
/// State-synchronisation error from [`chanora_state`].
|
||||
#[error("state: {0}")]
|
||||
State(#[from] chanora_state::StateError),
|
||||
/// Audio-subsystem error from [`chanora_audio`].
|
||||
#[error("audio: {0}")]
|
||||
Audio(#[from] chanora_audio::AudioError),
|
||||
/// Storage error from [`chanora_storage`].
|
||||
#[error("storage: {0}")]
|
||||
Storage(#[from] chanora_storage::StorageError),
|
||||
/// Diagnostics error from [`chanora_diagnostics`].
|
||||
#[error("diagnostics: {0}")]
|
||||
Diagnostics(#[from] chanora_diagnostics::DiagnosticsError),
|
||||
/// Bridge / DTO error from [`chanora_bridge`].
|
||||
#[error("bridge: {0}")]
|
||||
Bridge(#[from] chanora_bridge::BridgeError),
|
||||
/// A precondition was violated (typically caller bug or
|
||||
/// concurrent misuse).
|
||||
#[error("invariant violated: {0}")]
|
||||
Invariant(&'static str),
|
||||
}
|
||||
|
||||
/// The top-level Chanora session. Owns exactly one active server
|
||||
/// connection (DEC-006). Construction does **not** dial the server;
|
||||
/// see [`ChanoraSession::connect`] (scaffolded only).
|
||||
pub struct ChanoraSession {
|
||||
_seal: (),
|
||||
}
|
||||
|
||||
impl ChanoraSession {
|
||||
/// Construct a new session with the default subsystem
|
||||
/// configurations. Performs no I/O.
|
||||
pub fn new() -> Self {
|
||||
Self { _seal: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ChanoraSession {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn session_can_be_constructed() {
|
||||
let _ = ChanoraSession::new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user