Measure configured messaging channels
- Dominant language
- TypeScript
- Stars
- 22.5k
- Forks
- 3.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 715
Description
## Outcome
Measure which built-in messaging channels are configured across published NemoClaw environments without collecting credentials, configuration values, identities, health, or message activity.
This helps maintainers prioritize channel compatibility, testing, documentation, and support.
## Dependencies
- #10435 must define and receive approval for the telemetry privacy, service, schema, and reporting contract.
- Extend the post-commit registry observation mechanism from #10442. Do not create a separate observer or delivery path.
## OpenShell design alignment
OpenShell does not currently send messaging-channel data through anonymous telemetry.
This event follows its general privacy pattern:
- Use a checked-in category allowlist.
- Map unrecognized values locally to a fallback category.
- Send exact aggregate counts.
- Never transmit arbitrary local values.
- Use the common shared product identity, timestamps, opt-out, CI suppression, and best-effort delivery.
- Do not confuse local observability data with anonymous product telemetry.
## Measurement
Emit `nemoclaw_messaging_observed` with:
| Field | Allowed values |
| --- | --- |
| `messaging_channel` | `telegram`, `discord`, `wechat`, `slack`, `whatsapp`, `teams`, `googlechat`, or `other` |
| `count` | An exact positive integer |
Every event also uses the common envelope defined by #10435.
Emit one event for each configured channel category with a nonzero count.
Within each published environment, map all eligible configured entries to categories, then count each category at most once. Duplicate entries for the same category—including entries bound to different configured agents—contribute one. Different categories each contribute one. For example, two Slack entries and one Discord entry contribute `slack: 1` and `discord: 1`.
An environment can contribute more than one configured channel category. An environment without messaging configuration produces no messaging event.
## Source of truth
Use only the validated persisted messaging plan under a published `SandboxEntry`.
Count a channel when:
- The messaging envelope and plan pass structural validation.
- The channel entry records `configured === true`.
- The plan’s sandbox and agent authority match the registry entry.
- The channel is supported by the recorded agent or safely maps to `other`.
Registry state wins over staged plans, onboarding-session state, environment-encoded plans, and live agent configuration. Deduplicate only after structural validation and closed-category mapping within each environment, then sum those per-environment contributions across the snapshot.
Do not use the plan’s `active` or `disabled` fields. They can depend on credential availability, missing required inputs, enrollment behavior, or runtime startability.
Use existing validator-approved compatibility normalization for legacy plans. Do not infer configuration from credentials, providers, policies, rendered files, or live runtime state.
If a plan is malformed or inconsistent, skip that environment’s complete messaging contribution. Do not inspect arbitrary nested values or send a partial result.
## Channel mapping
Use the checked-in channel IDs from `src/lib/messaging/channels/built-ins.ts`:
- `telegram`
- `discord`
- `wechat`
- `slack`
- `whatsapp`
- `teams`
- `googlechat`
An exact recognized ID maps to its built-in category. Any other structurally valid persisted ID maps to `other`. Never transmit the original value.
Adding another named category requires accepted product scope and the schema review defined by #10435.
## Observation trigger
Use the shared post-commit registry observation after:
- Successful onboarding publishes an environment with configured channels.
- A successful channel add commits the final durable plan.
- A successful channel remove commits the post-removal plan and completes required cleanup.
- A snapshot, clone, restore, recovery, or rebuild operation publishes final channel membership.
- A published environment is created or removed.
Do not observe after:
- Channel start or stop, because those operations do not change this measurement.
- Staged or environment-encoded plans.
- Failed, cancelled, or rolled-back operations.
- Dry runs or no-op mutations.
- Read-only list, status, doctor, diagnostic, or health commands.
- Intermediate registry writes.
Place observation at the completed command boundary, not inside the messaging plan applier.
A registry or plan-projection failure skips the complete messaging event family. Telemetry failure does not change product behavior.
## Privacy boundary
The client may read only the validated channel ID and configured flag required for projection.
It must never transmit:
- Sandbox or agent names.
- Active or disabled state.
- Channel display names or authentication modes.
- Tokens, credentials, credential hashes, or credential-availability fields.
- Configuration keys, values, input IDs, environment-variable names, or state paths.
- Account, workspace, organization, team, room, sender, recipient, allowlist, or conversation identifiers.
- Phone numbers, usernames, email addresses, webhook URLs, bot IDs, app IDs, or tenant IDs.
- Provider bindings, policy details, ports, or network destinations.
- Rendered configuration, build steps, runtime setup, hooks, or health checks.
- Enrollment, pairing, reachability, connection, or authentication results.
- Message content, traffic, delivery outcomes, errors, or logs.
- Arbitrary plan fields or hashes of excluded values.
## Meaning and limitations
A count means the number of published environments whose valid persisted plans record that channel category as configured. It does not count accounts, bots, agents, plans, or integration entries.
It does not prove that the channel:
- Was rebuilt into the current runtime.
- Is started, connected, authenticated, paired, reachable, or healthy.
- Has sent or received any messages.
Reports must use **configured messaging-channel observations**. They must not say active channels, connected channels, messaging users, or message volume.
## Delivery and reporting
- Apply opt-out and CI or test suppression before reading messaging state.
- Use the common best-effort delivery path.
- Make no retry and create no durable outbox.
- Do not change onboarding, channel, rebuild, recovery, or lifecycle results when telemetry fails.
- Apply the public minimum-count rule from #10435.
- Do not join messaging counts with per-environment, model, agent, or configuration records.
## Acceptance criteria
- Only published registry entries and validated persisted plans are eligible.
- Configured channels map to the seven approved categories or `other`.
- Duplicate entries in one environment count once per mapped category, including duplicates across configured agents.
- Active, disabled, credential, health, and runtime state are not read for projection.
- Staged, session, environment-encoded, and live agent configuration are ignored.
- Malformed or inconsistent plans produce no partial events.
- Successful add and remove operations update the next observation.
- Start and stop operations produce no messaging observation.
- Failed, cancelled, rolled-back, dry-run, and no-op operations produce no observation.
- Opt-out, CI, and test suppression prevent plan reading and delivery.
- Delivery failure does not change the product result.
- Serialized events contain none of the prohibited fields.
- Public reporting follows the terminology and minimum-count contract from #10435.
## Test plan
Add deterministic tests for:
- Pure configured-channel projection and exact counts.
- Each built-in channel and the `other` fallback.
- Multiple categories in one environment and duplicate same-category entries across one or several configured agents.
- Missing, empty, legacy, malformed, and inconsistent plans.
- Plans whose sandbox or agent authority does not match.
- Stale plans on unsupported agents.
- Successful and failed onboarding, add, remove, rebuild, snapshot, clone, restore, and recovery.
- Start, stop, dry-run, and no-op suppression.
- Opt-out, CI, test suppression, and delivery failure.
- Negative serialization assertions for every prohibited field and adversarial value.
Use synthetic plans and a local contract server. No live messaging, NVIDIA, OpenShell, or sandbox service is required.
## Not included
- Enabled, disabled, connectivity, health, pairing, or authentication state.
- Messages, traffic, senders, recipients, or conversations.
- Credential or configuration-value inventory.
- Per-agent or per-environment messaging profiles.
- Support for another channel or agent runtime.
- Dynamic categories or raw custom values.
- Model or general configuration measurement.
Contributor guide
Assessment
This issue has not been assessed yet.