Replaces the diagnostics scaffold with the production redaction policy + a user-initiated export path that satisfies DEC-016 (no automatic uploads). * `chanora_diagnostics::Redactor` applies the six policy rules to every captured log line: `$HOME` paths → `[home]`; IPv4 + IPv6 literals → `[ip]`; email-shaped strings → `[email]`; long base64-ish tokens → `[token]`; substrings registered with `KnownSecretRegistry` → `[REDACTED]`. The registry implements SS-AUD-003 defence-in-depth: storage adapters can register secrets as they cross out of the keyring so an accidental `Debug` print is still scrubbed at write time. * `InMemoryLogSink` is a bounded ring buffer (cap 500 lines in the bridge) that always passes lines through the redactor before storing them. `RedactingLogLayer` plugs it into `tracing- subscriber` alongside the existing logcat / fmt layers. * `DiagnosticExport::from_sink` builds a plaintext blob — already redacted — combining free-form metadata (crate version, target os/arch) with the retained log tail. `bridge::api:: export_diagnostics()` is the Flutter-facing entrypoint (`#[frb(sync)]`). * `bridge_init` now installs the redaction layer on both Android and desktop hosts, switching from the global `fmt::init()` shortcut to a layered `Registry` so the in-memory sink can sit side-by-side with the platform sink. * Flutter adds a bug-report icon to the AppBar; tapping it opens a scrollable monospace dialog with Copy and Close actions. New `diagnosticsAction` / `copyAction` / `closeAction` strings land in `app_en.arb` + `app_zh.arb`. Tests cover the redaction matrix (IPv4, IPv6, email, long tokens, known secret), the ring buffer capacity, and the full `DiagnosticExport::to_text()` round-trip — 9/9 green. Live-verified on Moto G: the dialog rendered a multi-line transcript with `[ip]`, `[token]`, `[home]` substitutions, the metadata block showed `target_os=android` `target_arch=aarch64`, and Copy placed the same text on the clipboard.
35 lines
1.1 KiB
Plaintext
35 lines
1.1 KiB
Plaintext
{
|
|
"@@locale": "zh",
|
|
"@@x-source-of-truth": "DEC-015 (register v0.9.5). Simplified Chinese for the Beta key set.",
|
|
|
|
"appTitle": "Chanora",
|
|
"homeNotProductionReadyBanner": "Beta 版本——已接通语音收发;尚未达到生产环境质量。",
|
|
|
|
"fieldServerHost": "服务器地址",
|
|
"fieldNickname": "昵称",
|
|
|
|
"connectAction": "连接",
|
|
"disconnectAction": "断开连接",
|
|
"refreshAction": "刷新",
|
|
"diagnosticsAction": "诊断信息",
|
|
"copyAction": "复制",
|
|
"closeAction": "关闭",
|
|
"startAudioAction": "启动语音",
|
|
"pttHoldToTalk": "按住说话",
|
|
"pttTransmitting": "正在发送…",
|
|
|
|
"statusIdle": "未连接",
|
|
"statusConnecting": "正在连接…",
|
|
"statusConnected": "已连接到 {server}",
|
|
"statusError": "错误:{message}",
|
|
|
|
"statusReconnecting": "正在重新连接……第 {attempt} 次尝试,{delay} 秒后",
|
|
"statusConnectionLost": "连接已断开:{reason}",
|
|
|
|
"audioStatsLine": "发送 {sent} 帧 • 接收 {received} 帧 • PTT {ptt}",
|
|
|
|
"channelsHeading": "频道",
|
|
"clientsHeading": "在线用户",
|
|
"countChannelsAndClients": "{channels} 个频道 • {clients} 在线"
|
|
}
|