Back to Qwen Code

Observed Channel Contacts Implementation Plan

docs/plans/2026-07-17-observed-channel-delivery-targets.md

0.19.124.0 KB
Original Source

Observed Channel Contacts Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.

Goal: Expose a fresh, workspace-scoped graph of dynamically observed direct users, groups, topics, and their observed users with complete platform identifiers.

Architecture: ChannelBase normalizes accepted inbound envelopes into relationship observations. The daemon worker writes them to a bounded workspace-partitioned JSON registry. Authenticated read-only routes derive a fresh graph for the exact workspace runtime. Webhook behavior remains unchanged.

Constraints

  • Persist under $QWEN_HOME/channels/daemon/<workspaceHash>/observed-contacts.json.
  • Record after inbound preflight and before command or Agent handling.
  • Record each Envelope once; never record rejected input, bot output, proactive sends, or webhook traffic.
  • Return complete IDs and sanitized/fallback labels.
  • Top-level users contains direct-message users only.
  • groups[].users and groups[].topics[].users are observed relationships, not authoritative membership.
  • Default freshness is seven days; accept freshWithinSeconds from 1 second through 365 days.
  • Keep at most 500 most-recent relationship observations.
  • Preserve exact workspace ownership and never fall back on qualified routes.
  • Do not change webhook configuration, requests, or delivery.

Task 1: Base observation contract

Files: packages/channels/base/src/types.ts, ChannelBase.ts, ChannelBase.test.ts, index.ts

  • Add identity, observation, graph, group, topic, and related-user types.
  • Add observedContacts.observe to ChannelBaseOptions.
  • Normalize senderId, senderName, chatId, and threadId after successful preflight.
  • Deduplicate the same Envelope object and keep persistence failures non-blocking.
  • Cover direct, group, topic, rejection, pairing, duplicate Envelope, and failure cases.

Task 2: Workspace relationship store

Files: packages/cli/src/commands/channel/observed-contact-store.ts, observed-contact-store.test.ts, daemon-worker.ts, daemon-worker.test.ts

  • Persist version 1 relationship observations with atomic mode-0600 writes.
  • Deduplicate by channel, user, group, and topic; refresh labels and timestamps.
  • Derive direct users separately from group and topic relationships.
  • Filter stale observations and expose independent relationship timestamps.
  • Enforce validation and the 500-observation bound.
  • Wire daemon-managed channels to the workspace-partitioned store.

Task 3: Authenticated dynamic-observation API

Files: packages/cli/src/serve/routes/workspace-channel-observed-contacts.ts, its test, server.ts, server.test.ts, capabilities.ts

  • Add singular and qualified /channel/observed-contacts GET routes.
  • Parse freshWithinSeconds, default to seven days, and reject invalid values.
  • Return {users, groups} with nested group/topic users and complete IDs.
  • Add Cache-Control: no-store and sanitized failure responses.
  • Require exact trusted workspace resolution on qualified routes.
  • Advertise workspace_channel_observed_contacts.
  • Run the focused server authentication and capability tests.

Task 4: Remove prototype webhook integration

Files: ChannelWebhookTask.ts, ChannelBase.ts, channel config parsing/tests, channel overview documentation

  • Remove observed-reference webhook config and resolution.
  • Restore concrete webhook behavior to origin/main.
  • Verify webhook production files have no diff from origin/main.
  • Replace prototype documentation with the observed-contacts API.

Task 5: Verify and publish

  • Run Prettier on changed files.
  • Run focused base, CLI store, daemon-worker, route, server, runtime, and webhook tests.
  • Run npm run build && npm run typecheck.
  • Audit the full diff twice, including untracked files.
  • Commit, push feat/channel-observed-targets, and update Draft PR #7109.