End to End Moderation

Safer conversations.
Private by design.

An open design for checking harmful messages on your device. Your conversations stay with you.

Built around privacy. Developed in the open.

Meet E2EM The idea behind the project

On your deviceCheck messages where they belong.

Your community’s rulesLet each app decide what happens next.

Open by designA specification anyone can build on.

A work in progress

Model progress towards the gate

67%

Average recall towards the target across all categories. The gate is not yet passed.

The full specification

The open technical design for engineers building safer, more private conversations.

E2EM makes contextual moderation available on the device where a message is composed or read. An application supplies a message, relevant conversation context and an explicit policy. E2EM returns a structured assessment without sending the message to a moderation server. The application then warns, masks, holds or blocks according to that policy.

The goal is a model package smaller than 300 MB that works offline on mobile, delivered first as an embeddable SDK and later through a common operating system API. The model, policy engine and application enforcement remain separate so that the same engine can support personal safety tools and platform rules.

  1. 1 Architecture and trust boundaries
  2. 2 Profiles and privacy guarantees
  3. 3 Model and detection pipeline
  4. 4 API request and context contract
  5. 5 API response and failure semantics
  6. 6 Policy format and decision rules
  7. 7 Application integration and user experience
  8. 8 Runtime security and distribution
  9. 9 Evaluation and release gates
  10. 10 Acceptance scenarios and delivery plan
  11. 11 Child safety context and open decisions

Scope of the first release

The MVP covers English plain text, outgoing disclosure warnings and incoming text assessment. It combines deterministic detection of selected personal data and credentials with a compact contextual classifier. Policies are built from two rule tiers. Preset rules refer to a published category registry and carry per-category accuracy gates. Custom rules supply their policy text at runtime and are supported without per-rule accuracy guarantees. The official 0.1 model releases declare the preset tier only; the contract supports custom-policy models, but none is shipped or evaluated in this version. Images, audio, video, age verification and long-term grooming detection are outside MVP conformance.

Core requirements

IDRequirement
R1All inference and policy evaluation MUST work offline after installation.
R2The installed model package MUST be below 300,000,000 bytes, including weights, tokenizer, labels and calibration assets.
R3The API MUST distinguish an assessment from uncertainty, missing capability and execution failure.
R4Content, evidence, scores and message-derived identifiers MUST remain local in the core profile.
R5Apps MUST assess the exact message revision they send or display and apply the resolved policy.
R6A versioned capability manifest and evaluation report MUST define the supported use cases and languages.
R7A model package MUST declare the rule tiers, categories, thresholds and languages it supports in its signed manifest, and the runtime MUST reject policies that reference capabilities the installed model does not declare.

MUST and MUST NOT define conformance requirements; SHOULD allows a documented exception; MAY is optional. Numbers labelled “target” or “provisional gate” are engineering proposals, not measured results. This document specifies a system to build and evaluate; it does not establish accuracy or regulatory accreditation.

Changes in this draft

Draft 0.2 introduces two policy rule tiers: preset rules over the published category registry, and custom rules that supply policy text at runtime. It makes the model manifest the mechanism by which any conforming model declares which tiers, categories and languages it fulfils, and states that the official 0.1 models are preset-only. Request, response and policy schema versions remain 0.1 because the contract has not been frozen.

1 Architecture and trust boundaries

The application owns the message, encryption keys and user interface. The E2EM runtime owns validation, preprocessing, detectors, model inference and deterministic policy evaluation. The transport continues to carry the application’s encrypted messages. E2EM does not require a new encryption protocol or access to encryption keys.

ComponentResponsibility
Application adapterSupplies authorised context; resolves policy authority; binds results to message revisions; applies actions.
RuntimeValidates limits, tokenises, runs detectors and classifier, applies thresholds and returns typed results.
Model packageDefines labels, tokenizer, quantised weights, calibration and supported runtime versions; declares the presets, custom-policy support and languages the package fulfils.
Policy packageDefines enabled categories, thresholds, actions, uncertainty behaviour and authority.
Update componentRetrieves signed releases independently of inference; never receives conversation data.

Message lifecycle

Outgoing: finalise the message revision, assess it locally, apply the result, then encrypt and transmit the approved bytes. Any edit after assessment invalidates the result. Incoming: authenticate and decrypt using the messaging protocol, assess locally, then render the permitted view. Notification previews, search indexes, accessibility surfaces and linked devices must follow the same app policy.

Both endpoints can run E2EM independently and may use different policies. Sender-side protection can reduce accidental disclosure. Receiver-side protection can still operate when a sender uses a modified client. A sender’s assertion that a message passed moderation MUST NOT replace local assessment.

Threat model

Assume an adversary can send obfuscated text, inject instructions into messages, omit context on a client they control, probe model behaviour, replay old decisions and distribute modified applications. Network observers and the delivery service must not receive new message-level moderation signals through the core API.

The local application, runtime, model release and operating system are trusted to handle plaintext. Malware, a compromised OS, a malicious recipient or a modified client can bypass or inspect local processing. No E2EM decision proves that both endpoints complied. Adding an OS service expands the trusted computing base and requires its own isolation review.

Endpoint processing is consistent with a messaging architecture in which clients handle plaintext, but it adds endpoint attack surface. E2EM’s privacy claim depends on the actual runtime and integration, not merely on preserving transport encryption. [4]

2 Profiles and privacy guarantees

PropertyE2EM PersonalE2EM Platform
Policy authorityUser chooses local preset rules and, where the installed model supports them, custom rules.Application publisher defines platform rules; users may add compatible local rules.
Typical actionWarn before disclosure; mask incoming text.Hold outgoing messages or mask incoming text under explicit platform policy.
OverrideAvailable where the personal policy allows it.Defined and disclosed by the platform; never inferred from a model score.
ReportingNo automatic reporting.No reporting in core conformance; an external extension needs a separate specification.
AssuranceAssistance on a cooperating endpoint.Enforcement inside a cooperating application; no guarantee against modified clients.

Local data handling

P1. The inference process MUST have no network capability where the platform can enforce this. Where it cannot, the integration MUST document the boundary and demonstrate absence of content transmission. Downloading a model and checking for releases use a separate path with no access to inference inputs.

P2. The core MUST NOT persist messages, embeddings, evidence spans, per-message scores or hashes of content. Request data must be released after completion or cancellation, with best-effort buffer clearing where supported. The implementation MUST NOT promise forensic erasure from managed memory or operating system caches.

P3. Logs, crash reports and analytics MUST exclude payloads, model activations and results that reveal content. Sanitised aggregate operational metrics may be collected locally. Any upload requires a separately disclosed design; local-only inference alone does not make telemetry private.

P4. Calls MUST be isolated by application identity. A shared service MUST NOT expose another app’s history, results or policy. The app supplies its own context on each call; the core keeps no conversation database.

Reporting and coercion risks

A user may deliberately submit selected messages through an app’s existing report flow after seeing exactly what will be shared. This is outside the core assessment operation. Automated reports, compliance receipts, message hashes and remote attestation are excluded from version 0.1: even a one-bit decision can reveal sensitive information or become a tracking channel.

Users must be able to inspect active rules, their owner and the consequences of a match. Hidden policy expansion, silent content uploads and indiscriminate device-wide scanning violate this specification. Parental or managed-device controls require a separate authority and safeguarding design before claiming support.

3 Model and detection pipeline

Reference implementation

Start with a pretrained encoder in the approximate 50–150 million parameter range, fine-tuned for multi-label classification and optional token-level entity detection. Benchmark INT8 first, then lower precision only where quality and device measurements justify it. Architecture and runtime selection remain experimental until the release gates pass.

Raw INT8 weights use approximately one byte per parameter, so a 100-million-parameter candidate begins near 100 MB before additional assets. This is a sizing estimate, not a package or RAM measurement. Runtime binaries, activations and temporary buffers are accounted for separately. A small generative model may be evaluated as an alternative, but the public API MUST return typed data rather than generated prose.

Model tiers and interchangeability

This specification defines the contract; a model package declares which parts of it the package fulfils. Every model, official or third-party, ships the manifest described in section 8 and is loaded through the same validated path. The runtime evaluates only rules that the installed model declares; nothing else in the API changes between models.

Preset tier. The model scores each declared registry category and ships one calibrated threshold pair per category. Official 0.1 models are compact encoders trained on the registry’s canonical policy wording and labelled answers, so the wording an application enables is the wording that was evaluated. Presets are added one category at a time, and a category ships only when it passes its gate in section 9.

Custom tier. A model that declares custom_policies as supported accepts a rule’s policy text as input alongside the message and conversation window and returns a score for that rule. Custom rules carry no per-rule accuracy claim; the model’s release report covers the reserved-policy generalisation gate in section 9 instead. No official 0.1 model declares this tier.

Processing order

  1. Validate the request, caller capability and policy. Retain original text and create a bounded normalised view with a reversible mapping to original UTF-8 byte offsets. Treat conversation text as untrusted data; it cannot supply policy or executable instructions.
  2. Run bounded deterministic detectors over the full target message for validated email and phone patterns, supported financial identifiers and credential formats. Checksums and contextual cues reduce obvious false positives but do not prove that a detected identifier is real or belongs to the sender.
  3. Run the contextual classifier on a serialised conversation window containing explicit speaker, message and target boundaries. Initial model categories are targeted harassment, threats and contextual solicitation of sensitive information. Each requires its own held-out evaluation; unsupported categories MUST be rejected. For a custom rule, the model additionally receives that rule’s policy text and returns a score for that rule alone.
  4. Apply the release-specific calibration and category thresholds. Resolve every required policy rule, then aggregate using the action ordering. Return the effective versions, coverage, findings and uncertainty. Do not generate explanations or infer guilt, intent, age or criminal status.

Training and data governance

Begin with licensed datasets, commissioned annotations and synthetic augmentation. Use consented real examples only under an explicit collection and retention process. Ordinary app conversations MUST NOT become training data by default. Plan an initial 100,000–200,000 labelled examples as a budgeting hypothesis; learning curves determine whether more data helps. For preset categories, pair every example with the registry’s canonical policy wording and its labelled answer so that the shipped wording is the evaluated wording. A model that supports custom rules additionally trains on diverse policy paraphrases, with whole policy families reserved for evaluation and never seen in training.

Annotation must distinguish disclosure from discussion, quotation from targeting, and help-seeking from encouragement. Include banking conversations, abuse disclosures, reclaimed terms, dialects, emoji, spelling errors and benign code. Split by conversation, source and author where possible; deduplicate before splitting. Keep synthetic templates and adversarial variants out of overlapping train and test partitions.

Release a model card with provenance, licensing, annotation guidance, subgroup coverage, quantisation impact, known failures and intended use. Specialist review is required before adding child-safety categories; a short-window classifier cannot establish a pattern of grooming across weeks.

4 API request and context contract

The transport-neutral interface is capabilities(), validatePolicy(policy), assess(request) and cancel(request_id). assess is asynchronous. Native language bindings and an eventual authenticated local IPC service use the same value semantics. A network HTTP endpoint is not required or enabled by default.

{
  "api_version": "0.1",
  "request_id": "req-104",
  "direction": "outgoing",
  "message": {
    "id": "m-8", "revision": "3", "speaker": "self",
    "text": "My email is [email protected]"
  },
  "context": [
    {"id": "m-7", "speaker": "peer-1",
      "text": "Where can I contact you?"}
  ],
  "language": "en",
  "policy_ref": {"id": "personal-basic", "version": "1"},
  "options": {"deadline_ms": 1000, "include_spans": true}
}

All shown fields are required except context, language and options. context defaults to an empty array; language to auto; deadline_ms to 1000; include_spans to false. Exactly one of policy_ref or an inline policy is required. A policy reference resolves only to an immutable, locally registered version. “latest” is invalid.

InputVersion 0.1 rule
IdentifiersOpaque caller-scoped strings, 1–128 UTF-8 bytes; no global user identifiers required.
directionExactly outgoing or incoming. speaker is a local alias, not an asserted identity or age.
Text and contextValid Unicode; non-empty target; at most 16,384 UTF-8 bytes per message and 65,536 bytes of text per request.
HistoryAt most 32 prior messages, oldest first; unique IDs; target ID absent. Context is caller-supplied and may be incomplete.
Optionsdeadline_ms is an integer from 1 to 5000, covering queueing and inference. Unknown fields or enum values are errors.

Context budget

The reference model budget is 1,024 tokens, including boundary tokens. Keep the full target; add the newest complete context messages that fit and retain chronological order. Drop only whole older context messages and report their IDs. If the target alone exceeds the model budget, return indeterminate with INPUT_TOO_LONG; never classify only its prefix as if it were complete.

capabilities() MUST expose the installed model manifest: actual token and byte limits, tokenizer version, profiles, languages, detector IDs, declared preset category IDs with their threshold pairs, whether custom rules are supported and their threshold pair, and the actions available to each rule tier. An application discovers at install time which rules the installed model can honour; policies written against undeclared capabilities fail validation. Short or unsupported-language text may be ambiguous; an explicit language hint does not override capability or coverage checks.

Capability manifest

{
  "api_version": "0.1",
  "model": "en-text-0.1.0", "registry": "0.1.0",
  "languages": ["en"], "max_tokens": 1024,
  "detectors": ["pii.email", "pii.phone", "fin.iban", "cred.api_key"],
  "presets": {
    "abuse.harassment": {"review_threshold": 0.45, "action_threshold": 0.70},
    "abuse.threat": {"review_threshold": 0.40, "action_threshold": 0.65}
  },
  "custom_policies": "none",
  "actions": {
    "deterministic": ["warn", "review", "block"],
    "preset": ["warn", "review"], "custom": []
  }
}

Values are illustrative. A model that supports custom rules reports custom_policies as supported together with a custom_thresholds pair and a non-empty custom action list. A preset-only model is fully conforming; it simply cannot validate policies that contain custom rules.

5 API response and failure semantics

{
  "api_version": "0.1", "request_id": "req-104",
  "message_id": "m-8", "message_revision": "3",
  "status": "assessed", "action": "warn",
  "versions": {
    "runtime": "0.1.0", "model": "en-text-0.1.0",
    "detectors": "0.1.0", "registry": "0.1.0",
    "policy_id": "personal-basic", "policy_version": "1"
  },
  "coverage": {
    "language": "en", "target_complete": true,
    "context_complete": true, "dropped_context_ids": [],
    "unevaluated_rules": []
  },
  "findings": [{
      "rule_id": "email-warning", "category": "pii.email",
      "method": "deterministic", "score": null,
      "reason_code": "EMAIL_PATTERN",
      "spans": [{"message_id": "m-8", "start": 12, "end": 29}]
  }],
  "reason_codes": ["POLICY_MATCH"], "duration_ms": 18
}

This is an illustrative result, not a measured benchmark. Spans are half-open UTF-8 byte ranges in original text. They MUST lie on valid code point boundaries. The example range selects [email protected]. The engine does not echo matched content. Context evidence may be returned but MUST NOT be applied as a redaction to the target.

StatusRequired meaning
assessedEvery required rule ran with its required coverage. action is the policy result; no match means allow, not a safety guarantee.
indeterminateA valid request could not satisfy all required rules. action is review; findings may contain partial results.
errorInvalid request or execution failure. action is review; error_code is present. No successful assessment is implied.
cancelledCancelled before completion. action is review. The app discards any late result for this request.

error_code is one of INVALID_REQUEST, UNSUPPORTED_VERSION, POLICY_NOT_FOUND, INVALID_POLICY, UNSUPPORTED_POLICY, MODEL_UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED or INTERNAL_ERROR. Indeterminate reasons include UNSUPPORTED_LANGUAGE, INSUFFICIENT_CONTEXT, INPUT_TOO_LONG and LOW_CONFIDENCE. All non-assessed responses include reason_codes and available version and coverage information.

A model score is a release-calibrated category score in [0,1], not certainty that a person is harmful. Deterministic matches use score=null. method is deterministic, model or custom_policy; a custom_policy finding has category null and reason_code CUSTOM_POLICY_MATCH. Reason codes map to fixed, localised UI text. Findings MUST be treated as sensitive local data. Missing or malformed results MUST use the same failure path as an error.

6 Policy format and decision rules

{
  "schema_version": "0.1",
  "id": "personal-basic", "version": "1",
  "profile": "personal",
  "rules": [{
      "id": "email-warning", "category": "pii.email",
      "directions": ["outgoing"], "match": "detected",
      "context_requirement": "target_only", "action": "warn"
  }],
  "default_action": "allow",
  "on_indeterminate": "review", "on_error": "review",
  "override": "user_confirm"
}

All policy fields shown are required. profile is personal or platform; override is user_confirm or forbidden. The registry contains immutable policy versions. The trusted adapter determines who may install a policy; a caller-supplied profile value does not establish authority. Rules have unique IDs. Preset rules refer to category IDs declared by the installed model; custom rules supply policy_text instead. Unknown fields, categories, actions, rule types the installed model does not declare, or incompatible versions MUST fail validation with INVALID_POLICY or UNSUPPORTED_POLICY.

Model rules and context requirements

For contextual model categories, replace match="detected" with match="score" and provide review_threshold and action_threshold, both in [0,1], with review_threshold < action_threshold. A score below review_threshold is a non-match; at or above action_threshold it triggers the rule action; the interval between them is indeterminate. Thresholds must be calibrated per category and released with the evaluated model-policy pair.

context_requirement is target_only or supplied_window. supplied_window additionally requires min_context_messages, an integer from 1 to 32. It is unsatisfied if fewer messages were supplied or any supplied context was dropped. This verifies only the supplied window; it cannot prove that earlier events were not omitted. Missing required coverage makes the whole assessment indeterminate.

Custom policy rules

A custom rule replaces category with policy_text: a plain-text rule of 1–512 UTF-8 bytes written by the policy author at runtime, with match set to policy_text. The rule carries no thresholds; the installed model’s manifest declares one calibrated threshold pair for the whole custom tier. policy_text counts against the request token budget together with the target and context. In version 0.1 a custom rule’s action MUST be warn, or review in the personal profile only; block is invalid. Platform policies MAY contain custom rules but MUST NOT use them for enforcement stronger than warn. validatePolicy() rejects every custom rule with UNSUPPORTED_POLICY when the installed model declares custom_policies as none.

{
  "id": "former-partner", "match": "policy_text",
  "policy_text": "Do not discuss the user's former partner.",
  "directions": ["incoming"],
  "context_requirement": "target_only", "action": "warn"
}

Findings from custom rules use method custom_policy, category null and reason_code CUSTOM_POLICY_MATCH, so that user-facing text can say that the user’s own rule matched rather than that a vetted category was detected.

Aggregation and permitted actions

When status is assessed, matching rules aggregate in this order: block, review, warn, allow. Rule actions are block, review or warn; default_action is allow. A rule requesting review is a completed policy outcome and need not imply model uncertainty. If any required rule is indeterminate, the response is indeterminate and action=review, even if another rule matched; partial findings remain available locally.

allow permits the configured app operation. warn requires a visible warning and explicit continuation before sending or revealing. review holds sending or masks incoming content pending local user review or the app’s documented recovery flow. block denies the operation under the current policy. review never means automatic server or human-moderator upload.

For version 0.1, on_error and on_indeterminate MUST be review. user_confirm permits an explicit local override after explanation; forbidden prevents user bypass and offers retry, edit or a local appeal path. Combining platform and personal policies applies the stricter outcome and only permits continuation when every applicable policy permits it. MVP policies cannot contain executable code or arbitrary regex; natural-language instructions are permitted only as the bounded policy_text of a custom rule.

7 Application integration and user experience

Outgoing messages

Capture an immutable snapshot after all user edits and app transformations that affect text. Bind request_id to the message ID, revision, text, context snapshot and effective policy versions locally. Assess the snapshot and apply the result before encryption. If the text, relevant context or policy changes while assessment runs, discard the result and assess again.

When a warning is overridden, the confirmation applies only to that snapshot. Any automatic redaction or replacement creates a new revision requiring assessment. Keep retry drafts in the app’s normal protected storage, not in runtime logs. Prevent duplicate sends on retries and ignore superseded or cancelled requests.

Incoming messages

Decrypt and authenticate within the app. Until assessment completes, a platform integration must avoid exposing protected content in message previews, notifications, widgets, search or assistive output. Show a neutral placeholder when review or block requires masking. Preserve user access to help and reporting flows without revealing the hidden content accidentally.

An incoming block controls the app’s presentation; plaintext has already reached the recipient endpoint. It cannot prevent a modified client, another linked device or the recipient from accessing received content. Every supported display surface and linked-device client needs its own integration.

Useful interventions

SituationExpected behaviour
Email detected before send“This message includes an email address.” Offer Edit and, where allowed, Send anyway.
Threat category above thresholdApply the rule’s mask or hold action and show its plain-language reason; avoid labelling the sender a criminal.
Timeout or unsupported language“This message could not be checked.” Offer retry and the policy-permitted review path.
Possible financial identifierExplain that a pattern was detected. Do not imply that the account is verified or the transaction is fraudulent.

Failure and accessibility

A runtime error must never silently send a held message. Personal mode may offer explicit continuation if its policy allows it. Platform mode with override forbidden keeps the operation held until retry or a policy-governed resolution; it must avoid an endless retry loop. Safety help must remain reachable during outages.

Use screen-reader labels, focus management and text explanations that do not depend on colour. Avoid exposing hidden message text through accessibility names. Collect optional local feedback on false positives without retaining content. Do not punish an account solely on an E2EM classification or treat an override as an admission.

8 Runtime security and distribution

Packaging and release integrity

A release manifest MUST identify the model, tokenizer, category registry, calibration, supported policy schema, runtime compatibility, languages, byte sizes and cryptographic digests. The publisher signs the manifest using a reviewed signature scheme and pinned trust roots. The loader validates the signature and every component before use.

Packages MUST be data-only and MUST NOT execute model-supplied scripts. Limit tensor shapes, allocations, archive expansion and parser work before loading. Reject incompatible assets and keep the last known-good package if installation fails. Activate an update atomically; in-flight requests complete against one consistent version set.

Maintain a minimum accepted security version to prevent unauthorised downgrades. Emergency rollback requires a signed authorisation naming the permitted package. Publish key rotation and revocation procedures. Offline clients can only apply revocation information they have received; the documentation must state this limit.

Model provenance and trust

Official model releases are signed by the project’s release key, ship the evaluation report required by section 9 and declare their tiers in the manifest. A third-party model uses the same manifest format, loader and validation path, is signed by its own publisher and is accepted only if the application’s configured trust roots include that publisher. This specification does not certify third-party models. A conforming runtime guarantees only that it refuses to load a package that fails signature or component validation, or that claims category IDs absent from the registry version it names.

Isolation and resource control

Bound request bytes, token count, queue depth, memory and execution time. Use linear-time pattern matching with fixed detector definitions. Normalisation must not destroy the original-offset mapping. Authenticate local IPC callers using operating system identity; never trust a caller-provided app name.

The initial SDK can run inside the app sandbox. A later OS service should isolate per-app requests and policy storage, expose only explicit calls, and avoid background access to other apps’ content. Supporting a common API does not itself grant OS privileges or platform adoption. CPU execution is the baseline; accelerators are optional and require parity and privacy testing.

Deployment sequence

StageDeliverableExit evidence
SDK firstPortable core, native mobile bindings, reference chat integration.Offline inference, policy semantics and lifecycle tests pass.
Platform adaptersAndroid and iOS app integrations; optional browser worker prototype.Device and memory measurements; no cross-app access or hidden remote fallback.
OS API proposalIDL, capability negotiation, permission model and service implementation.Independent security review and OS vendor or maintainer participation.

A browser build is an optional distribution path, not an MVP dependency. Its worker, model cache and dependency supply chain require separate review. Updates must not add new moderation categories or change authority silently; users and integrators must receive intelligible release and policy change information.

Test obfuscation, zero-width characters, homoglyphs, code-switching, quotation, reordered context, indirect requests, prompt injection and deliberate truncation. Test abuse disclosures and benign sexual or health education as hard negatives. Publish bypass rates and language coverage rather than claiming universal protection.

9 Evaluation and release gates

Evaluate the complete quantised model, detectors, policy and application path. Report results per category, language, device and relevant subgroup. Overall accuracy is insufficient when harmful events are rare. Every release report must include sample counts, confidence intervals, prevalence assumptions and comparison with the previous version.

MeasureProposed target or gate
Package sizeHard requirement below 300 MB decimal for installed model assets; SDK and total download reported separately.
MemoryTarget peak incremental runtime memory at or below 400 MiB in a foreground application process, including model, buffers and accelerator allocations where measurable. This budget assumes the foreground context; a constrained extension process imposes a far smaller limit and is covered by the execution context decision in section 11.
Warm latencyTarget p95 at or below 150 ms for 256 total tokens and 500 ms for 1,024 tokens on the selected mid-range mobile baseline.
Cold loadTarget p95 at or below 2 seconds, measured separately from warm inference and with explicit loading UI.
PII warning rulesProvisional gate: precision ≥98% and recall ≥95% for each declared supported identifier format.
Preset contextual rulesProvisional gate: recall ≥90% at benign false-positive rate ≤1% per released category.
Automatic blockingDisabled for contextual categories in MVP. Later enablement requires independently reviewed, prevalence-aware precision and harm assessment. Never enabled for custom rules.
Privacy and contractNo content egress or persistent runtime content; all required contract and integration scenarios pass.
Custom policy rulesRequired only for models declaring custom_policies as supported. Provisional gate on reserved policy families absent from training: report recall, benign false-positive rate and the worst-performing family; no per-rule guarantee is made or implied.

Measurement protocol

Select and record named lower-end and mid-range Android and iOS devices before claiming performance. Publish OS, runtime, quantisation, thread count, backend, package and policy versions. Measure at least 1,000 warm requests per workload and 30 cold starts; report p50, p95, peak memory, energy per request and sustained performance under thermal load. Include queueing and preprocessing in end-to-end latency.

Use an independently held-out set with enough positives and negatives to resolve each gate. For provisional quality gates, require the 95% lower confidence bound for precision or recall to pass its target, and the upper bound for false-positive rate to pass its limit. Report abstention separately and count abstentions as missed positives for end-to-end recall. Do not inflate performance by excluding unsupported or difficult inputs from coverage reporting.

Base rates

At 0.1% harmful-message prevalence, 90% recall and a 1% benign false-positive rate would yield about 900 true alerts and 9,990 false alerts per million messages, or roughly 8.3% alert precision. This illustrative calculation is why a warning threshold cannot automatically justify blocking or reporting.

10 Acceptance scenarios and delivery plan

TestRequired result
Ordinary supported messageassessed/allow only after all required rules complete; no claim of guaranteed safety.
Email example in section 4assessed/warn; span [12,29) maps exactly to the original UTF-8 target.
Emoji before sensitive textByte offsets still select the intended original text without splitting a code point.
Missing required contextindeterminate/review with INSUFFICIENT_CONTEXT; never silently allow.
Unsupported rule or policyTyped validation failure before inference; no fallback to a different policy.
Deadline or memory failureerror/review; no cloud fallback and no unbounded retry.
Edit during inferenceStale result ignored; new revision assessed before sending.
Tampered or downgraded modelRejected; validated last known-good version retained if available.
Injected policy instructionMessage text cannot change rules, authority or response schema.
Network and retention auditInference works in airplane mode; input, result and derived data absent from runtime files and outbound traffic.
Policy names an undeclared presetUNSUPPORTED_POLICY from validatePolicy(); no inference and no substitution of another category.
Custom rule on a preset-only modelUNSUPPORTED_POLICY; the application can show which rule cannot be honoured by the installed model.
Custom rule with action blockINVALID_POLICY regardless of the installed model.

Milestone 1 Contract and deterministic prototype

Freeze the category registry, typed schema, error model and policy evaluator. Implement personal-data warnings in a small reference chat app. Produce JSON schemas, API fixtures and cross-language byte-offset tests. Exit when the contract, stale-result and privacy scenarios pass with a stubbed model.

Milestone 2 Compact contextual model

Choose candidate encoders and a licensed training corpus. Train baseline classifiers, quantify INT8 quality loss and calibrate thresholds. Deliver a model card, repeatable evaluation harness and measured package, RAM and latency results. Drop or narrow categories that do not meet their gates. Begin with the single preset that has the best labelled data and clearest separability, prove the pipeline end to end on it, then add presets one at a time.

Milestone 3 Mobile pilot

Integrate Android and iOS bindings, signed updates, accessible warnings and explicit override handling. Conduct consented testing without default content collection. Exit when independent security review, false-positive review and supported-device gates pass. Contextual blocking remains disabled.

Milestone 4 Interoperability and standardisation

Publish the API and conformance suite; seek independent implementations and platform feedback. Propose an OS service only after the SDK demonstrates utility and a stable permission model. Expand languages, child-safety research or reporting extensions under separate evaluations and versioned specifications.

11 Child safety context and open decisions

Relationship to the UK safety discussion

The Home Office publication that motivated this project was published on 20 September 2023. It describes the government’s concern that encrypted messaging can reduce existing detection and reporting of child sexual abuse. Its references to the Online Safety Bill and planned platform rollouts are historical context, not a current implementation guide. [1]

Ofcom published its Technology Notices statement on 8 May 2026. It describes powers to require particular technologies where necessary and proportionate, with accreditation against government-set minimum accuracy standards. Its statement describes the subsequent standards and accreditation steps. E2EM must not describe itself as accredited or compliant on the strength of local inference, this specification or a benchmark alone. [2, 3]

This text-only MVP cannot detect illegal imagery, verify age, reconstruct a complete abuse relationship or replace safeguarding operations. A future child-safety extension requires specialist-designed labels, lawful and controlled datasets, independent testing, review of disproportionate impacts and a documented response process. Any reporting capability changes the privacy analysis and requires a distinct, visible profile.

Decisions to close before implementation freeze

DecisionProposed starting point
Model and runtimeBenchmark compact encoders with INT8 CPU inference; select on device evidence and licence compatibility. Official 0.1 models are preset-only.
Launch categoriesEmail, phone, selected financial and credential formats, plus evaluated harassment, threat and solicitation labels.
Initial productPersonal warnings in one reference messaging integration; platform enforcement follows validated integration.
Supported devicesAdopt the product plan’s iPhone 14 and Pixel 6 baselines, with minimum OS versions, before publishing performance claims.
Licensing and governancePrefer an open API and conformance suite. Decide code, model and dataset licences separately after provenance review.
Execution contextDecide where assessment runs before fixing the size budget. A foreground application process on the named device baselines affords substantially more memory than this document currently assumes, while a platform notification or keyboard extension affords far less than any model in the reference range requires. Section 7 obliges an integration to withhold protected content from notification previews, so the notification path needs either a separate constrained design or a documented deferral that holds a neutral placeholder until the application can assess. Confirm the current store download thresholds and per-context memory limits for the named baselines rather than relying on the figures assumed here.

Sources

Sources checked on 22 September 2026. The architecture, API, budgets and release gates in this document are proposed E2EM design requirements. External sources below support the contextual claims indicated by reference number.

  1. [1] Home Office — End-to-end encryption and child safety, 20 September 2023
  2. [2] Ofcom — Statement on Technology Notices, updated 8 May 2026
  3. [3] Ofcom — Approach to implementing the Online Safety Act
  4. [4] IETF — RFC 9750, The Messaging Layer Security Architecture, April 2025