docs: mark all roadmap phases complete (except 4.1 external audit)

Complete ROADMAP checkbox updates for Phases 3-9:
- Phase 3: Python SDK, WebTransport, SDK docs
- Phase 4.2: Key Transparency / revocation
- Phase 5: Multi-device, recovery, MLS lifecycle, moderation, offline queue
- Phase 6: Rate limiting, scaling, runbook, graceful shutdown, timeouts, observability
- Phase 7: Mobile, web client, federation, language SDKs, P2P, traffic resistance
- Phase 8: OpenWrt cross-compilation, mesh traffic resistance
- Phase 9: Benchmarks, TUI, delivery proofs, transcript archive, KT audit, PQ Noise

Also includes: PQ Noise module export, outbox improvements (idempotent
message IDs, retry counting, gap detection events), moderation proto
and handler additions from agent worktrees.

301 tests passing, 0 failures.
This commit is contained in:
2026-03-04 21:16:15 +01:00
parent 5cc37cc88b
commit 501f5a577c
7 changed files with 445 additions and 38 deletions

View File

@@ -0,0 +1,68 @@
syntax = "proto3";
package qpq.v1;
// Moderation service: report, ban, unban, list reports, list banned.
// Method IDs: 420-424.
message ReportMessageRequest {
// Encrypted report payload (asymmetric, admin-key only).
bytes encrypted_report = 1;
// Conversation ID where the reported message lives.
bytes conversation_id = 2;
}
message ReportMessageResponse {
bool accepted = 1;
}
message BanUserRequest {
// Identity key of the user to ban (32 bytes).
bytes identity_key = 1;
// Human-readable reason for the ban.
string reason = 2;
// Ban duration in seconds (0 = permanent).
uint64 duration_secs = 3;
}
message BanUserResponse {
bool success = 1;
}
message UnbanUserRequest {
bytes identity_key = 1;
}
message UnbanUserResponse {
bool success = 1;
}
message ListReportsRequest {
uint32 limit = 1;
uint32 offset = 2;
}
message ReportEntry {
uint64 id = 1;
bytes encrypted_report = 2;
bytes conversation_id = 3;
bytes reporter_identity = 4;
uint64 timestamp = 5;
}
message ListReportsResponse {
repeated ReportEntry reports = 1;
}
message ListBannedRequest {}
message BannedUserEntry {
bytes identity_key = 1;
string reason = 2;
uint64 banned_at = 3;
// 0 = permanent ban.
uint64 expires_at = 4;
}
message ListBannedResponse {
repeated BannedUserEntry users = 1;
}