Applies the gen2 desktop-PTT review summary
(`gen2/chanora-desktop-ptt-review-summary-v0.9.2.md`) to our doc set
with the owner rulings PTT-OPEN-001 through PTT-OPEN-006 resolved as
accepted decisions DEC-023 through DEC-028:
* DEC-023 Windows Global PTT P0 / MVP
* DEC-024 macOS Global PTT P0 / MVP with permission UX
* DEC-025 Linux officially-tested env: GNOME on Wayland only
* DEC-026 Mouse side buttons supported (Win + macOS; Linux portal)
* DEC-027 PTT diagnostics: capability + availability only, no
raw key codes ever
* DEC-028 Missed-key-up watchdog: P0
Requirements (SysRS / SRS) and architecture (SysDes / SAD / SDD)
gain the desktop-PTT ID set the gen2 summary describes:
SysRS-296..302 -> SysDes-142..148
-> SRS-195..203
-> SAD-071..079
-> SDD-081..092
ID totals advance from 295 / 141 / 194 / 70 / 80 to 302 / 148 / 203
/ 79 / 92. The strict layered sourcing rule (`SRS -> SysDes` only,
`SAD -> SRS` only, `SDD -> SAD` only) is preserved; the
`tools/validate_docs.py` validator reports zero undefined refs and
zero direct-layer-rule violations.
New document:
* `docs/architecture/desktop-ptt-architecture.md` — capability
ladder (L0Focused, L1GlobalShortcut, L2GlobalHoldToTalk,
L3GlobalWithMouseButtons, L4DeviceAware reserved), Windows /
macOS / Linux strategies, privacy rule, audio-gate rule,
missed-key-up watchdog, release-readiness evidence requirement,
traceability summary.
Doc addenda (Baseline Candidate 0.9.3):
* `privacy/privacy-policy.md` — no raw key history, capability-
dependent Global PTT, UI reflects actual runtime capability
* `security/threat-model.md` — THREAT-PTT-001..006
* `security/diagnostic-redaction-audit-report.md` —
REDACT-PTT-001..006 banned field list enforced by `PttSanitizer`
* `release/platform-release-policy.md` — per-platform evidence
fields, no over-claim on untested Linux compositors
* `release/release-readiness-go-nogo-record.md` — RR-PTT-001..008
release-readiness items
* `verification/swe4-unit-verification-plan.md` —
SWE4-UV-035..039
* `verification/swe5-software-integration-verification-plan.md` —
SWE5-IV-015
* `verification/swe6-software-verification-plan.md` — SWE6-SV-017
* `verification/sys4-system-integration-verification-plan.md` —
SYS4-SIV-016
* `governance/traceability-matrix.md` — full PTT trace rows +
verification map
* `governance/decision-impact-assessment.md` — DEC-023..028
impact matrix
* `governance/product-decision-register.md` v0.9.9 entry
recording DEC-023..028 in the decision table and the status
table at §7
* `governance/document-index.md` — adds
`desktop-ptt-architecture.md` to the controlled set
* `architecture/proof-of-concept-plan.md` —
PoC-PTT-001..005 platform items
* `references/external-references.md` — Windows Raw Input,
macOS event-tap, Linux GlobalShortcuts portal references
* Both validation reports
(`baseline-candidate-validation-report.md`,
`repo-format-validation-report.md`) bumped to v0.9.3 with the
new ID totals (302 / 148 / 203 / 79 / 92).
README §"Desktop Push-to-Talk" added between Architecture Overview
and Repository Layout: capability levels, per-platform strategy,
privacy posture, missed-key-up watchdog.
Tooling:
* `tools/validate_docs.py` copied from the gen2 zip into the
repo tree (was previously available only inside the zip).
Reports zero undefined refs, zero direct-layer-rule violations,
English-only CJK check passes. The 35 "old package-style
filename" hits are pre-existing and identical to the gen2
baseline (they live in `path-migration-map.md` and config-ID
headers of governance docs and are intentional per the path
migration policy).
* `.gitignore` adds `/gen2/` so the externally-provided review
package does not enter the repo.
No code changes in this commit; B (the implementation split into
`transmit_active` / `capture_active`, `PttCapabilityLevel`
reporting, `PttSanitizer` diagnostics rule, and the UI capability
badge) follows in a separate commit.
9.3 KiB
Sec Diagnostic Redaction Audit Report V0.9.3.0.0
Document type: Security / Diagnostic Redaction Audit Report
Version: 0.9.3
Status: Baseline Candidate
Language: English
Product: Chanora
Repo path: docs/security/diagnostic-redaction-audit-report.md ---
1. Purpose
This report records evidence that Chanora logs and diagnostic exports do not leak sensitive information.
2. Sensitive Data Redaction Policy
| Data category | Default diagnostic behavior |
|---|---|
| Server password | Must redact |
| Identity private key / identity secret | Must redact |
| Authentication tokens if later added | Must redact |
| Secure-storage keys | Must redact |
| Server address | Redact or minimize according to release policy |
| Channel names | Redact or include only with explicit user consent |
| Client nicknames | Redact or include only with explicit user consent |
| Chat messages | Exclude by default unless a future explicit opt-in policy is approved |
| Local file paths | Minimize or redact user-identifying segments |
| Device IDs | Redact or hash if collected |
| IP addresses | Redact or minimize according to release policy |
3. Diagnostic Surfaces
| Surface | Risk | Required control |
|---|---|---|
| Application log | Secret leakage | Redaction filter and structured logging discipline |
| Protocol log | Hostile or sensitive server content | Redaction and length limits |
| Audio diagnostics | Device privacy | Device name minimization if needed |
| Export bundle | Aggregated sensitive data | Redaction audit before release |
| Error report | Stack trace or secret context | User-safe error mapping |
| User support copy/paste | Over-sharing | Explicit review and confirmation |
4. Redaction Test Matrix
| Test ID | Input | Expected output | Status | Evidence |
|---|---|---|---|---|
| REDACT-TC-001 | Server password in connection data | Password replaced by [REDACTED] |
PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_001_server_password_in_connection_data |
| REDACT-TC-002 | Identity secret in storage error | Secret absent | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_002_identity_secret_in_storage_error (via KnownSecretRegistry) |
| REDACT-TC-003 | Server URL with password-like field | Secret part redacted | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_003_server_url_with_password_field — only the password value is redacted, the host and other query params keep flowing |
| REDACT-TC-004 | Chat text in diagnostic export | Excluded by default | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_004_chat_text_excluded_by_default — default policy sets include_chat = false |
| REDACT-TC-005 | Channel name with Unicode | Preserved only if permitted; otherwise redacted safely | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_005_channel_name_with_unicode_excluded_by_default — default policy excludes; UTF-8 preservation verified in TC-010 |
| REDACT-TC-006 | Nickname with Unicode | Preserved only if permitted; otherwise redacted safely | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_006_nickname_with_unicode_preserved_in_safe_field |
| REDACT-TC-007 | Local file path | User-identifying segments redacted or minimized | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_007_local_file_paths_user_segment_minimized — Linux /home/<user>/, Windows C:\Users\<user>\, macOS /Users/<user>/ all minimized |
| REDACT-TC-008 | Diagnostic bundle with mixed sensitive fields | All sensitive fields redacted | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_008_diagnostic_bundle_with_mixed_sensitive_fields — whole-bundle JSON scan finds no plaintext |
| REDACT-TC-009 | Long hostile protocol string | Truncated or safely escaped | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_009_long_hostile_protocol_string_truncated — MAX_PROTOCOL_STRING_LEN = 256 cap with …[truncated] marker |
| REDACT-TC-010 | Multilingual safe diagnostic text | Unicode preserved | PoC Pass | poc/diagnostics-redaction-spike/tests/redaction.rs::redact_tc_010_multilingual_safe_text_preserved — Chinese, Japanese, Korean, and Latin-diacritic text preserved verbatim |
5. Export Bundle Contents
| Bundle item | Included? | Redaction rule | Status |
|---|---|---|---|
| App version | Yes | None | PoC Pass (DiagnosticBundle.app_version preserved verbatim) |
| Build number | Yes | None | PoC Pass (DiagnosticBundle.build_number preserved verbatim) |
| Platform info | Yes | Minimize device details | PoC Pass — flows through Redactor::redact_text, so embedded paths/usernames are minimized |
| Connection state | Yes | No secrets | PoC Pass — flows through Redactor::redact_text |
| Server address | Yes (redacted) | Redact/minimize | PoC Pass — passwords inside ts3server:// URLs redacted |
| Channel tree | No by default | Redact/minimize | PoC Pass — default include_channel_tree = false |
| Chat history | No by default | Exclude unless explicit policy changes | PoC Pass — default include_chat = false |
| Logs | Yes | Redacted | PoC Pass — each log line flows through Redactor::redact_text |
| Audio diagnostics | Yes | No audio content | PoC Pass — only device names are exported; no PCM |
| Secure storage data | No | Never include | PoC Pass by construction — the redactor has no path that reads from SecretStorageRepository; the host application must never put secret material into the bundle in the first place |
6. Findings
| Finding ID | Severity | Description | Status | Owner |
|---|---|---|---|---|
| REDACT-FIND-001 | Informational | The PoC regex catalogue covers the documented audit matrix but is not exhaustive. Production chanora_diagnostics should add fuzz testing and adversarial inputs (e.g. base64 lookalikes, unicode confusables, regex evasion). |
Open | Security Reviewer + chanora_diagnostics owner |
| REDACT-FIND-002 | Informational | The PoC redactor is a post-processor over strings. Production code should wire the redactor as a tracing-subscriber layer so redaction happens at write-time, not by re-walking text afterward. |
Open — to be addressed when chanora_diagnostics is scaffolded |
chanora_diagnostics owner |
| REDACT-FIND-003 | Informational | The KnownSecretRegistry defence-in-depth requires the secure-storage layer to register secrets when they materialise. The cross-spike contract is documented but not yet enforced by any product code. |
Open — to be enforced by chanora_storage calling into chanora_diagnostics. |
chanora_storage + chanora_diagnostics owners |
7. Approval
| Role | Name | Decision | Date |
|---|---|---|---|
| Security Reviewer | TBD | Pending | TBD |
| Privacy Reviewer | TBD | Pending | TBD |
| QA / Verification Owner | TBD | Pending | TBD |
8. Change History
| Version | Date | Description |
|---|---|---|
| 0.9.0 | 2026-05-14 | Initial diagnostic redaction audit report template. |
Baseline Candidate 0.9.1 Update
| Version | Date | Description |
|---|---|---|
| 0.9.1 | 2026-05-14 | Updated baseline after product decision closure: Apple App Store SDK gate uses Xcode 26+ and iOS 26 / iPadOS 26 SDK+ since 2026-04-28, platform baselines and decision traceability propagated across the document set. |
Baseline Candidate 0.9.2 Update
| Version | Date | Description |
|---|---|---|
| 0.9.2 | 2026-05-14 | Corrected Apple App Store Connect upload gate to 2026-04-28 and checked full-package naming, references, and coverage. |
Baseline Candidate 0.9.3 Update
| Version | Date | Description |
|---|---|---|
| 0.9.3 | 2026-05-14 | Recorded PoC empirical evidence: REDACT-TC-001..010 status set to PoC Pass with evidence pointers to poc/diagnostics-redaction-spike/tests/redaction.rs. Export bundle policy §5 populated for every row. Findings REDACT-FIND-001..003 added (regex coverage limits, tracing-layer integration gap, KnownSecretRegistry cross-spike contract). |
Desktop Push-to-Talk Redaction Addendum (Baseline Candidate 0.9.3)
Per SysRS-302 / SRS-202 / SAD-077 / SDD-090, the redaction policy adds the following rules for desktop PTT diagnostics:
| Rule | Banned field name | Disposition |
|---|---|---|
| REDACT-PTT-001 | key_code |
Drop record. |
| REDACT-PTT-002 | scan_code |
Drop record. |
| REDACT-PTT-003 | virtual_key, vk |
Drop record. |
| REDACT-PTT-004 | keysym, keysym_string |
Drop record. |
| REDACT-PTT-005 | key_sequence, key_press_history, key_timing |
Drop record. |
| REDACT-PTT-006 | Free-form message strings shall not embed key values; offending records shall be reformatted by the originating backend before emission. |
Drop record. |
The PttSanitizer tracing_subscriber::Layer decorates RedactingLogLayer and is the enforcement point. Fields whose names match the banned list cause the entire record to be dropped — Chanora does not attempt to redact-in-place because partial-redaction false negatives are riskier than a missing line.
Permitted fields for PTT diagnostics: capability_level, backend_id, bound_input_class, fallback_exercised.
| Version | Date | Description |
|---|---|---|
| 0.9.3 | 2026-05-15 | Added desktop PTT redaction rules REDACT-PTT-001..006: ban raw key codes, scan codes, virtual-key values, keysyms, and key timing sequences from logs and exports. |