feat(mvp): v1.0.0-rc.1 — keyring-backed DEK, encrypted bookmarks, MVP release-gate docs
Closes the v0.4 dual-file weakness in identity-at-rest and turns the release into an MVP public release candidate. The remaining work before `v1.0.0` is DEC-012 legal sign-off — see `docs/governance/legal-review-readiness.md` — and the staged platform promotions in `docs/governance/staged-release-plan.md`. No decision rows in `product-decision-register.md` change; the register's change-history advances to 0.9.8. `chanora_storage` ----------------- * New public `Crypto` trait + `IdentityFileStore::crypto()` give callers an encrypt / decrypt pair anchored on the per-install 32-byte DEK without exposing the key material. * `IdentityFileStore` keyring-first DEK retrieval (Linux Secret Service via D-Bus, macOS Keychain, Windows Credential Manager, iOS Keychain via the `keyring` crate). Pre-existing `identity.dek` files are opportunistically migrated into the keyring on first run; the on-disk DEK copy is removed once the keyring acknowledges. `CHANORA_DISABLE_KEYRING=1` forces the file-fallback path for tests and headless / CI hosts where a real keyring call would prompt the user or block on a missing D-Bus session. * `BookmarkRepository::with_crypto(dir, crypto)` encrypts the server password into a new `password_blob` BLOB column under the same per-install DEK. Schema v2 migration is idempotent — legacy v0.4 rows with a plain `password TEXT` are read transparently and lifted into `password_blob` on the next `update()`. `BookmarkRepository::new` (no crypto) is preserved for tests and as a documented fallback when the DEK is unreachable. * Storage tests rise from 8 to 10: encrypted bookmark password round-trip + legacy-plaintext-bookmark upgrade. `chanora_core` -------------- * `ChanoraSession::init_storage(dir)` wires the bookmark repository with crypto by default. On any crypto-derivation failure it falls back to the plain-password repository and logs the gap — better than hard-failing init. * `supervisor_loop` now tracks a 64-bit `snapshot_signature` over channels (id + parent + order + name) and clients (id + channel + name) instead of the old `(channel_count, client_count)` tuple. Any in-channel client move, channel rename, or reorder now fires `SessionEvent::SnapshotChanged`. The signature sorts by id before hashing so it's stable under input-vector reordering. * Two new unit tests cover the signature behaviour; new `tests/mvp_storage.rs` integration test drives `ChanoraSession::init_storage` end-to-end and verifies the bookmark `password_blob` does not contain the plaintext. * Re-export `ChannelId` + `ClientId` from `chanora_protocol` so downstream callers and tests can construct DTOs directly. Flutter ------- * New About dialog (info icon in the AppBar) surfaces DEC-018 (public name "Chanora"), DEC-019 (non-affiliation statement), and DEC-020 (Apache-2.0 OR MIT dual license). New ARB keys in `app_en.arb` and `app_zh.arb`: `aboutAction`, `aboutVersion`, `aboutNonAffiliation`, `aboutLicenseHeading`, `aboutLicenseBody`, `aboutThirdPartyHeading`, `aboutThirdPartyBody`. * `pubspec.yaml` version bumps to `1.0.0-rc.1+5`. Governance ---------- * `docs/governance/legal-review-readiness.md` — DEC-012 handoff package. Enumerates trademark / non-affiliation / license-text / third-party-attribution / `tsclientlib`-posture / crypto- export / data-handling items the legal reviewer must confirm, and lists the concrete engineering deliverables they block on (`cargo about generate`, `cargo deny check licenses`, Flutter `LicenseRegistry` dump). * `docs/governance/staged-release-plan.md` — DEC-002 channel schedule. Linux + Android sideload promote to GA on DEC-012 sign-off; Play Store / Windows / macOS / iOS gate on per- platform signed-build availability. Rollback policy included. * `product-decision-register.md` change-history advances to 0.9.8 with a single entry summarising v0.3, v0.4, and v1.0-rc.1 progress against DEC-001. No decision rows mutate. Build + ops ----------- * `NOTICE` refreshed for the MVP product-code dependency set: adds `chacha20poly1305`, `rand`, `zeroize`, `base64`, `keyring`, `connectivity_plus`, `path_provider`, `freezed_annotation`; drops PoC-only entries. * `CHANGELOG.md` restructured: explicit version sections for v0.3.0-beta.1, v0.4.0-beta.2, v1.0.0-rc.1. Previous "Unreleased" contents migrated into their respective milestone sections. * `.github/workflows/ci.yml` exports `CHANORA_DISABLE_KEYRING=1` for the cargo-test job — CI runners have no D-Bus session and the keyring crate would otherwise block. * `run-chanora.sh` reads `CHANORA_BUNDLE_FLAVOUR` (default `release`) and self-copies the latest cdylib into the bundle's `lib/` if missing. Verification ------------ * `cargo test --workspace` with `CHANORA_DISABLE_KEYRING=1`: all green (49 unit tests across the workspace; up from 36 at v0.4.0-beta.2). * `cargo test -p chanora_core --release -- --ignored alpha_smoke` passes against the live `cn.teamspeak.app` (DNS → connect → snapshot → disconnect in ~2.5 s). * `flutter analyze`: clean. * `cargo build -p chanora_bridge --release` + `flutter build linux --release` produce a working Linux x86_64 bundle. No Android live test in this commit per the user's note that the physical device was removed; the Android arm64-v8a build path is mechanically identical to v0.4.0-beta.2.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# Legal review readiness — DEC-012 sign-off checklist
|
||||
|
||||
| Version | Date | Status |
|
||||
|---|---|---|
|
||||
| 0.1.0 | 2026-05-15 | Initial draft alongside v1.0.0-rc.1 |
|
||||
|
||||
## Purpose
|
||||
|
||||
DEC-012 in `product-decision-register.md` records the legal /
|
||||
trademark / licensing review as the **only** outstanding gate before
|
||||
the MVP public release per DEC-001 sequencing. That decision was
|
||||
accepted as a *release gate* on 2026-05-14; the actual review work
|
||||
has not been performed.
|
||||
|
||||
This document is the engineering-side handoff package for that
|
||||
review. It enumerates exactly what the reviewer needs to confirm,
|
||||
points to the artefacts in this repository that answer each item,
|
||||
and lists the work the reviewer must perform that the engineering
|
||||
side cannot.
|
||||
|
||||
Engineering does **not** make legal decisions. Items marked
|
||||
"engineering: done" mean the underlying technical artefact is in
|
||||
place; the corresponding legal confirmation is still required.
|
||||
|
||||
## Scope
|
||||
|
||||
Reviewer is expected to confirm or correct each of the following
|
||||
before `v1.0.0-rc.1` is promoted to `v1.0.0` and any release
|
||||
artefact is published publicly or to a store.
|
||||
|
||||
### 1. Trademark — "Chanora"
|
||||
|
||||
* **DEC-018** accepted "Chanora" as the public product name.
|
||||
* Engineering: name appears in `Cargo.toml`, `pubspec.yaml`, the
|
||||
About dialog, the AppBar title via the `appTitle` localisation
|
||||
key, and every commit message.
|
||||
* **Reviewer action**:
|
||||
- Trademark registrability check in target jurisdictions (CN, US,
|
||||
EU at minimum, per DEC-002 target platforms' user base).
|
||||
- Confirm no conflicting registration in voice-communication
|
||||
software / mobile-app categories.
|
||||
- Issue go / no-go ruling. A no-go ruling triggers a rename which
|
||||
invalidates `v1.0.0-rc.1` and forces a new RC.
|
||||
|
||||
### 2. Non-affiliation statement — TeamSpeak
|
||||
|
||||
* **DEC-019** accepted the working wording:
|
||||
> Chanora is independent and is not affiliated with, endorsed by,
|
||||
> sponsored by, or officially associated with TeamSpeak.
|
||||
* Engineering: that exact sentence ships in:
|
||||
- `NOTICE` (top of file).
|
||||
- `README.md` `## License and trademark` section.
|
||||
- The in-app About dialog (English: `aboutNonAffiliation` ARB key;
|
||||
Chinese Simplified: `aboutNonAffiliation` in `app_zh.arb`,
|
||||
translated by an engineer — translation should be reviewed for
|
||||
legal precision).
|
||||
* **Reviewer action**:
|
||||
- Confirm the English wording is sufficient under target-market
|
||||
consumer-protection and unfair-competition statutes.
|
||||
- Confirm the Chinese-Simplified translation does not weaken the
|
||||
statement.
|
||||
- Confirm there is no remaining text anywhere in the product that
|
||||
could imply affiliation (search hints: "TeamSpeak", "official",
|
||||
"endorsed").
|
||||
|
||||
### 3. Trademark usage — "TeamSpeak"
|
||||
|
||||
The product documentation and UI strings reference "TeamSpeak" in
|
||||
several places where we describe interoperability (e.g.
|
||||
"TeamSpeak-compatible servers"). This is nominative use.
|
||||
|
||||
* **Reviewer action**:
|
||||
- Confirm each occurrence of "TeamSpeak" in user-facing strings,
|
||||
documentation, and store metadata is permissible nominative
|
||||
use under target-jurisdiction trademark law.
|
||||
- Recommend a `™` or `®` symbol convention if required.
|
||||
|
||||
### 4. License posture — Chanora's own code
|
||||
|
||||
* **DEC-020** accepted dual-license **Apache-2.0 OR MIT**.
|
||||
* Engineering: the texts ship as `LICENSE-APACHE` and `LICENSE-MIT`
|
||||
at the repository root; the aggregator `LICENSE` references both.
|
||||
Cargo-level package manifests carry `license.workspace = true`
|
||||
pointing to `Apache-2.0 OR MIT` in the workspace `Cargo.toml`.
|
||||
* **Reviewer action**:
|
||||
- Confirm the dual-license declaration is consistent with all
|
||||
contributor agreements (none in place yet — see open items).
|
||||
- Confirm `LICENSE` file contents satisfy each app store's source-
|
||||
code-availability and inbound-license requirements.
|
||||
|
||||
### 5. Third-party license posture — direct dependencies
|
||||
|
||||
* `NOTICE` enumerates the direct dependency list as of v1.0.0-rc.1.
|
||||
* Each direct dependency is permissively licensed
|
||||
(`MIT`, `Apache-2.0`, `MIT OR Apache-2.0`, `BSD-3-Clause`).
|
||||
No GPL / LGPL / AGPL surfaces in the direct set.
|
||||
* **Reviewer action**:
|
||||
- Confirm the `NOTICE` enumeration matches what the build tooling
|
||||
actually links (the audit must be repeated against a `cargo
|
||||
about generate --workspace` output and a Flutter
|
||||
`LicenseRegistry` dump as of the release build).
|
||||
- Confirm each direct dependency's attribution obligations are
|
||||
satisfied (Apache-2.0 requires a copy of the license text, the
|
||||
NOTICE entry, and a list of changes in any modified copies).
|
||||
- Confirm no copyleft transitive dependency creeps in via
|
||||
`tsclientlib` or `cpal`. The most likely failure mode is a
|
||||
crypto / DSP subdep with LGPL coverage; `cargo deny` config
|
||||
should refuse those.
|
||||
|
||||
### 6. `tsclientlib` posture specifically
|
||||
|
||||
The project pins `tsclientlib` to a specific commit
|
||||
(`04aa249` on `https://github.com/ReSpeak/tsclientlib`). The crate is
|
||||
upstream-licensed `MIT OR Apache-2.0`. It implements the
|
||||
TeamSpeak 3 protocol from publicly observed behaviour, not from
|
||||
TeamSpeak proprietary sources.
|
||||
|
||||
* **Reviewer action**:
|
||||
- Confirm linking against `tsclientlib` does not by itself create
|
||||
a derivative-work obligation under TeamSpeak's own licenses or
|
||||
EULAs.
|
||||
- Confirm using `tsclientlib` to talk to third-party
|
||||
TeamSpeak-protocol servers does not create a trademark or
|
||||
contract-tort exposure.
|
||||
|
||||
### 7. Crypto + secure-storage compliance
|
||||
|
||||
* `chacha20poly1305` (Apache-2.0 OR MIT) provides envelope
|
||||
encryption for the identity at rest and bookmark passwords.
|
||||
* `keyring` (Apache-2.0 OR MIT) hits the platform Secret Service /
|
||||
Keychain / Credential Manager for the DEK.
|
||||
* No symmetric or asymmetric primitive other than the above is
|
||||
introduced by Chanora's own code; `tsclientlib` carries its own
|
||||
protocol-level crypto.
|
||||
* **Reviewer action**:
|
||||
- Confirm export-control posture for the resulting binary
|
||||
(cryptography category determination, ECCN, any EAR self-
|
||||
classification needed for store distribution).
|
||||
- Confirm any privacy-statement updates required by jurisdictions
|
||||
that treat persistent device identifiers as personal data.
|
||||
|
||||
### 8. Data handling — DEC-016 / DEC-017
|
||||
|
||||
* **DEC-016** No automatic diagnostic upload. The `export_diagnostics`
|
||||
bridge function is invoked only on user action and the redacted
|
||||
output is local-only (Clipboard or share-sheet).
|
||||
* **DEC-017** Crash reporting disabled. Repository grep for
|
||||
`sentry|crashlytics|bugsnag` returns zero hits as of v1.0.0-rc.1.
|
||||
* Engineering: diagnostics redaction is enforced at write-time by
|
||||
the in-bridge `RedactingLogLayer`; tests
|
||||
`chanora_diagnostics::tests::*` cover the policy.
|
||||
* **Reviewer action**:
|
||||
- Confirm privacy policy text aligns: no telemetry, no automatic
|
||||
upload, no crash reporting in MVP.
|
||||
- Confirm app-store privacy-label entries are consistent.
|
||||
|
||||
### 9. Store-listing copy
|
||||
|
||||
Out of scope for engineering; reviewer drafts and validates per
|
||||
DEC-002 staged platform list:
|
||||
|
||||
- Google Play Store (Android arm64-v8a)
|
||||
- Apple App Store (iOS, MVP gate)
|
||||
- Microsoft Store / direct (Windows)
|
||||
- Mac App Store / direct (macOS)
|
||||
- Linux (direct distribution; no store)
|
||||
|
||||
## Open engineering work blocking sign-off
|
||||
|
||||
These are concrete items that engineering must close before the
|
||||
reviewer's work can complete. They do **not** require legal input
|
||||
themselves — they are listed here so the reviewer's scope is clear.
|
||||
|
||||
1. Produce a `cargo about generate --workspace` output checked into
|
||||
`docs/security/`.
|
||||
2. Produce a Flutter `LicenseRegistry` dump for the release build
|
||||
checked into the same path.
|
||||
3. Wire `cargo deny check licenses` into CI with a deny-list of
|
||||
GPL / LGPL / AGPL / commercial source licenses.
|
||||
4. Confirm iOS and macOS build artefacts can ship (DEC-002 staged
|
||||
release allows deferring these; today neither has a live build).
|
||||
|
||||
## Out-of-scope
|
||||
|
||||
The following are *not* part of DEC-012 and have their own owners
|
||||
and decisions:
|
||||
|
||||
* Cryptographic primitive selection (`chacha20poly1305`, key sizes,
|
||||
KDF choice) — Security Architect; closed by DEC-013.2.
|
||||
* Codec choice (Opus) — Software Architect.
|
||||
* TLS / connection security — falls inside `tsclientlib`.
|
||||
Reference in New Issue
Block a user