diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 399219b..c7b23b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,8 @@ jobs: run: cargo fmt --all --check - name: release version alignment run: python3 scripts/check-release-version.py + - name: documentation controls + run: python3 scripts/check-docs.py - name: clippy run: cargo clippy --workspace --all-targets --all-features - name: tests diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6ee1fb..59cac81 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,10 +9,9 @@ Testers can start with the [Alpha testing guide](docs/27-alpha-testing.md); current priorities and evidence language are in the [stabilization program](docs/29-stabilization-program.md). -Komms is currently founder-directed, including intentional use of automated -implementation assistance. Contributions provide ideas, implementation, -testing, and evidence; product and release authority remains with the founder -unless explicitly delegated. +Komms is currently founder-directed. Contributions provide ideas, +implementation, testing, and evidence; product and release authority remains +with the founder unless explicitly delegated. ## Where contributions help @@ -56,11 +55,10 @@ fix does not require advance permission. release gate changes. Documentation claims must distinguish automated build evidence from hands-on device or hardware qualification. - Keep PRs scoped to one concern; cite the spec section your change implements. -- Automated assistance is permitted. The human submitter must understand and - take responsibility for the diff, verify that they have the right to submit - it, check license and provenance concerns, run the applicable tests, and be - able to explain and revise the result. Automated output is not independent - review. +- The human submitter must understand and take responsibility for the diff, + verify that they have the right to submit it, check license and provenance + concerns, run the applicable tests, and be able to explain and revise the + result. ## Process diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 74e5293..25dedfe 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -50,11 +50,10 @@ migration plan, and evidence required for acceptance. Rough consensus is preferred; the lead maintainer makes the final decision and records the reason when consensus is not possible. -Founder-directed automated assistance is an intentional implementation method. -Automated systems are tools, not maintainers, reviewers, or decision-makers. -The human maintainer remains accountable for provenance, scope, review, testing, -acceptance, and public claims. Tool-assisted output is not independent review or -release evidence by itself. +Implementation method does not change accountability. The human maintainer who +approves a change remains accountable for provenance, scope, review, testing, +acceptance, and public claims. Only evidence meeting the published independence +criteria counts as independent review. ## Review and release @@ -79,7 +78,9 @@ and cannot be represented as closed, audited, or independently approved. The lead maintainer currently authorizes releases. A stable release also requires all applicable P0 gates in the [stabilization program](docs/29-stabilization-program.md) to be closed with -published evidence. +published evidence. The current owners, unassigned independent roles, claim +register, gaps, and review dates are recorded in the +[release evidence ledger](docs/31-release-evidence-ledger.md). ## Conflicts, conduct, and appeals @@ -111,6 +112,12 @@ before a stable release. A temporary steward may maintain security and release continuity when the lead maintainer cannot act; permanent authority changes must be publicly recorded. +No backup steward currently exists. The role remains visibly unassigned in +[MAINTAINERS.md](MAINTAINERS.md), and stable release authority remains blocked +until a real person accepts the scope and the credential-recovery procedure is +rehearsed. Repository access or a platform role alone does not confer project +or release authority. + Governance evolution is not automatic. When sustained adoption has produced a real community of users, contributors, reviewers, and operators, the founder may publish a proposal for additional delegated maintainers, a foundation, a diff --git a/MAINTAINERS.md b/MAINTAINERS.md index b82e12e..06ab9c4 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -15,6 +15,29 @@ The lead maintainer is accountable for final decisions under [GOVERNANCE.md](GOVERNANCE.md). Being listed as code owner or maintainer does not make self-review independent. +## Stabilization ownership + +Andri temporarily carries every internal category in the stabilization program. +This records accountability; it does not claim equal expertise or independent +review in every category. + +| Category | Current accountable person | Independence / limit | +|---|---|---| +| FND — founder and release accountability | Andri | Founder authority | +| SEC — core security | Andri (interim) | Self-review is not independent security evidence | +| NET — network and services | Andri (interim) | External operator/field evidence remains unassigned | +| PROD — product and clients | Andri (interim) | External accessibility/field evidence remains unassigned | +| REL — release engineering | Andri (interim) | External reproducibility/release evaluation remains unassigned | +| COM — community and governance | Andri (interim) | No unconflicted backup steward currently exists | +| LEG — legal and brand | Andri (project risk owner only) | Qualified trademark and licensing counsel is unassigned | +| EXT — independent evidence | **Unassigned** | A named external person must accept each scoped assignment | + +The exact P0 assignments, evidence gaps, and next review dates are in the +[release evidence ledger](docs/31-release-evidence-ledger.md). Independent +cryptography review, interoperability implementation, field/accessibility +evaluation, operator review, release verification, trademark advice, and backup +stewardship remain unassigned until a real person accepts the documented scope. + ## Contribution and review needs The project welcomes implementation help and qualified evidence in these areas. @@ -35,13 +58,6 @@ An interested contributor should open a public issue describing the area, relevant experience, and work they would like to contribute. Security-sensitive background details may be sent privately using [SECURITY.md](SECURITY.md). -## Implementation assistance - -The founder intentionally uses automated analysis and implementation tools. -Those tools are not maintainers, reviewers, or independent evidence providers. -Every accepted change remains attributable to and the responsibility of the -human maintainer who approves it. - ## Appointment and expectations Maintainers are appointed by the lead maintainer after a record of constructive diff --git a/README.md b/README.md index 272e7fa..5a74f80 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ private keys belonging to Komms users.* Komms has a nonprofit public-benefit mission: private, resilient communication should be useful to ordinary people without surveillance or exclusive-provider -lock-in. The project is founder-directed and intentionally uses automated -implementation assistance; accountability remains with the human maintainer. +lock-in. The project is founder-directed, and accountability remains with the +human maintainer. **New here?** Read [Start Here](docs/00-start-here.md): the whole idea in plain words, with no cryptography knowledge required. @@ -72,9 +72,10 @@ required. iOS currently remains source/Simulator-only. - **Clearer identity and discovery.** Safety numbers are 30 readable digits while QR verification retains the full 256-bit comparison. Desktop sharing, contact rename, DHT/mDNS status, and conversation rendering are hardened. -- **Four-platform release evidence.** Android and iOS simulators plus local - macOS and Linux desktop previews now require explicit human visual approval. - Linux desktop launch smoke also runs in CI and in the release workflow. +- **Four-platform preview evidence.** Android and iOS simulators plus local + macOS and Linux desktop previews now require explicit visual approval. Linux + desktop launch smoke also runs in CI and in the release workflow. This is not + physical-device or stable-platform qualification. - **A release-shaped self-hosted node.** The public `kultd` image is prepared for Linux amd64 and arm64 with provenance, an SBOM, and immutable `0.3.0` tagging. @@ -95,7 +96,7 @@ independent interoperability. | **Applications and messaging** | Desktop, Android, and iOS shells expose pairwise/group text and a broad Alpha feature set, including attachments, local organization, linked devices, ephemeral content, polls, roles, and direct audio-call paths. CI and simulator evidence exist; hands-on device, background lifecycle, NAT, accessibility, and localization qualification remain. | | **Distribution** | Unsigned desktop packages and a debug-signed Android APK are published for Alpha testing; iOS is source/Simulator-only. Production signing, authenticated updates, reproducibility measurements, store distribution, upgrade/rollback qualification, and stable support are not configured. | | **Optional mobile convenience** | ADR-0017 through ADR-0019 propose reversible post-pairing rendezvous and content-free native wake. The layer is design-only: no optional service is implemented or required by the sovereign core. | -| **Trust and governance** | The project is founder-directed by design during construction and stabilization under a nonprofit public-benefit mission. The founder retains product and release authority. Independent security and interoperability evidence is still missing; automated assistance is not presented as independent review. The [stabilization program](docs/29-stabilization-program.md) defines the evidence required before stable claims. | +| **Trust and governance** | The project is founder-directed by design during construction and stabilization under a nonprofit public-benefit mission. The founder retains product and release authority. Independent security and interoperability evidence is still missing. The [stabilization program](docs/29-stabilization-program.md) defines the evidence required before stable claims. | Older `KKR1` through `KKR6` backups remain restorable; current backups are `KKR7`. KKR6 added signed group authority state and consumed admin-request ids. @@ -111,7 +112,12 @@ gates, and the first 90 days. The [roadmap](docs/08-roadmap.md) remains the engineering inventory, the [feature delivery plan](docs/12-feature-delivery-plan.md) remains the product backlog, and the [local release gate](docs/24-local-release-gate.md) describes existing build -checks. +checks. The [stable-v1 product profile](docs/30-stable-v1-product-profile.md) +freezes the release target, the +[release evidence ledger](docs/31-release-evidence-ledger.md) records every P0 +gate and stable claim, and the +[name-risk decision](docs/32-name-risk-decision.md) records the founder's +keep-and-monitor decision without claiming legal clearance. Komms is built on four principles: @@ -171,6 +177,9 @@ status of any particular proposal. | [27: Alpha Testing](docs/27-alpha-testing.md) | Download verification, installation, smoke testing, issue reporting, and self-hosted image quick start | | [28: Brand System](docs/28-brand-system.md) | Cross-shell product character, tokens, hierarchy, and pragmatic name-risk monitoring | | [29: Stabilization Program](docs/29-stabilization-program.md) | Canonical evidence vocabulary, trust gates, owners, and 90-day sequence | +| [30: Stable-v1 Product Profile](docs/30-stable-v1-product-profile.md) | Frozen install, messaging, bounds, recovery, delivery, platform, service, and exclusion contract | +| [31: Release Evidence Ledger](docs/31-release-evidence-ledger.md) | P0 and stable-claim owners, evidence, revisions, gaps, and review dates | +| [32: Name-risk Decision](docs/32-name-risk-decision.md) | Dated keep-and-monitor decision, observed overlap, migration cost, cadence, and advice triggers | | [ADRs](docs/adr/README.md) | Decision index, status, and the alternatives each decision beat | ## Stack @@ -179,8 +188,9 @@ Rust workspace (`kult-crypto` / `kult-protocol` / `kult-transport` / `kult-store `kult-node` / `kultd` / `kult-ffi`), UniFFI bindings, Tauri desktop app, native mobile shells. Layout in [Architecture §7](docs/03-architecture.md). Implemented so far: -`kult-crypto` (hybrid PQXDH, Double Ratchet with encrypted headers, anonymous sealed -boxes, sealed state, sender-key group chains), `kult-protocol` (envelopes, padding +`kult-crypto` (hybrid PQXDH, Double Ratchet with encrypted headers, +sender-anonymous sealed envelopes, sealed state, sender-key group chains), +`kult-protocol` (envelopes, padding buckets, fragmentation + NACKs, delivery tokens, sealed group headers, `.kkb` bundles), and `kult-store` (encrypted SQLite, key hierarchy, persistent queue), `kult-transport` (the `Transport` contract, the diff --git a/SECURITY.md b/SECURITY.md index 72238b1..81d897d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,6 +23,40 @@ These are targets rather than a 24/7 support guarantee. If you receive no acknowledgment, resend with `[Komms security]` in the subject. There is currently no bounty program; do not incur expense in expectation of payment. +## Incident handling + +The founder is the current security coordinator and incident decision owner. +There is no 24/7 team or accepted backup security steward. That continuity gap +is tracked in [MAINTAINERS.md](MAINTAINERS.md) and the +[release evidence ledger](docs/31-release-evidence-ledger.md). + +For a confirmed vulnerability or operational incident, the coordinator: + +1. opens a private, access-limited incident record with discovery time, affected + revisions/services, reporter preference, known impact, and evidence custody; +2. classifies urgency and decides containment without exposing report details + through public issues, logs, or ordinary diagnostics; +3. identifies affected releases, protocol versions, operators, credentials, and + user actions, including whether signing, service, domain, or notification + channels remain trustworthy; +4. prepares and validates the smallest safe correction, key/service rotation, + rollback, or disabling action, recording every deferred platform or external + dependency; +5. coordinates disclosure with the reporter and publishes an advisory with + affected versions, impact, fixes, workarounds, credits, and residual risk; +6. notifies known official operators and users through authenticated project + release/advisory channels when action is required; and +7. publishes a post-incident process summary when doing so will not expose + reporters, users, credentials, or still-exploitable detail. + +The incident owner may make an emergency release or disable an official +project-operated service within the authority in +[GOVERNANCE.md](GOVERNANCE.md). Emergency action does not waive release +evidence: missing checks and independent review remain explicit, and the +evidence ledger records follow-up and closure. If the founder has a conflict, +the project seeks an unconflicted external reviewer; none is currently assigned +in advance. + ## Ground rules - Coordinated disclosure: please allow the initial assessment window and agree diff --git a/apps/android/README.md b/apps/android/README.md index a1d17cf..9aebe20 100644 --- a/apps/android/README.md +++ b/apps/android/README.md @@ -12,7 +12,7 @@ own, verbatim. before each activity draws. Compliant screenshots, screen recordings, and recent-task previews are blocked. Settings show the shared B14 policy and its compromised-device, overlay/accessibility-abuse, and external-camera limits. -- **Request private keyboard behavior on every text editor.** Every audited XML +- **Request private keyboard behavior on every inventoried text editor.** Every covered XML and programmatic field uses `IncognitoEditText`, which sets Android's no-personalized-learning and no-suggestions metadata. Passphrases and recovery mnemonics are masked. Settings state honestly that third-party IMEs may ignore @@ -81,13 +81,15 @@ own, verbatim. used. Generic files show and recheck F4 before explicit send/discard. JPEG/PNG selections use the shared Rust editor for orientation normalization, free/preset crop, 90-degree rotation, and user-positioned blur/pixelation, then - review and send only the exact metadata-free PNG. Originals, intermediates, + review and send only the exact PNG re-encoded without source metadata. + Originals, intermediates, and protected receiver previews are deleted on send, discard, denial, failure, activity stop/lock, low storage, and restart orphan recovery. - **Record pairwise or group audio messages** with runtime microphone consent, a foreground-only stop/review flow, no autoplay, locally derived duration/waveform, and explicit send/discard. Every native capture is rewritten - to the shared metadata-free mono 16-bit PCM WAV / 16 kHz / 60-second profile + to the shared source-metadata-omitting mono 16-bit PCM WAV / 16 kHz / + 60-second profile and enters the existing F3 pipeline. Audio-focus loss, activity stop, lock, failure, discard, and restart remove plaintext cache files; completed clips are probed and exported only into short-lived app-private playback files. F4 is @@ -141,7 +143,8 @@ own, verbatim. Native rows and pins render the sealed icon or generated initials; the manager offers all eight bundled glyphs, Android SAF JPEG/PNG selection, clear-to- fallback, and quota usage. Selected content is copied only into a short-lived - app-private file before the shared core emits a metadata-free 256×256 RGBA PNG. + app-private file before the shared core emits a 256×256 RGBA PNG re-encoded + without source metadata. The 512 KiB/1,024-record/64 MiB limits and corrupt fallback are shared with every shell; `KKR7` and authenticated own-device C2 sync are the only portability paths, and no icon creates network, @@ -226,7 +229,8 @@ and Swift: exact vocabulary/roles, first-run System, idempotency, restart, preference cache carries no identity, message, contact, or network data. Custom-icon acceptance drives the shared B13 fixture through Rust RPC, UniFFI, -Kotlin, and Swift: all four exact target types, canonical metadata-free output, +Kotlin, and Swift: all four exact target types, canonical PNG output that omits +source metadata, quota accounting, restart/`KKR7`, generated-initials fallback, local events, and zero delivery work. The Android manager uses SAF access only for the explicit selection and deletes its app-private transient after the blocking core call. diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 77de52f..12487af 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -14,7 +14,7 @@ security indicators are the node's own, verbatim. lock path. Capture protection remains honestly best effort because desktop OS, window-server, compositor, privileged-software, and external-camera behavior cannot be controlled universally. -- **Reduce input retention on every editable text control.** All audited controls are +- **Reduce input retention on every inventoried editable text control.** Those controls are semantically classified and receive disabled autocomplete, autocorrect, autocapitalization, and spellcheck at startup and after modal cloning. Passphrases and recovery mnemonics are password inputs. The unlock screen @@ -81,7 +81,7 @@ security indicators are the node's own, verbatim. JPEG/PNG selections enter the shared bounded Rust editor for orientation normalization, free/preset crop, 90-degree rotation, and user-positioned blur or pixelation; the keyboard/screen-reader-accessible dialog reviews the exact - metadata-free final PNG, and only that asset enters F3. Protected originals + final PNG re-encoded without source metadata, and only that asset enters F3. Protected originals and intermediates are cleared on send, discard, failure, hide/lock, shutdown, and restart. Completed edited images render only through validated protected transients. Transfers continue while Komms is open or minimized and resume @@ -89,7 +89,8 @@ security indicators are the node's own, verbatim. - **Record pairwise or group audio messages** only while Komms is visible, stop into a no-autoplay review with duration/waveform and the current F4 carrier explanation, then explicitly send or discard. The shell rewrites every clip - to the shared metadata-free mono 16-bit PCM WAV / 16 kHz / 60-second profile + to the shared source-metadata-omitting mono 16-bit PCM WAV / 16 kHz / + 60-second profile before the existing F3 import. Hiding, locking, interruption, failure, or shutdown stops capture and clears review/plaintext transients; received audio is validated and materialized only for explicit protected local playback. @@ -136,8 +137,9 @@ security indicators are the node's own, verbatim. - **Manage private custom icons** for contacts, groups, folders, and note-to-self. Every row renders the sealed icon or generated initials; the accessible manager offers eight bundled glyphs, local JPEG/PNG selection with centered-square crop, - clear-to-fallback, and quota usage. The shared core emits only metadata-free - 256×256 RGBA PNGs, enforces 512 KiB/1,024-record/64 MiB limits, and safely falls + clear-to-fallback, and quota usage. The shared core emits only 256×256 RGBA + PNGs re-encoded without source metadata, enforces + 512 KiB/1,024-record/64 MiB limits, and safely falls back after corrupt bytes. Icons travel only in `KKR7` or authenticated own-device C2 sync, never URLs, peer sync, envelopes, capabilities, queues, notifications, or transports. @@ -170,7 +172,8 @@ its own `deny.toml`, same posture). The core is reached only through the path dependency on `kult-ffi`. Custom-icon acceptance consumes the shared B13 fixture through the same session -surface the Tauri commands wrap: canonical metadata-free local data URLs, exact +surface the Tauri commands wrap: canonical local data URLs whose PNG omits +source metadata, exact folder/note targets, bundled and selected-image paths, quota accounting, restart/`KKR7`, safe fallback, local events, and zero delivery work. Rust node acceptance independently covers contact and group identities plus corrupt sealed @@ -255,7 +258,7 @@ must never depend on. Store/package-manager channels will carry updates. - The webview is locked down: strict CSP, no Tauri plugins, no filesystem / shell / network capabilities: the frontend reaches the world only - through the audited command surface in `commands.rs`. + through the bounded command surface in `commands.rs`. - The store passphrase exists in the webview only inside the unlock form and crosses IPC once per unlock; it is never persisted by the shell. - QR codes render black-on-white on their own card regardless of theme; diff --git a/apps/desktop/ui/main.js b/apps/desktop/ui/main.js index ce780fb..141ca3d 100644 --- a/apps/desktop/ui/main.js +++ b/apps/desktop/ui/main.js @@ -2732,7 +2732,7 @@ function renderImageReview(root) { const draft = state.imageDraft; root.querySelector('[data-f="image-review"]').src = draft.review.data_url; root.querySelector('[data-f="image-info"]').textContent = - `${draft.review.width} × ${draft.review.height} pixels · ${Number(draft.review.encoded_bytes).toLocaleString()} bytes · exact metadata-free PNG`; + `${draft.review.width} × ${draft.review.height} pixels · ${Number(draft.review.encoded_bytes).toLocaleString()} bytes · PNG re-encoded without source metadata`; const regions = root.querySelector('[data-f="regions"]'); regions.replaceChildren(); draft.recipe.regions.forEach((region, index) => { diff --git a/apps/ios/KommsApp/Sources/AttachmentView.swift b/apps/ios/KommsApp/Sources/AttachmentView.swift index 2bea2ce..7a716f5 100644 --- a/apps/ios/KommsApp/Sources/AttachmentView.swift +++ b/apps/ios/KommsApp/Sources/AttachmentView.swift @@ -582,7 +582,7 @@ private struct AttachmentReviewSheet: View { } else { Label("Preview unavailable", systemImage: "photo") } - Text("\(image.width) × \(image.height) pixels · \(image.encodedBytes) bytes · exact metadata-free PNG") + Text("\(image.width) × \(image.height) pixels · \(image.encodedBytes) bytes · PNG re-encoded without source metadata") .font(.footnote).foregroundStyle(.secondary) TextField("Display filename", text: $filename) .incognitoKeyboard() diff --git a/apps/ios/README.md b/apps/ios/README.md index e18686a..aa18caa 100644 --- a/apps/ios/README.md +++ b/apps/ios/README.md @@ -13,8 +13,9 @@ are the node's own, verbatim. inactive/background transitions, and responds to UIKit capture notifications. Settings explicitly state that iOS cannot universally block still screenshots and that capture notification is not retroactive. -- **Reduce keyboard retention on every SwiftUI editor.** Every audited text editor - disable autocorrection through one audited modifier; message/name fields keep +- **Reduce keyboard retention on every inventoried SwiftUI editor.** Every + covered text editor disables autocorrection through one shared modifier; + message/name fields keep only explicit capitalization semantics. Passphrases and recovery mnemonics use `SecureField`. Settings state that iOS has no per-field personalized-learning guarantee and non-secure third-party keyboards remain best effort. @@ -81,7 +82,8 @@ are the node's own, verbatim. permission is required. Generic files show and recheck F4 before explicit send/discard. JPEG/PNG selections use the shared Rust editor for orientation normalization, free/preset crop, 90-degree rotation, and user-positioned blur - or pixelation, then review and send only the exact metadata-free PNG. + or pixelation, then review and send only the exact PNG re-encoded without + source metadata. Originals, intermediates, receiver previews, and protected export sources are cleaned on send, discard, denial, failure, background/lock, low storage, and restart. The UI states iOS's actual lifecycle contract: work continues only @@ -90,7 +92,7 @@ are the node's own, verbatim. and foreground-only capture, then stop into a no-autoplay review with locally derived duration/waveform and an F4 carrier explanation before explicit send or discard. AVFoundation's native recording is canonicalized to the shared - metadata-free mono 16-bit PCM WAV / 16 kHz / 60-second profile before F3 + source-metadata-omitting mono 16-bit PCM WAV / 16 kHz / 60-second profile before F3 import. Interruption, route change, background, lock, view teardown, failure, discard, and restart clean the Data-Protection-complete transient; received clips are validated and materialized only for explicit protected playback. @@ -143,7 +145,8 @@ are the node's own, verbatim. SwiftUI rows and pins render the sealed icon or generated initials; the VoiceOver/Dynamic-Type manager offers all eight bundled glyphs, security- scoped Files JPEG/PNG selection, clear-to-fallback, and quota usage. The shared - core produces only metadata-free 256×256 RGBA PNGs and enforces the 512 KiB, + core produces only 256×256 RGBA PNGs re-encoded without source metadata and + enforces the 512 KiB, 1,024-record, and 64 MiB caps with safe corrupt fallback. Portability is limited to `KKR7` and authenticated own-device C2 sync; icons never enter iCloud sync, URLs, peers, envelopes, @@ -233,7 +236,8 @@ non-synchronizing `UserDefaults` cache contains only the pre-unlock theme token; it is not a portability or backup channel. Custom-icon acceptance uses the same B13 fixture as Rust RPC, UniFFI, and -Kotlin, covering all exact target kinds, canonical metadata-free PNG output, +Kotlin, covering all exact target kinds, canonical PNG output that omits source +metadata, quota accounting, restart/`KKR7`, safe initials fallback, local events, and zero delivery work. Security-scoped Files access lasts only for the explicit blocking import call; no selected path or plaintext image becomes synchronized state. diff --git a/docs/00-start-here.md b/docs/00-start-here.md index 874a8d1..59db6b2 100644 --- a/docs/00-start-here.md +++ b/docs/00-start-here.md @@ -27,10 +27,10 @@ Three things make it different from the messengers you know: supported route, working devices, power, configuration, and sometimes radio hardware. 3. **You are not a phone number.** No number, no email, no account, no sign-up. Your - identity is a cryptographic key created on your own device. Nobody can ban your - Komms account, because there is no centrally administered Komms account. - Networks, app stores, and device owners can still deny access to their own - resources. + identity is a cryptographic key created on your own device. There is no + centrally administered Komms account for one operator to deactivate. + Contacts can block an identity, and networks, app stores, service operators, + and device owners can deny access to their own resources. ## What do the crypto words mean? @@ -54,7 +54,8 @@ shutdowns when a supported alternate path remains. **It cannot protect**: a phone that is already hacked or taken from you unlocked; the fact that a radio transmission physically happened (radio can be detected); you, if the person you message shares your messages; or all timing/network metadata -when you enable an optional convenience service. No honest tool claims otherwise. +when you enable an optional convenience service. No honest privacy claim says +otherwise. Our full, frank list is in the [threat model](02-threat-model.md). ## Can I use it today? diff --git a/docs/01-why.md b/docs/01-why.md index 80a7d72..966b2c0 100644 --- a/docs/01-why.md +++ b/docs/01-why.md @@ -58,16 +58,19 @@ The empty niche Komms targets: contact + chosen durable mailbox operators + direct/local/mesh paths, with no optional project service required to communicate ([03: Architecture](03-architecture.md)). -2. **Off-grid as a first-class transport**, not a demo: commodity Meshtastic LoRa radios - give kilometers of range and multi-hop store-and-forward when networks are shut down - or shut off ([05: Transports](05-transports.md)). +2. **Off-grid as an implemented Alpha transport**, not yet a field-qualified + claim: Komms supports Meshtastic LoRa adapters and bounded multi-hop + store-and-forward. Actual range, background behavior, and two-radio operation + remain environment- and hardware-dependent release evidence + ([05: Transports](05-transports.md)). 3. **Modern cryptographic constructions, conservatively assembled**: hybrid post-quantum key agreement (X25519 + ML-KEM-768), Double Ratchet with encrypted headers, XChaCha20-Poly1305, and sealed-sender delivery. The primitives and constructions are published; their combination in Komms is not yet independently audited or independently interoperable ([04: Cryptography](04-cryptography.md)). -4. **No identifiers**: identity is a keypair you mint yourself +4. **No mandatory registration identifiers**: identity is a keypair you mint + yourself, without a required phone number, email address, or real name ([06: Identity & Trust](06-identity-trust.md)). ## Who it's for diff --git a/docs/08-roadmap.md b/docs/08-roadmap.md index 7bc50ed..2d30b69 100644 --- a/docs/08-roadmap.md +++ b/docs/08-roadmap.md @@ -483,26 +483,26 @@ B2 recorded audio is implemented end to end on top of that unchanged F3/F4 path. Desktop, Android, and iOS record only while foregrounded, stop into a local review with no autoplay, show locally derived duration/waveform and the current carrier explanation, and require explicit send or discard. All three canonicalize to one -metadata-free profile—mono signed 16-bit little-endian PCM WAV at 16 kHz, bounded -to 60 seconds / 1,920,044 bytes—and deliver exact bytes pairwise or through the -encrypt-once sender-key group flow. Protected playback and failure, interruption, -lock, restart, and orphan cleanup are covered. The ADR-0015 invariant remains -absolute: mesh-only recorded audio waits for a faster link and emits zero bulk -airtime frames. +source-metadata-omitting profile—mono signed 16-bit little-endian PCM WAV at +16 kHz, bounded to 60 seconds / 1,920,044 bytes—and deliver exact bytes pairwise +or through the encrypt-once sender-key group flow. Protected playback and +failure, interruption, lock, restart, and orphan cleanup are covered. The +ADR-0015 invariant remains absolute: mesh-only recorded audio waits for a faster +link and emits zero bulk airtime frames. B16 still-image editing is implemented end to end without changing F3, F4, wire metadata, crypto, or transport behavior. One path-based Rust/UniFFI helper owns the 32 MiB / 4096-edge / 12-megapixel decode limits, EXIF-orientation -normalization, integer crop/quarter-turn/region semantics, metadata-free RGBA -PNG output, and create-new protection. Desktop, Android SAF, and iOS +normalization, integer crop/quarter-turn/region semantics, RGBA PNG output that +omits source metadata, and create-new protection. Desktop, Android SAF, and iOS security-scoped pickers all stage protected app-private originals, show the exact final asset, support free/preset crop, rotation, and user-positioned blur or pixelation, and require explicit send or discard. Only the canonical final enters F3; cleanup covers denial, cancellation, failure, low storage, background/lock, shutdown, and restart orphans. Generic non-image files now show and atomically recheck the same authoritative F4 explanation. Pairwise and sender-key group -acceptance proves exact bytes, metadata removal, wrapper determinism, protected -receiver rendering/export, and zero manifest/chunk/range or other bulk mesh +acceptance proves exact bytes, source metadata omission, wrapper determinism, +protected receiver rendering/export, and zero manifest/chunk/range or other bulk mesh airtime. Video, cloud/generative editing, filters, face recognition, project files, and protocol changes remain out of scope. @@ -547,9 +547,10 @@ The F5 sealed local-metadata foundation is implemented in `kult-store`: typed an bounded conversation, folder, pin, label, draft, preference, and custom-icon records use an isolated storage key and reveal no local organization keys in a copied database. User-authored metadata and sealed note-to-self history are -included in current `KKR7` backups. Note-to-self text is implemented through every shell under one -reserved identity; folders, conversation pins, labels, appearance, and bounded -metadata-free custom icons now ship as separate local experiences. +included in current `KKR7` backups. Note-to-self text is implemented through +every shell under one reserved identity; folders, conversation pins, labels, +appearance, and bounded custom icons re-encoded without source metadata are +implemented as separate local experiences. B5 private contact rename is implemented end to end through `kult-node`, strict RPC/CLI, UniFFI, desktop, Android, and iOS. The peer key remains the only identity @@ -566,10 +567,11 @@ B13 private custom icons are implemented end to end across the existing F5 recor `kult-node`, RPC/CLI, UniFFI, desktop, Android, and iOS. Exact contact, group, folder, and note-to-self targets render generated initials when absent or after a safe read failure. Eight bundled glyphs and selected local JPEG/PNG inputs become -strict 256×256 RGBA PNGs after bounded orientation/crop/resize and metadata-free -re-encoding. Per-record, count, and 64 MiB aggregate quotas are enforced at the -sealed-store boundary; `KKR7` preserves canonical records. Icons create no remote -lookup, peer sync, envelope, capability, queue, notification, or transport work. +strict 256×256 RGBA PNGs after bounded orientation/crop/resize and re-encoding +that omits source metadata. Per-record, count, and 64 MiB aggregate quotas are +enforced at the sealed-store boundary; `KKR7` preserves canonical records. Icons +create no remote lookup, peer sync, envelope, capability, queue, notification, +or transport work. B10 private local conversation folders are implemented end to end across the unchanged F5 record contract, `kult-node`, RPC/CLI, UniFFI, desktop, Android, diff --git a/docs/11-feature-scope.md b/docs/11-feature-scope.md index e23fd9e..c3eb40f 100644 --- a/docs/11-feature-scope.md +++ b/docs/11-feature-scope.md @@ -31,8 +31,9 @@ status and prerequisites are tracked in the delivery plan. - **Text and audio messages.** Both are implemented. Recorded audio is an asynchronous encrypted F3 attachment, never a live call: every shell records - the same bounded metadata-free mono PCM WAV profile, requires local review and - explicit send/discard, and derives duration/waveform only on the endpoint. + the same bounded mono PCM WAV profile that omits source metadata, requires + local review and explicit send/discard, and derives duration/waveform only on + the endpoint. F4 explains the current carrier at confirmation. Under ADR-0015's hard rule, a mesh-only route holds every audio clip for a faster link and emits zero bulk airtime frames. @@ -93,7 +94,7 @@ status and prerequisites are tracked in the delivery plan. - **Custom icons.** Implemented for contacts, groups, folders, and note-to-self over the sealed F5 record and every wrapper/shell. Missing records render generated initials; eight bundled glyphs and selected local JPEG/PNG inputs become exact - metadata-free 256×256 RGBA PNGs after orientation normalization and square + 256×256 RGBA PNGs that omit source metadata after orientation normalization and square crop. Animated/decompression-heavy inputs fail closed. Limits are 512 KiB per icon, 1,024 records, and 64 MiB aggregate; reads safely fall back after corrupt or legacy non-canonical bytes. Portability is limited to `KKR7` and authenticated @@ -120,7 +121,8 @@ status and prerequisites are tracked in the delivery plan. - **Local still-image editing.** Implemented across desktop, Android, and iOS through one bounded Rust helper: JPEG/PNG orientation normalization, free/preset crop, 90-degree rotation, and manual blur/pixelation are applied *before* encryption. - The exact metadata-free PNG is reviewed and is the only asset sealed; protected + The exact PNG re-encoded without source metadata is reviewed and is the only + asset sealed; protected originals and intermediates are cleaned locally. No protocol involvement. - **Mentions.** Group mentions are implemented through explicit current-roster pickers and canonical typed content, diff --git a/docs/12-feature-delivery-plan.md b/docs/12-feature-delivery-plan.md index f76dd53..963a702 100644 --- a/docs/12-feature-delivery-plan.md +++ b/docs/12-feature-delivery-plan.md @@ -482,7 +482,8 @@ generated initials. Users can instead choose one of eight bundled glyphs content-verified local JPEG/PNG. The shared node normalizes EXIF orientation, rejects animated PNG and oversized/decompression-heavy inputs, applies a centered-square or explicit oriented-pixel square crop, resizes to 256×256, and -emits a metadata-free non-interlaced RGBA8 PNG containing only IHDR/IDAT/IEND. +emits a non-interlaced RGBA8 PNG containing only IHDR/IDAT/IEND, with no source +metadata copied. The existing F5 record is now enforced as one icon per exact target, at most 512 KiB each, 1,024 records, and 64 MiB aggregate encoded bytes. Reads verify the @@ -565,7 +566,7 @@ keyboard qualification follows [14: Incognito Keyboard](14-incognito-keyboard.md One path-based Rust/UniFFI helper performs content-verified bounded decoding (32 MiB encoded, 4096 per edge, 12 megapixels), EXIF-orientation normalization, exact integer crop then quarter-turn rotation, ordered user-positioned blur or -pixelation, and deterministic metadata-free RGBA PNG encoding. Output is +pixelation, and deterministic RGBA PNG encoding that omits source metadata. Output is create-new and re-probed before F3 import; malformed, spoofed, truncated, animated, unsupported, over-dimension, decompression-bomb-like, and overwrite cases fail closed. diff --git a/docs/28-brand-system.md b/docs/28-brand-system.md index 450c651..4ae60cd 100644 --- a/docs/28-brand-system.md +++ b/docs/28-brand-system.md @@ -1,15 +1,12 @@ # Komms product brand system **Name status:** `Komms` is the current project and product name. The project -does not represent it as a registered or legally cleared trademark. Potential -overlap—including `komms.app`—is monitored and documented, but an observed -similar name is not by itself a legal conclusion, automatic rename requirement, -or engineering stop. Under -[stabilization gate P0-02](29-stabilization-program.md), the founder records a -keep, adjust, or rename decision before stable brand and wire identifiers are -frozen, using qualified advice when actual confusion or expansion makes it -proportionate. The product character and accessibility tokens remain reusable -if that decision ever changes. +does not represent it as a registered or legally cleared trademark. The +founder's dated decision is to continue using Komms for now, monitor the +observed `komms.app` overlap monthly, and seek qualified advice on the triggers +in the [name-risk decision](32-name-risk-decision.md). That is a project risk +decision, not legal clearance. The product character and accessibility tokens +remain reusable if the decision changes. The application shells use the same visual language as the public Komms site. The light theme follows `komms.org`; the dark theme follows the technical diff --git a/docs/29-stabilization-program.md b/docs/29-stabilization-program.md index d83b35b..6a3585d 100644 --- a/docs/29-stabilization-program.md +++ b/docs/29-stabilization-program.md @@ -14,12 +14,12 @@ It is the canonical source for stabilization priority. The [feature delivery plan](12-feature-delivery-plan.md) remain useful inventories, but a completion label there does not override a gate here. -Founder-directed, tool-assisted implementation may continue throughout -stabilization. It is a means of production, not independent evidence. -Stabilization freezes what qualifies for a stable release; it does not prevent +Founder-directed implementation may continue throughout stabilization. +Implementation authorship is not independent evidence. Stabilization freezes +what qualifies for a stable release; it does not prevent isolated roadmap work needed to make Komms broadly capable, reliable, accessible, and polished. Experimental breadth must not silently expand the -audited v1 profile or block closure of its trust gates. +stable-v1 profile or block closure of its trust gates. ## 1. Product and architecture contract @@ -109,6 +109,13 @@ not a legal conclusion or engineering veto. Work continues while the founder records a proportionate keep, adjust, or rename decision before stable brand and wire identifiers are frozen. +The current founder decision is to continue using Komms with monthly +monitoring; the limits and escalation triggers are in the +[name-risk decision](32-name-risk-decision.md). The frozen scope is the +[stable-v1 product profile](30-stable-v1-product-profile.md), and every P0 gate +and stable claim is tracked in the +[release evidence ledger](31-release-evidence-ledger.md). + | Gate | Owner | Required evidence | Unlocks | |---|---|---|---| | **P0-01 Honest claims and evidence ledger** | FND + SEC + PROD | Public pages use the vocabulary above; security, deletion, blocking, legal-policy, platform, and feature-status claims cite their limits and evidence. A release-scoped ledger links every stable claim to a revision and artifact. | Stable marketing and release notes | diff --git a/docs/30-stable-v1-product-profile.md b/docs/30-stable-v1-product-profile.md new file mode 100644 index 0000000..efd62ac --- /dev/null +++ b/docs/30-stable-v1-product-profile.md @@ -0,0 +1,301 @@ +# Stable-v1 product profile + +**Status:** frozen release target; not a statement that Komms is stable + +**Decision date:** 2026-07-26 + +**Accountable owner:** Andri, founder and lead maintainer + +**Change control:** a material expansion or weakening requires an ADR, an +updated claim entry in the [release evidence ledger](31-release-evidence-ledger.md), +and founder approval + +Komms stable-v1 is an everyday private messenger with a deliberately bounded +public contract. The product promise remains: + +> **Private messaging that keeps working.** + +That sentence expresses the product direction: Komms keeps queued work and can +try more than one supported route. It is not a promise of universal +availability, guaranteed delivery time, censorship resistance against every +adversary, or operation after every usable device, route, or power source is +lost. + +This profile freezes what may be represented as stable. A feature can exist in +the repository or an Alpha package without joining this profile. Every stable +public statement must use one of the claim identifiers below and must satisfy +the corresponding entry in the +[release evidence ledger](31-release-evidence-ledger.md). + +## 1. Installation and supported systems + +**Claims:** `SV1-C01`, `SV1-C11` + +A stable release is installed from a project-authorized artifact with a +published checksum, production signature where the platform supports one, +provenance, an SBOM, and an authenticated update path or an explicitly bounded +manual-update procedure. Install, upgrade, rollback, recovery from an interrupted +upgrade, and release-key recovery must be exercised from clean systems before +the stable label is used. + +The stable-v1 candidate matrix is: + +| Client family | Candidate architecture and floor | Stable declaration rule | +|---|---|---| +| Android | Android 8.0 / API 26 or newer; `arm64-v8a` | Only named physical device and OS cells recorded as passed are supported. Emulator assembly is build evidence only. | +| iOS | iOS 16 or newer; `arm64` | Only named physical iPhone and iOS cells recorded as passed are supported. Simulator assembly is build evidence only. | +| Windows | Windows 10/11; x86-64 | Only named supported Windows releases with signed installer, install, upgrade, rollback, and lifecycle evidence are supported. | +| macOS | Intel and Apple silicon | The minimum macOS release and every supported hardware/OS cell must be named in the release matrix before stable. | +| Linux desktop | x86-64 | Support is distribution- and version-specific. AppImage, DEB, or RPM availability alone does not imply support for every Linux system. | + +Every combination not present as passed in the published stable release matrix +is unsupported, even if it builds or happens to run. The headless operator +image is a separate Linux amd64/arm64 support profile and does not turn a client +platform into a supported server platform. + +The current unsigned or debug-signed 0.3 packages remain Alpha artifacts and do +not satisfy this section. + +## 2. Identity and contact establishment + +**Claims:** `SV1-C02`, `SV1-C04` + +- A user creates a local cryptographic identity without a required phone + number, email address, real name, or project account. +- The ordinary intentional-contact path is a versioned Connect code exchanged + by QR, link, paste, or file. It contains a random rotatable discovery + capability distinct from the stable account fingerprint. +- A nearby pairing flow works without a project service. A Standard internet + flow may use disclosed, replaceable bootstrap and introduction-mailbox + defaults. +- Public discovery exposes bounded, capability-scoped introduction data and + mailbox routes, not a stable identity-to-current-IP directory. +- A valid cryptographic introduction is a provisional message request, not + consent, a trusted contact, group membership, or permission to spend + unbounded endpoint resources. +- An invitation can provide the fast consent path. Unsolicited contact is + subject to the signed admission policy, hard count/byte/work quotas, and an + explicit Accept, Delete, or Block decision. +- Safety-number comparison remains the out-of-band verification path. Contact + names are local petnames and are not identity. + +The stable implementation must accept the authority, admission, and discovery +decisions in [ADR-0026](adr/0026-revocable-device-authority.md), +[ADR-0030](adr/0030-first-contact-admission.md), and +[ADR-0031](adr/0031-capability-scoped-dht-discovery.md), or superseding ADRs +that close the same threats. The current automatic-contact Alpha path is +outside stable-v1. + +## 3. Pairwise text + +**Claims:** `SV1-C03`, `SV1-C05` + +- Stable-v1 supports authenticated end-to-end encrypted UTF-8 text between two + accepted contacts. +- One canonical v1 text content frame is at most 65,535 bytes, including its + 28-byte header. The exact text payload limit is therefore **65,507 UTF-8 + bytes**. User interfaces must measure bytes, not characters, and reject a + larger value before changing delivery state. +- A send succeeds locally only after the immutable history event, ratchet + transition, per-device delivery state, and durable outbound ciphertext commit + atomically. +- A receive becomes visible only after the receiving ratchet, history, + replay/seen state, receipt state, and source-row acknowledgement commit + atomically. +- Text formatting, when presented, is a bounded inert local projection. The + authenticated source remains text and cannot create links, HTML, scripts, + remote fetches, or executable content. + +Legacy Alpha text may remain readable, but stable-v1 send and receive behavior +uses the declared versioned content and atomic transition contract. + +## 4. Bounded groups + +**Claims:** `SV1-C06` + +- A stable-v1 group contains at most **64 active accounts**. One account may + have at most **8 active linked devices** under the device-authority profile. + Lower operational limits may be selected, but no interface or operator may + raise these protocol ceilings. +- Group text and attachment manifests use one sender-key ciphertext with + recipient-scoped delivery. Delivery remains visible per recipient rather + than collapsing partial delivery into a false group-wide success. +- Every recipient must authenticate the claimed sender account and device for + ordinary messages and author-sensitive events. Membership knowledge alone + is not sufficient authorship evidence. +- Membership changes rotate the applicable sender and recipient-origin + material. Removed members may retain content and keys they already received; + removal is not remote erasure. +- Joining a group is an explicit consent action. Receipt of an invitation does + not expose membership, download media, or create mesh airtime. + +[ADR-0029](adr/0029-recipient-authenticated-groups.md), or a superseding +recipient-verifiable origin design, is required before current sender-key +groups enter stable-v1. Groups larger than 64 accounts and any future MLS +profile are excluded. + +## 5. Bounded attachments + +**Claims:** `SV1-C07` + +Stable-v1 supports one encrypted primary object and at most one optional image +preview per attachment offer: + +| Property | Stable-v1 limit | +|---|---| +| Primary object | 512 MiB / 536,870,912 bytes | +| Preview object | 256 KiB / 262,144 bytes | +| Plain data per chunk | 49,152 bytes | +| Primary chunks | 10,923 maximum | +| Preview chunks | 6 maximum | +| Manifest | 1,024 bytes maximum | +| Filename hint | 255 UTF-8 bytes maximum | +| Media-type hint | 127 lowercase ASCII bytes maximum | +| Active media objects | 8 inbound and 8 outbound per peer; 32 globally | +| Default media-store quota | 2 GiB | +| Default incomplete-media quota | 1 GiB | + +Attachment acceptance is explicit. Chunks authenticate independently, resume +after interruption, and remain excluded from airtime-budgeted mesh carriers. +The filename and media type are untrusted hints. A received file is not +described as safe, is never opened automatically, and is exported or opened +only after an explicit user action and a platform-qualified protected-file +transition. + +Image and audio preparation may create a canonical output that omits source +metadata, but Komms does not call a file “metadata-free”: dimensions, duration, +format fields, filesystem data, traffic observations, and recipient-created +copies can still exist. Malware detection, cloud scanning, and remote deletion +are not stable-v1 claims. + +## 6. Backup, recovery, and linked authority + +**Claims:** `SV1-C08` + +- A user can export one encrypted, versioned backup and a newly generated + 24-word recovery mnemonic. Restore refuses to overwrite an existing profile. +- The stable backup carries the account identity, contacts, ordinary retained + history, eligible local organization, group authority, and the accepted + device-authority chain. +- Ratchet state, group sender/receiver chains, one-time prekeys, reusable device + private credentials, live ephemeral plaintext/media, calls, and queued + outbound runtime work do not become portable backup state. Restored contacts + re-handshake. +- The account root is an offline recovery authority and is absent from routine + live-device stores and link packages. Ordinary device changes use a strict + majority of the previous active device set; loss of that majority requires + explicit root recovery. +- Root recovery revokes the previous active set, creates one fresh recovery + device, rotates relationship capabilities, and makes conflicts visible. +- A stable release includes clean-device backup/restore, lost-device, + old-backup, stolen-device, manifest-fork, recovery-conflict, and failed-restore + evidence on supported platforms. + +Current `KKR7` round trips are Alpha implementation evidence. They are not the +frozen stable backup format because the copied-root authority flaw in +[ADR-0026](adr/0026-revocable-device-authority.md) remains open. + +## 7. Blocking and deletion + +**Claims:** `SV1-C09`, `SV1-C14` + +Block is an explicit sealed local rule bound to the exact account/device +identity. It removes local provisional state, pending invitations, queued local +copies, and that relationship's rendezvous/wake capabilities, and prevents new +ordinary contact or group-invite state from that identity. It does not: + +- erase content already received by another person or device; +- revoke an identity globally; +- make a remote operator delete ciphertext; +- prove that screenshots, exports, backups, notifications, filesystem + snapshots, or flash remnants are gone; or +- stop a blocked person from creating a different identity. + +Deleting history removes the live logical record and Komms-owned references +from the current profile. Local storage applies best-effort remnant reduction, +but the user-facing statement is “removed from this Komms history,” never +forensic or remote erasure. + +Mute, Delete, Reject, and Block remain distinct actions. Optional reputation +lists must be signed, scoped, expiring, inspectable, and user-overridable; they +are not a hidden global ban service. + +## 8. Delivery semantics + +**Claims:** `SV1-C10`, `SV1-C13` + +| User-visible state | Exact meaning | +|---|---| +| **Scheduled** | Retained locally for a future activation time; no ratchet or transport work has occurred. | +| **Queued** | The local atomic transition retained the history event and durable outbound ciphertext; no next hop has accepted it. | +| **Sent** | A direct endpoint or store-and-forward next hop accepted bounded custody under its declared contract. This does not prove recipient receipt or reading. | +| **Delivered** | An authenticated end-to-end receipt from the intended recipient device was accepted. It does not mean read. | +| **Delivery failed after 30 days** | No end-to-end receipt arrived before the bounded retry window ended. History remains; automatic queue retention ended. | + +Stable direct acceptance occurs only after bounded durable endpoint admission, +not a volatile RAM queue. Stable mailbox acceptance occurs only after a durable +v2 deposit; collection leases rows and deletes only exact rows acknowledged +after endpoint commit. Duplicate delivery is absorbed without duplicate +history, and the sender retains its original ciphertext until the encrypted +end-to-end receipt or terminal retry result. + +No delivery state promises latency. A user can remain unreachable when all +configured operators, routes, radios, carried files, devices, or power sources +are unavailable or blocked. + +## 9. Optional services and pure-core operation + +**Claims:** `SV1-C12`, `SV1-C15` + +The stable profile distinguishes: + +- **Core roles:** capability-scoped DHT discovery and durable mailboxes. Users + may choose or self-host their bootstrap peers and mailbox operators. +- **Optional convenience:** post-pairing rendezvous and content-free native + wake. Removing them may reduce speed or mobile convenience but does not change + message format, identity, or the end-to-end trust root. +- **Standard mode:** may ship disclosed, replaceable project defaults for easy + first use. +- **Sovereign mode:** disables project-operated optional services and retains + manual, community, local, radio, file, and self-hosted routes. + +No service receives message/media plaintext or user Komms identity private +keys. That is not a claim that an operator sees nothing: addresses, timing, +volume, opaque locators/tokens, live memory, service keys, availability, and +provider telemetry can remain visible. A malicious operator can suppress, +replay, delay, correlate, or refuse work within those limits. + +The **Private** mode label remains outside stable-v1 until its non-collusion, +OHTTP placement, operator independence, lifecycle, and field evidence are +published. A RAM-backed discovery service is not a durable mailbox. One +founder-operated deployment is not plural infrastructure. + +Official project operation follows the nonprofit public-benefit mission in +[ADR-0033](adr/0033-nonprofit-founder-stewardship.md). This is project policy, +not registered-charity status and not a restriction on independent AGPL +commercial use. + +## 10. Exclusions + +The following may remain implemented, experimental, or planned, but are not +part of the stable-v1 public contract unless this profile is formally revised: + +- live audio or video calls; +- groups above 64 active accounts, MLS, public communities, and broadcast + channels; +- anonymous messaging, metadata invisibility, traffic-analysis resistance, or + protection from a global passive adversary; +- remote or forensic erasure, screenshot prevention, or permanent suppression + of a person who creates another identity; +- guaranteed delivery, guaranteed background execution, or operation through + every block, outage, device loss, or jammer; +- disappearing/view-once content, edits, polls, roles, moderation, semantic + mentions, linked-device convenience, and advanced local organization as + required golden-path features; +- Freenet-style carriers, cross-protocol federation, cryptocurrency-dependent + operation, or mandatory project infrastructure; +- independent-audit, independent-interoperability, production-readiness, or + high-risk-user claims until the exact evidence gate closes. + +Excluded features must be visibly labelled Alpha or experimental, remain +isolated from the stable golden path, and fail without weakening this profile. diff --git a/docs/31-release-evidence-ledger.md b/docs/31-release-evidence-ledger.md new file mode 100644 index 0000000..5ed3187 --- /dev/null +++ b/docs/31-release-evidence-ledger.md @@ -0,0 +1,112 @@ +# Release evidence ledger + +**Ledger date:** 2026-07-26 + +**Release scope:** stable-v1 candidate + +**Current evidence baseline:** [`main@4fda544`](https://github.com/AndriGitDev/Komms/tree/4fda544739c0665b6a324256d858c16c1d73d992) + +**Baseline automated run:** [`a02b064`, CI run 197](https://github.com/AndriGitDev/Komms/actions/runs/30199264838); +this successful PR-head tree is the tree merged by PR #77 + +**Release-control run:** [`25daa69`, CI run 199](https://github.com/AndriGitDev/Komms/actions/runs/30202463092); +all nine jobs passed on draft PR #78 + +**Accountable release owner:** Andri (`@AndriGitDev`) + +**Stable release decision:** not authorized; all P0 gates remain open + +**Next ledger review:** 2026-08-09 + +This is the canonical release-scoped ledger required by P0-01. It records +evidence; it does not turn a design, test, or founder review into independent +assurance. Links to repository tests identify the current evidence source. +Closure requires retained run output tied to an exact revision and environment, +plus every named external artifact. + +Andri temporarily owns founder and internal project categories. Every +independent role is explicitly **Unassigned** until a named external person +accepts it and the assignment is recorded in +[MAINTAINERS.md](../MAINTAINERS.md). + +## 1. P0 gate ledger + +| Gate | Accountable owner | Current control evidence | Status and open gaps | Revision / artifacts | Next review | +|---|---|---|---|---|---| +| **P0-01 Honest claims and evidence ledger** | Andri (FND; interim SEC/PROD) | Designed: vocabulary, frozen claim register, and this ledger exist; the repository documentation check passed in release-control CI. | **Open.** External website and repository-description corrections remain; no stable release evidence bundle exists. | [Stabilization vocabulary](29-stabilization-program.md#2-evidence-vocabulary); [stable-v1 profile](30-stable-v1-product-profile.md); [CI run 199](https://github.com/AndriGitDev/Komms/actions/runs/30202463092); this ledger; [public-copy follow-up](#4-public-copy-audit) | 2026-08-09 | +| **P0-02 Name-risk assessment and recorded decision** | Andri (FND and project risk owner); qualified trademark counsel: **Unassigned** | Designed: dated founder decision, observed overlap, migration cost, cadence, and escalation triggers recorded. | **Open.** This is not legal clearance. No qualified similarity/class/jurisdiction opinion or trademark/asset policy exists. | [Name-risk decision](32-name-risk-decision.md); [brand system](28-brand-system.md) | 2026-10-26, or trigger event | +| **P0-03 Stabilized core product profile** | Andri (FND; interim PROD/SEC) | Designed: product boundary, bounds, supported-system rule, services, and exclusions frozen. | **Open.** ADR-0026 through ADR-0032 remain proposed; atomic paths beyond ordinary pairwise receive remain incomplete; profile has not passed field or independent review. | [Stable-v1 profile](30-stable-v1-product-profile.md); [P0 ADR index](adr/README.md) | 2026-08-09 | +| **P0-04 Clean-install and real-network golden path** | Andri (interim NET/PROD); independent field evaluator: **Unassigned** | Implemented with local/CI evidence for internet components and shells. | **Open.** No qualified default bootstrap/mailbox, clean-device distinct-NAT matrix, default-blackhole journey, replacement operator, or pure-core journey. | [Internet tests](../crates/kult-node/tests/internet_e2e.rs); [Alpha guide](27-alpha-testing.md); [ADR-0034](adr/0034-operator-minimized-reference-discovery.md) | 2026-08-09 | +| **P0-05 Unsolicited-contact abuse admission** | Andri (interim SEC/NET/PROD); independent adversarial/usability evaluator: **Unassigned** | Designed, with automated evidence for interim byte/count bounds. | **Open.** No pre-KEM admission, durable request inbox, consent promotion, identity block implementation, or adversarial/field evidence. Current first contact can create normal contact state. | [ADR-0030](adr/0030-first-contact-admission.md); [transport bounds](05-transports.md); [protocol tests](../crates/kult-protocol/tests/protocol.rs) | 2026-08-09 | +| **P0-06 Independent crypto and protocol assurance** | Andri (interim SEC); independent cryptography reviewer: **Unassigned**; independent interoperability implementer: **Unassigned** | Automated evidence for local KATs, properties, sessions, and protocol decoding. | **Open.** No external vectors, separate implementation, review scope, findings report, disposition, or residual-risk statement. P0 protocol/security ADRs remain proposed. | [Baseline CI](https://github.com/AndriGitDev/Komms/actions/runs/30199264838); [Crypto KATs](../crates/kult-crypto/tests/kat.rs); [properties](../crates/kult-crypto/tests/properties.rs); [session tests](../crates/kult-crypto/tests/session.rs); [cryptography spec](04-cryptography.md) | 2026-08-09 | +| **P0-07 Signed and recoverable distribution** | Andri (interim REL/SEC); independent release evaluator: **Unassigned** | Implemented Alpha packaging with checksums; some workflow provenance/SBOM paths exist. | **Open.** Stable desktop/mobile signing, protected release-key recovery, authenticated updates, reproducibility measurements, clean install/upgrade/rollback, store/repository publication, and external verification are missing. | [Release runbook](25-release-runbook.md); [release workflow](../.github/workflows/release.yml); [0.3 Alpha artifacts](https://github.com/AndriGitDev/Komms/releases/tag/v0.3.0) | 2026-08-09 | +| **P0-08 Durable mailbox and operator qualification** | Andri (interim NET/SEC); independent operator evaluator: **Unassigned** | Implemented Alpha mailbox-v1 behavior with automated bounds and end-to-end receipt tests. | **Open.** Mailbox v1 can delete before endpoint custody. Persistent v2 deposits, leases, restart/disk-full/overload/expiry/multi-operator evidence, published operator policy, and maintained self-hosting cost model are missing. | [ADR-0032](adr/0032-leased-mailbox-delivery.md); [node mailbox tests](../crates/kult-node/tests/mailbox_e2e.rs); [transport mailbox tests](../crates/kult-transport/tests/mailbox.rs) | 2026-08-09 | +| **P0-09 Field qualification across supported claims** | Andri (interim PROD/NET/REL); independent accessibility/field evaluator: **Unassigned** | Implemented shells and automated host, simulator, and packaging evidence. | **Open.** No published named-device/OS/NAT/background/handoff/accessibility/recovery/two-radio matrix. macOS and Linux stable support cells are not frozen. | [Local release gate](24-local-release-gate.md); [HIL bench](10-hil-bench.md); [candidate platform rule](30-stable-v1-product-profile.md#1-installation-and-supported-systems) | 2026-08-09 | +| **P0-10 Accountable founder authority, review, and incidents** | Andri (FND; interim COM/SEC); independent reviewers and backup steward: **Unassigned** | Implemented as public governance, ownership, security intake, recusal, release authority, and incident policy. | **Open.** No accepted backup steward, independent sensitive-surface reviewers, rehearsed incident record, or continuity handoff. Founder self-review is not independent. | [Governance](../GOVERNANCE.md); [maintainers](../MAINTAINERS.md); [security and incidents](../SECURITY.md); [CODEOWNERS](../.github/CODEOWNERS); [ADR-0033](adr/0033-nonprofit-founder-stewardship.md) | 2026-08-09 | + +## 2. Stable public claim register + +These are the complete stable public claims authorized by the frozen profile. +The quoted wording is the strongest stable wording permitted after its evidence +closes. Until then, public copy must use the current evidence level and disclose +the listed gap. A new stable claim requires a new identifier here. + +| Claim | Stable wording | Owner | Current evidence level | Revision / artifacts | Open gaps | Next review | +|---|---|---|---|---|---|---| +| **SV1-C01 Distribution** | Supported Komms clients install, update, and recover through authenticated release paths. | Andri (REL/SEC); external release evaluator: **Unassigned** | Implemented Alpha packaging only | [0.3 release](https://github.com/AndriGitDev/Komms/releases/tag/v0.3.0); [release runbook](25-release-runbook.md) | P0-07 signing, updates, rollback, reproducibility, and key recovery | 2026-08-09 | +| **SV1-C02 Local identity** | Komms identity can be created without a required phone number, email address, real name, or project account. | Andri (SEC/PROD); external reviewer: **Unassigned** | Automated evidence | [Identity design](06-identity-trust.md); [node e2e](../crates/kult-node/tests/node_e2e.rs); [FFI e2e](../crates/kult-ffi/tests/ffi_e2e.rs) | Independent protocol review and supported-platform clean-install evidence | 2026-08-09 | +| **SV1-C03 Pairwise confidentiality and authenticity** | Accepted contacts exchange authenticated end-to-end encrypted pairwise text; intermediaries receive sealed envelopes rather than message plaintext. | Andri (SEC); external cryptography reviewer: **Unassigned** | Automated evidence | [`main@4fda544`](https://github.com/AndriGitDev/Komms/tree/4fda544739c0665b6a324256d858c16c1d73d992); [KATs](../crates/kult-crypto/tests/kat.rs); [node e2e](../crates/kult-node/tests/node_e2e.rs) | P0-06 external vectors/review/interoperability; remaining atomic transitions under ADR-0028 | 2026-08-09 | +| **SV1-C04 Contact establishment** | Intentional Connect codes and bounded message requests establish contact without making a project service the identity authority. | Andri (SEC/NET/PROD); external evaluators: **Unassigned** | Designed | [ADR-0030](adr/0030-first-contact-admission.md); [ADR-0031](adr/0031-capability-scoped-dht-discovery.md) | Implement, accept, adversarially test, and field-qualify v2 contact flow | 2026-08-09 | +| **SV1-C05 Pairwise text bounds and atomicity** | One stable-v1 text event carries at most 65,507 UTF-8 bytes and changes visible/delivery state only through its complete atomic transition. | Andri (SEC/PROD); external reviewer: **Unassigned** | Automated evidence for the bound and one receive slice; full claim designed | [Content codec](../crates/kult-protocol/src/content.rs); [ADR-0028](adr/0028-atomic-protocol-commits.md); [node e2e](../crates/kult-node/tests/node_e2e.rs) | Pairwise send, handshake, receipt, failure injection, and independent review | 2026-08-09 | +| **SV1-C06 Bounded groups** | Stable-v1 groups support at most 64 active accounts and authenticate the claimed sender separately for every recipient. | Andri (SEC/PROD); external reviewer: **Unassigned** | Automated evidence for current bounded groups; required origin property designed | [Group tests](../crates/kult-node/tests/groups_e2e.rs); [ADR-0029](adr/0029-recipient-authenticated-groups.md) | Implement recipient origin, atomic group transitions, upgrade path, malicious-member evidence, and independent review | 2026-08-09 | +| **SV1-C07 Bounded attachments** | Consented attachments use authenticated resumable chunks, a 512 MiB primary limit, a 256 KiB preview limit, and no bulk airtime carrier. | Andri (SEC/PROD/NET); external reviewer and field evaluator: **Unassigned** | Automated evidence | [ADR-0015](adr/0015-encrypted-attachment-pipeline.md); [protocol constants](../crates/kult-protocol/src/attachment.rs); [attachment e2e](../crates/kult-node/tests/attachments_e2e.rs); [media store tests](../crates/kult-store/tests/media.rs) | Accept ADR-0015 or successor; atomic transition coverage; protected-file device matrix; independent review | 2026-08-09 | +| **SV1-C08 Backup and recovery** | A versioned encrypted backup restores eligible user state on a clean supported device while live protocol secrets reset; offline account-root recovery replaces a lost device set. | Andri (SEC/PROD); external reviewer and field evaluator: **Unassigned** | Automated evidence for KKR7 round trips; stable authority designed | [Storage contract](07-storage.md#4-backup--portability); [backup tests](../crates/kult-store/tests/backup.rs); [backup e2e](../crates/kult-node/tests/backup_e2e.rs); [ADR-0026](adr/0026-revocable-device-authority.md) | Offline-root implementation, format freeze, conflict/stolen-device tests, clean-device field matrix, independent review | 2026-08-09 | +| **SV1-C09 Blocking** | Blocking is an exact local identity rule that removes local relationship capabilities and state without claiming remote erasure or global identity revocation. | Andri (SEC/PROD); external abuse/usability evaluator: **Unassigned** | Designed | [ADR-0030](adr/0030-first-contact-admission.md#4-accept-reject-block-and-invite-are-explicit-state-transitions); [profile boundary](30-stable-v1-product-profile.md#7-blocking-and-deletion) | Implement block state/transitions across carriers, groups, capabilities, restore, and supported clients; adversarial/usability evidence | 2026-08-09 | +| **SV1-C10 Honest delivery** | Queued means durable local custody, sent means bounded next-hop custody, and delivered requires an authenticated end-to-end receipt; none means read. | Andri (SEC/NET/PROD); external evaluator: **Unassigned** | Automated evidence for current ladder; stable custody designed | [Architecture lifecycle](03-architecture.md#3-message-lifecycle); [transport semantics](05-transports.md); [node e2e](../crates/kult-node/tests/node_e2e.rs); [ADR-0032](adr/0032-leased-mailbox-delivery.md) | Durable direct admission, mailbox v2, crash matrix, operator and real-network qualification | 2026-08-09 | +| **SV1-C11 Supported platforms** | The stable release supports only the named device, OS, architecture, lifecycle, install, upgrade, and accessibility cells published as passed. | Andri (PROD/REL); independent field/accessibility evaluator: **Unassigned** | Implemented shells with automated build/simulator evidence | [Platform rule](30-stable-v1-product-profile.md#1-installation-and-supported-systems); [release gate](24-local-release-gate.md) | P0-09 named physical matrix and exact macOS/Linux support cells | 2026-08-09 | +| **SV1-C12 Replaceable services** | Standard defaults are disclosed and replaceable; no project service is the user identity authority or receives message plaintext or user identity private keys. | Andri (NET/SEC/FND); external operator reviewer: **Unassigned** | Designed; pure-core components implemented | [Stabilization contract](29-stabilization-program.md#1-product-and-architecture-contract); [ADR-0034](adr/0034-operator-minimized-reference-discovery.md); [self-hosting](26-self-hosting.md) | Dedicated reference services, public configuration/revision, default-blackhole and replacement evidence, independent operator review | 2026-08-09 | +| **SV1-C13 Resilient retry and fallback** | Komms retains queued work, retries within declared bounds, and can use more than one supported route; it does not guarantee availability or delivery time. | Andri (NET/PROD); external field evaluator: **Unassigned** | Automated evidence | [Transport design](05-transports.md); [node delivery tests](../crates/kult-node/tests/node_e2e.rs); [mesh policy tests](../crates/kult-node/tests/mesh_policies.rs); [sneakernet tests](../crates/kult-transport/tests/sneakernet.rs) | Real NAT, background, handoff, operator-failure, and two-radio field matrix | 2026-08-09 | +| **SV1-C14 Local deletion limits** | Delete removes live logical history and Komms-owned references from the current profile; it does not promise forensic or remote erasure. | Andri (SEC/PROD); external storage reviewer: **Unassigned** | Implemented with automated evidence in current schema; stronger storage profile designed | [Storage limits](07-storage.md); [ADR-0027](adr/0027-opaque-indexed-store.md); [ephemeral tests](../crates/kult-node/tests/ephemeral_e2e.rs) | Opaque indexes/row binding, migration/remnant qualification, supported-platform storage review | 2026-08-09 | +| **SV1-C15 Nonprofit project mission** | Official Komms activity follows a nonprofit public-benefit mission; this is project policy, not registered-charity status and not a restriction on independent AGPL commercial use. | Andri (FND/COM; project policy owner); qualified legal reviewer: **Unassigned** | Implemented governance policy | [ADR-0033](adr/0033-nonprofit-founder-stewardship.md); [governance](../GOVERNANCE.md) | Legal entity, funding/trademark/asset policies, and qualified policy review remain P1 work | 2026-10-26 | + +## 3. Evidence-level rules + +1. A source file or ADR is **Designed**, not proof that runtime behavior occurs. +2. A merged implementation without a repeatable test is **Implemented**. +3. A test file becomes **Automated evidence** only when retained output names + its exact revision, environment, command, and result. +4. Simulator, emulator, localhost, self-round-trip, or founder-only review does + not satisfy field, independent interoperability, or independent review. +5. An independent role stays `Unassigned` until the named person has accepted + the scope and conflict requirements in a public record. +6. A gate closes only through a ledger change that links all required artifacts + and records founder release disposition. Closing one claim does not close + another claim or its P0 gate. + +## 4. Public-copy audit + +### In-repository surfaces + +The README, governance/security/contribution files, active product documents, +platform READMEs, and user-visible attachment copy are checked by +`python3 scripts/check-docs.py`. The check validates relative Markdown links, +the complete P0/claim identifiers, and terminology that previously overstated +deletion, source-metadata removal, evidence, or implementation provenance. + +Negative statements such as “not independently audited” remain permitted and +necessary. The everyday promise “Private messaging that keeps working.” also +remains; the frozen profile supplies its availability limit. + +### Public surfaces outside this repository + +These corrections cannot be completed by this repository change and remain +P0-01 follow-up: + +| Surface | Observed wording or risk | Required disposition | +|---|---|---| +| [`komms.org`](https://komms.org/) | The indexed page title still says 0.1 while the page presents 0.3. “works anywhere” and “truly deletable” exceed the stable claim register; the AGPL summary also compresses section-13 scope. | Align the version/title. Keep “Private messaging that keeps working.” Replace universal reachability and deletion wording with `SV1-C13` and `SV1-C14`; align the source-offer summary with ADR-0033. | +| [GitHub repository description](https://github.com/AndriGitDev/Komms) | “serverless” and “functional on & off the grid” can read as current universal/field-qualified claims. | Describe an Alpha with direct, local, radio, and file transport implementations and name the outstanding stable/field gates. | +| Release and package listings | Old screenshots, summaries, or package descriptions can outlive repository corrections. | Audit at every release; stable wording must cite a claim id and the release evidence bundle. | + +The accountable owner for these external corrections is Andri. Completion must +be linked here before P0-01 closes. diff --git a/docs/32-name-risk-decision.md b/docs/32-name-risk-decision.md new file mode 100644 index 0000000..d1d64ea --- /dev/null +++ b/docs/32-name-risk-decision.md @@ -0,0 +1,178 @@ +# Komms name-risk decision + +**Decision:** continue using **Komms** for now + +**Decision owner:** Andri, founder and lead maintainer + +**Assessment date:** 2026-07-26 + +**Next scheduled review:** 2026-10-26 + +**Status:** project risk decision; **not legal clearance, a registrability +opinion, or a finding of non-infringement** + +## 1. Decision + +The project continues using the Komms name while monitoring the exact-name +overlap described below. Engineering and Alpha testing continue. Long-lived +stable brand identifiers are not treated as legally cleared, and this decision +does not claim ownership over the word. + +The current response is proportionate because: + +- the project is still Alpha, founder-run, nonprofit in mission, and not + represented as stable; +- a rename is still possible but already has meaningful package, domain, + release, artwork, documentation, and wire-domain cost; +- the observed `komms.app` project is a real and close category overlap, but + this record contains no evidence of actual user confusion, an enforcement + contact, or a registry opinion; and +- monitoring plus explicit escalation triggers preserve the option to obtain + qualified advice before expansion or a harder-to-reverse brand freeze. + +## 2. Search scope and observations + +This founder review used public web, domain, company, package, and official +registry entry points on 2026-07-26. It is a screening record, not a +professional clearance search. Search-engine absence is not evidence that a +right does not exist, and company names, domains, package names, and trademarks +are not interchangeable. + +### Closest observed overlap + +| Observation | Category proximity | Likely confusion surfaces | Limits of this observation | +|---|---|---|---| +| [`komms.app`](https://komms.app/) presents **“Komms Protocol”** as communication infrastructure using Kaspa, Hippius, and Bittensor, with a waitlist, specifications, privacy page, and a referenced application. | High. Both use the exact word `Komms`, the phrase `Komms Protocol`, cryptography/decentralization language, and communication software. The architectures and visual identities differ. | Search results; verbal recommendations; social handles; press; package/app-store searches; GitHub repository references; phrases such as “Komms protocol,” “Komms app,” and “Komms docs.” | The page establishes public use, not priority, ownership, trademark registration, market reach, or legal rights. | +| [`komms.app/privacy`](https://komms.app/privacy) references `Komms-protocol/komms-core` as a public contact channel. | High for developer discovery and repository attribution. | GitHub search, issue reports, dependency/security notices, protocol discussions, and copied documentation links. | Repository availability, maintainership, legal ownership, and current activity require separate verification. | +| [A KOMMS LTD](https://find-and-update.company-information.service.gov.uk/company/12464746) is an active UK company whose filed activity includes telecommunications. | Medium category proximity, low identity evidence. | Company and provider searches in the UK. | A company registration is not a trademark record and the public filing does not establish a competing software mark. | +| Warframe uses “Komms” for a game resource, including in an [official update](https://www.warframe.com/en/patch-notes/switch/30-0-0). | Low product proximity. | General web search noise and social handles. | Entertainment use is materially different from a private messenger, but no legal conclusion follows. | + +No actual confusion report is recorded as of the assessment date. + +### Jurisdictions and search categories + +The project begins in Iceland and publishes globally through GitHub and public +package surfaces. Monitoring therefore covers at least: + +- Iceland, using the + [Icelandic Intellectual Property Office trademark search](https://www.hugverk.is/en/search/trademark); +- European Union registers and classification tools through + [EUIPO](https://www.euipo.europa.eu/en); +- international/Madrid records through the + [WIPO Global Brand Database](https://www.wipo.int/en/web/global-brand-database) + and [Madrid Monitor](https://www3.wipo.int/madrid/monitor/en/); +- the United Kingdom because of the observed telecommunications company and + likely software distribution; and +- any jurisdiction targeted by an app-store launch, paid promotion, operator + contract, grant, or sustained user adoption. + +Screening terms include `Komms`, `Komms Protocol`, close visual/phonetic +variants, and the K mark. Product categories include downloadable messaging +software, mobile/desktop applications, telecommunications and message +delivery, hosted software/infrastructure, cryptographic/security software, and +developer protocol services. Nice classes 9, 38, and 42 are useful starting +points for monitoring, not a founder determination of the correct filing +classes. + +No qualified person has completed a registry similarity search, common-law/use +search, goods/services comparison, priority analysis, or registrability +opinion for Iceland, the EU, UK, US, or Madrid designations. Those items remain +open. + +## 3. Current identifiers and migration cost + +The repository currently contains the Komms name in about 200 tracked files. +The cost is not limited to replacing visible prose: + +| Surface | Current examples | Migration consequence | +|---|---|---| +| Public identity | `komms.org`, `AndriGitDev/Komms`, Komms logo/screenshots, release names | Redirects, repository/package continuity, documentation and screenshot replacement, search-result ambiguity | +| Applications | `is.andri.komms` on desktop, Android, and iOS; `Komms` product name | Store/package migrations, signing identities, platform preferences/keychain namespaces, deep links, user-recognizable upgrade path | +| Distribution | `Komms-*.dmg/.msi/.apk`; `ghcr.io/andrigitdev/komms-kultd` | Release automation, container aliases, checksums, updater metadata, operator migration | +| Source/API | `komms` module/package namespaces and user-visible command names | Binding consumers, scripts, examples, support material | +| Protocol/storage domains | strings such as `Komms-PQXDH-v1`, `Komms-DHT-Locator-v2`, and local preference keys | A brand rename need not rewrite cryptographic domain separation, but any change would require compatibility vectors and migration rather than search-and-replace | +| Legal/governance | license notices, mission policy, security contacts, future trademark policy | Policy review, provenance continuity, contributor/operator guidance | + +Migration cost is therefore **material and increasing**, but still manageable +before stable identifiers, app-store listings, signed update channels, and +large-scale adoption exist. That supports a keep-and-monitor decision today, +not indefinite deferral. + +## 4. Confusion controls + +While the name remains: + +- use the repository owner and `komms.org` in security/release references; +- describe this project as the private resilient messenger, not merely “Komms + Protocol” without context; +- do not imply affiliation with `komms.app`, Kaspa, Hippius, Bittensor, or the + referenced `Komms-protocol` organization; +- route misdirected reports without collecting unnecessary information and + record the event as a confusion signal; +- keep release signing identities, checksums, package origins, and security + contacts prominent; and +- reserve new handles/domains only when useful, without treating registration + as legal clearance. + +## 5. Monitoring cadence + +Andri owns the monitoring record until the role is delegated: + +1. **Monthly during Alpha and stable-v1 preparation:** exact-name web, GitHub, + app-store, package-registry, domain, and observed-project activity check. +2. **Before every public release:** verify project/release descriptions, + package identifiers, security contacts, redirects, and new confusion + reports. +3. **Quarterly registry checkpoint:** record the date and search coverage for + Iceland, EUIPO/WIPO, and jurisdictions where distribution or adoption has + become material. The next checkpoint is 2026-10-26. +4. **Event-driven review:** run immediately on any trigger below. + +Each review is appended through a dated change to this file or a linked public +record. Silence is recorded as “no new observation,” not “cleared.” + +## 6. Triggers for qualified trademark advice + +Qualified advice becomes proportionate before the project: + +- files or opposes a trademark application; +- freezes stable brand, package, update, or long-lived public wire identifiers; +- enters an app store, paid distribution, material fundraising/grants, + sponsorship, operator contracts, or paid promotion; +- expands sustained targeting beyond Iceland or into a jurisdiction with a + relevant observed right; +- grants official operator status or a trademark licence; or +- incurs a rename cost materially greater than the one recorded here. + +Advice is sought immediately if: + +- a user, contributor, operator, press contact, search result, or security + reporter actually confuses the two communication projects; +- `komms.app`, another claimant, a platform, or counsel contacts the project + about the name; +- a cease-and-desist letter, opposition, takedown, package dispute, domain + dispute, or store rejection occurs; +- a relevant identical/similar application or registration is found; or +- the other project begins overlapping distribution, app-store, protocol, + operator, or nonprofit messaging activity in a way that increases likely + confusion. + +These triggers require a qualified assessment; they do not predetermine keep, +coexistence, adjustment, or rename. + +## 7. Rename review criteria + +If a trigger fires, the founder records: + +- claimant/right and verified priority; +- goods/services and jurisdictions; +- evidence of actual or likely confusion; +- user-safety and security-update consequences; +- coexistence or qualifier options; +- migration sequence for domains, signed artifacts, package identities, + protocol compatibility, and redirects; and +- the cost of changing now versus after the next release stage. + +Until that review changes this record, the decision remains: **continue using +Komms for now, monitor monthly, and do not represent the name as legally +cleared.** diff --git a/docs/adr/0013-real-time-calls.md b/docs/adr/0013-real-time-calls.md index e113162..78a0e56 100644 --- a/docs/adr/0013-real-time-calls.md +++ b/docs/adr/0013-real-time-calls.md @@ -39,7 +39,7 @@ audio/video **clips** are unaffected and remain ordinary payloads on every carri **Signaling** is the fixed content-v1 kind `0x0008` `CallControl`, encrypted as an ordinary pairwise ratchet message. It does not add a cleartext -`EnvelopeKind::CallSignal`: envelope kind is relay-visible in the shipped wire +`EnvelopeKind::CallSignal`: envelope kind is relay-visible in the current Alpha wire format, so a dedicated kind would unnecessarily identify call attempts. The fixed operations are offer, answer, decline, busy, cancel, and hangup. They bind one random call id, the exact physical sender device, an expiry, and the @@ -69,7 +69,8 @@ late sequence numbers rather than growing latency without bound. Once bytes enter the reliable stream, packet loss can still cause head-of-line delay, which is an explicit alpha limitation and a measured release criterion. -The shipped audio implementation therefore requires a fresh direct `/quic-v1` route. +The current Alpha audio implementation therefore requires a fresh direct +`/quic-v1` route. TCP/Yamux, Circuit Relay, mailbox, sneakernet, and every airtime carrier do not qualify as `realtime`. AutoNAT, relay reservation, and DCUtR may establish and upgrade connectivity, but the call button remains unavailable until the @@ -82,7 +83,7 @@ selection, and interruption integration use the native platform audio stack; the core owns canonical frame bounds, encryption, replay state, jitter policy, and transport. Video remains out of scope until the audio release matrix passes. WebRTC is not the automatic fallback: without third-party STUN/TURN it cannot -reuse the shipped libp2p relay path, and adding it would create a second NAT and +reuse the current Alpha libp2p relay path, and adding it would create a second NAT and dependency surface without solving Komms' constrained-connectivity requirement. ## Transport spike evidence diff --git a/docs/adr/0014-versioned-message-content.md b/docs/adr/0014-versioned-message-content.md index 4eb143d..51a36b5 100644 --- a/docs/adr/0014-versioned-message-content.md +++ b/docs/adr/0014-versioned-message-content.md @@ -179,7 +179,7 @@ exactly like a delivery receipt. A decrypted body beginning with capability magic `00 00 ff 4b 43 43` (`empty receipt || 0xff || "KCC"`) is a capability control; every other body continues through the existing `ReceiptPayload` decoder. The first two bytes are the complete canonical Postcard encoding of an -empty receipt. The currently shipped `postcard::from_bytes` receipt path ignores +empty receipt. The current Alpha `postcard::from_bytes` receipt path ignores the unused suffix, so an old endpoint accepts the control as a harmless empty receipt without allocating from an attacker-controlled count. A stricter old decoder would merely reject it, which is equally terminal and invisible to the @@ -283,7 +283,7 @@ The implementation PR must include: existing encrypted receipt lane preserves relay and endpoint compatibility. - **Use an ASCII magic prefix.** Rejected: an existing valid text message could collide with it. The invalid-UTF-8 leading byte makes collision impossible - for all text emitted by the shipped public APIs. + for all text emitted by the implemented Alpha public APIs. - **Send framed text to everyone immediately.** Rejected: pre-ADR clients would lossy-render binary framing as text. Conservative authenticated negotiation preserves useful messaging across versions. diff --git a/docs/adr/0015-encrypted-attachment-pipeline.md b/docs/adr/0015-encrypted-attachment-pipeline.md index f8a2a7a..60a55fb 100644 --- a/docs/adr/0015-encrypted-attachment-pipeline.md +++ b/docs/adr/0015-encrypted-attachment-pipeline.md @@ -292,7 +292,7 @@ chunk-based. This rule is origin-enforced because intermediaries remain metadata-blind. An old opaque relay cannot identify a small manifest it received over another -carrier, but chunk and bulk-control size floors exceed the shipped bridge +carrier, but chunk and bulk-control size floors exceed the current Alpha bridge airtime ceiling. The unavoidable residual is at most the ordinary padded manifest envelope, never media bytes. Acceptance tests measure the updated origin and require an attachment attempt under a fresh `mesh_only` verdict to diff --git a/docs/adr/0021-ephemeral-retention.md b/docs/adr/0021-ephemeral-retention.md index 7316cba..10e7e7c 100644 --- a/docs/adr/0021-ephemeral-retention.md +++ b/docs/adr/0021-ephemeral-retention.md @@ -93,7 +93,7 @@ cannot reopen content; cleanup resumes on the next tick. An original arriving after an `Expired`/`Consumed` marker is acknowledged but never stored. Duplicates cannot rehydrate it. Edits cannot target ephemeral -content. Quotes and replies are not yet a shipped structured content type; a +content. Quotes and replies are not yet an implemented structured content type; a future design must render a non-plaintext expired placeholder rather than copy ephemeral text into permanent content. @@ -108,7 +108,7 @@ an erasure promise. Each linked installation applies the authenticated deadline and first-open rule to its own local copy. First open is per installation, not a synchronized claim -that every device or recipient deleted. Shipped C2 linked-device sync carries +that every device or recipient deleted. Implemented Alpha C2 linked-device sync carries tombstones but not active ephemeral content; an active copy may disappear earlier after receiving one, never later or by resurrecting plaintext. diff --git a/docs/adr/0033-nonprofit-founder-stewardship.md b/docs/adr/0033-nonprofit-founder-stewardship.md index 8056997..e14b3a0 100644 --- a/docs/adr/0033-nonprofit-founder-stewardship.md +++ b/docs/adr/0033-nonprofit-founder-stewardship.md @@ -8,7 +8,7 @@ Komms is being built as public-benefit communications infrastructure rather than as a venture-backed service or a data business. During the construction and stabilization phase, Andri is the sole maintainer and directs a broad, -tool-assisted implementation program. Contributions and criticism are welcome, +implementation program. Contributions and criticism are welcome, but a governance structure should reflect the community that actually exists rather than simulate plural ownership before adoption. @@ -41,10 +41,9 @@ charity, tax-exempt entity, or legally incorporated nonprofit. ### 2. Founder direction is the intentional incubation model The founder holds final product, protocol, merge, release, delegation, and -roadmap authority during construction and stabilization. Automated research and -implementation systems are tools, not maintainers, reviewers, copyright holders -represented by the project, or decision-makers. The human maintainer remains -accountable for provenance, scope, testing, acceptance, and public claims. +roadmap authority during construction and stabilization. The human maintainer +remains accountable for provenance, scope, testing, acceptance, and public +claims. Implementation authorship does not provide independent review. External reviewers may publish findings and decline to support an assurance claim. Their work is evidence, not shared product governance or an automatic diff --git a/docs/adr/README.md b/docs/adr/README.md index d1e4b7f..816488a 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -2,7 +2,7 @@ ADRs record decisions that constrain Komms across implementations. An accepted ADR is normative until another ADR explicitly supersedes it. A proposed ADR is -design work under review: it may guide experiments, but it is not a shipped +design work under review: it may guide experiments, but it is not a stable product promise merely because the file exists. | ADR | Status | Decision area | diff --git a/scripts/check-docs.py b/scripts/check-docs.py new file mode 100644 index 0000000..a0b357b --- /dev/null +++ b/scripts/check-docs.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +"""Validate documentation links, release-control coverage, and public terms.""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path +from urllib.parse import unquote + + +ROOT = Path(__file__).resolve().parents[1] +LINK_RE = re.compile(r"!?\[[^\]]*]\(([^)\s]+)(?:\s+\"[^\"]*\")?\)") +P0_IDS = {f"P0-{number:02d}" for number in range(1, 11)} +CLAIM_RE = re.compile(r"\bSV1-C\d{2}\b") + +PUBLIC_COPY = [ + ROOT / "README.md", + ROOT / "docs/00-start-here.md", + ROOT / "docs/01-why.md", + ROOT / "docs/11-feature-scope.md", + ROOT / "docs/12-feature-delivery-plan.md", + ROOT / "docs/27-alpha-testing.md", + ROOT / "docs/28-brand-system.md", + ROOT / "apps/desktop/README.md", + ROOT / "apps/android/README.md", + ROOT / "apps/ios/README.md", + ROOT / "apps/desktop/ui/index.html", + ROOT / "apps/desktop/ui/main.js", + ROOT / "apps/android/app/src/main/res/values/strings.xml", + ROOT / "apps/ios/KommsApp/Sources/AttachmentView.swift", +] + +OVERCLAIM_TERMS = { + "metadata-free": re.compile(r"\bmetadata-free\b", re.IGNORECASE), + "truly deletable": re.compile(r"\btruly deletable\b", re.IGNORECASE), + "works anywhere": re.compile(r"\bworks anywhere\b", re.IGNORECASE), + "audited control inventory": re.compile( + r"\baudited (?:controls?|command surface|text editor|modifier)\b", + re.IGNORECASE, + ), +} + + +def relative(path: Path) -> str: + return path.relative_to(ROOT).as_posix() + + +def line_number(source: str, offset: int) -> int: + return source.count("\n", 0, offset) + 1 + + +def validate_links(errors: list[str]) -> None: + for markdown in sorted(ROOT.rglob("*.md")): + if ".git" in markdown.parts or "target" in markdown.parts: + continue + source = markdown.read_text(encoding="utf-8") + for match in LINK_RE.finditer(source): + target = match.group(1).strip("<>") + if ( + target.startswith("#") + or target.startswith("/") + or "://" in target + or target.startswith("mailto:") + ): + continue + path_part = unquote(target.split("#", 1)[0].split("?", 1)[0]) + if not path_part: + continue + resolved = (markdown.parent / path_part).resolve() + try: + resolved.relative_to(ROOT) + except ValueError: + errors.append( + f"{relative(markdown)}:{line_number(source, match.start())}: " + f"relative link escapes the repository: {target}" + ) + continue + if not resolved.exists(): + errors.append( + f"{relative(markdown)}:{line_number(source, match.start())}: " + f"missing relative link target: {target}" + ) + + +def validate_control_coverage(errors: list[str]) -> None: + profile_path = ROOT / "docs/30-stable-v1-product-profile.md" + ledger_path = ROOT / "docs/31-release-evidence-ledger.md" + profile = profile_path.read_text(encoding="utf-8") + ledger = ledger_path.read_text(encoding="utf-8") + + ledger_p0 = set(re.findall(r"\bP0-\d{2}\b", ledger)) + if not P0_IDS <= ledger_p0: + errors.append( + f"{relative(ledger_path)}: missing P0 gates " + f"{sorted(P0_IDS - ledger_p0)}" + ) + + profile_claims = set(CLAIM_RE.findall(profile)) + ledger_claims = set(CLAIM_RE.findall(ledger)) + if not profile_claims: + errors.append(f"{relative(profile_path)}: no stable claim ids found") + if profile_claims != ledger_claims: + errors.append( + "stable claim register mismatch: " + f"profile-only={sorted(profile_claims - ledger_claims)}, " + f"ledger-only={sorted(ledger_claims - profile_claims)}" + ) + + slogan = "Private messaging that keeps working." + for path in (ROOT / "README.md", profile_path): + if slogan not in path.read_text(encoding="utf-8"): + errors.append(f"{relative(path)}: required product promise is missing") + + if "**Unassigned**" not in ledger: + errors.append( + f"{relative(ledger_path)}: independent roles must remain visibly unassigned" + ) + + +def validate_terms(errors: list[str]) -> None: + for path in PUBLIC_COPY: + source = path.read_text(encoding="utf-8") + for label, pattern in OVERCLAIM_TERMS.items(): + for match in pattern.finditer(source): + errors.append( + f"{relative(path)}:{line_number(source, match.start())}: " + f"public copy uses disallowed term {label!r}" + ) + + +def main() -> None: + errors: list[str] = [] + validate_links(errors) + validate_control_coverage(errors) + validate_terms(errors) + if errors: + for error in errors: + print(f"documentation check failed: {error}", file=sys.stderr) + raise SystemExit(1) + print( + "documentation links, P0/claim coverage, product promise, " + "and public terminology are valid" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/local-release-matrix.sh b/scripts/local-release-matrix.sh index f2fa863..af9ff85 100755 --- a/scripts/local-release-matrix.sh +++ b/scripts/local-release-matrix.sh @@ -21,6 +21,7 @@ run_in() { export RUSTFLAGS="${RUSTFLAGS:--D warnings}" run_in "$root" python3 scripts/check-release-version.py +run_in "$root" python3 scripts/check-docs.py run_in "$root" cargo fmt --all -- --check run_in "$root" cargo clippy --workspace --all-targets --all-features run_in "$root" cargo test --workspace --all-features