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.
192 lines
8.0 KiB
Markdown
192 lines
8.0 KiB
Markdown
# 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`.
|