Files
chanora/docs/governance/legal-review-readiness.md
T
EdisonJwa 50768a8f48 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.
2026-05-15 02:24:42 +08:00

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`.