Skip to content

Roadmap: richer people profiles, relationships, and CardDAV #534

Description

@salmonumbrella

The durable person root introduced in #531 is the base for a broader People and CardDAV upgrade. This issue tracks the direction so each focused pull request can stay reviewable without losing the larger context.

Outcomes

  • Rich, typed person profiles with provenance, history, custom fields, structured names, contact points, addresses, dates, media, and categories.
  • Organizations, complete employment history, and typed temporal relationships represented as first-class records rather than copied display fields.
  • Explainable identity resolution that preserves source evidence and requires review for ambiguous matches instead of merging people by name or email alone.
  • A dated activity layer that derives contact recency and cadence from archived messages, chats, and meetings without request-time full-archive scans.
  • Person-scoped attachments: scoped collection policy that keeps the media worth keeping, searchable document and visual attachments, a per-person Media and Files gallery, and the same person-scoped question answerable from the web, MCP, and the CLI.
  • A scheduled people sweep that keeps curated attributes current from the archive: deterministic fields for everyone, evidence-backed extracted candidates for tracked people with a per-attribute auto-apply policy, bitemporal supersession instead of overwrites, and a dated "last time we talked" brief.
  • Lossless vCard support with stable UID continuity and preservation of unknown properties, and a standards-only CardDAV client that syncs curated people into the user's existing address book server. Msgvault does not serve CardDAV.
  • A web Directory workspace and bounded people-network projection built on the same typed APIs.
  • Optional contact enrichment inspired by Mesh, with contact details, public profiles, organizations, and employment changes.
  • A fresh install that reaches all of the above from a pasted Voyage key and Mistral key, one consent per hosted provider, and recommended defaults everywhere else.

Delivery sequence

  1. Establish the lossless, registry-backed vCard syntax boundary (Add lossless registry-backed vCard codec #533).
  2. Add portable field metadata and typed, historized custom attributes (Add portable field metadata and typed person attributes #535).
  3. Add structured profile primitives and service-scoped contact observations (feat(store): add structured person profile primitives #565).
  4. Add reviewable identity candidates for importer evidence (feat(beeper): add reviewable identity candidates #596).
  5. Add organizations and temporal employment associations (feat(people): add organizations and employment records #593).
  6. Add canonical typed person relationships (feat(people): add typed temporal relationships #592).
  7. Make chats and meetings semantically retrievable for relationship queries: conversation-window embedding units and turn-aware transcript chunking (feat(vector): add contextual chat and transcript embeddings #589).
  8. Embed curated person attributes into one document per person so semantic people search ("a finance expert in New York") returns the contact directly (feat(people): add semantic person search #656).
  9. Add per-account and conversation-scoped attachment policy — media_scope, a participant threshold, typed skip markers that distinguish a deliberate skip from a failed download, and a purge path for media a changed policy no longer collects (feat(media): add scoped attachment policies and excluded-media purge #620). Report durable over-cap drops and retry them only after the cap changes (fix(beeper): report durable over-cap media skips #648).
  10. Add searchable document and visual attachments while preserving exact message and attachment-occurrence provenance: Docbank-backed PDF extraction and lexical document search (feat(documents): index attachments with shared Docbank processing #635); capability-gated visual attachment search through Docbank's public media and Voyage packages (feat(vector): add capability-gated visual attachment search #650); and document vectors, semantic retrieval, and lexical/vector fusion through the existing vector machinery (feat(documents): add semantic attachment search #664). The provider-neutral Docbank processing, embedding, and retrieval dependency is tracked upstream in kenn-io/docbank#176 before downstream adoption. Broader authenticated document-format coverage remains tracked by Add opt-in semantic search for every authenticated Mistral document format #608.
  11. Add a person-scoped cross-channel Media and Files gallery to show all attachments received from a person (feat(web): add person attachment galleries #622).
  12. Expose person-scoped attachment retrieval through MCP and the CLI over one person identity and one direction vocabulary, across metadata, document, and visual lanes, degrading to metadata-only when a lane is unavailable (Retrieve person files across metadata, documents, and visual search #668, superseding Retrieve person files across metadata, documents, and visual search #658).
  13. Add dated activity and computed contact state (feat(activity): add dated contact activity #599).
  14. Add a lossless native vCard resource envelope (feat(vcard): add lossless native resource envelopes #621).
  15. Merge two person profiles into one when they turn out to be the same human, and split them back: survivor keeps its ID and vCard UID, the retired UID becomes an alias, every curated row moves with its provenance, and the link and candidate flows offer merge instead of failing on person_binding_conflict (feat(people): add reversible profile merges #655).
  16. Add a CardDAV client that syncs curated people into an external address book (feat(carddav): add bidirectional client sync #654).
  17. Add a scheduled people sweep that keeps attributes current from the archive. The no-model catalog and tracking foundation (Add person profile catalog and tracking foundation #644) and consent-gated inference-provider boundary (feat(people): add consent-gated inference providers #653) are merged; the shared person-fact ledger and automatic resolution layer (feat(people): add person fact ledger and automatic resolution #677); archive inference (feat(people): add person facts self-healing #685) and external enrichment (feat(people): add person external enrichment #686) are in review, while dated briefs and review surfaces remain (feat(people): add provider-neutral sweep profiles #694).
  18. Add a keyboard-first TUI People browser over the merged profile, relationship, activity, meeting, and person-file primitives, with dossier tabs, promotion, historized attributes, and private notes (feat(tui): add People browser #669).
  19. Expose the resulting model through a web Directory workspace and bounded network views: every typed fact about a person visible and editable in place on the existing kit-ui components, with the identity and fact review queues in the same shell (feat(web): add Directory and Settings workspaces #705).
  20. Ship recommended defaults and a setup pass that ties the stack together: provider defaults keyed off the keys the operator has (Voyage contextual + multimodal, Mistral documents via Docbank, OpenAI-compatible or local Ollama fallbacks), a participant cap on group-room media, the seeded attribute catalog and sweep schedule, the inference-model default for synthesis, and an MCP surface that answers "when did we last talk", "who is this", "who was active", and "which network" out of the box (Ship recommended defaults and a setup pass that turns on the people and attachment stack #634).

Design constraints

  • SQLite and PostgreSQL remain behaviorally equivalent.
  • New profile facts are typed and provenance-aware; mutable facts retain history.
  • Creating a custom field inserts metadata and values, never runtime DDL.
  • Unknown vCard data survives round trips until Msgvault explicitly manages it.
  • Published person UIDs are stable and never silently reassigned.
  • Identity evidence is preserved; ambiguous matches are reviewable and reversible.
  • One person can hold multiple current and historical emails, phones, usernames, social profiles, and other contact points.
  • The attachment occurrence stays message-owned; person scope is a filter, never ownership.
  • External enrichment is disabled by default, receives no message or transcript content, and writes candidates rather than curated facts.
  • Public fixtures and examples contain only synthetic identities.

Bonus: auto merge

Later, add optional public-data enrichment behind a provider-neutral adapter, explicit consent, cost limits, provenance, and review.

Same-name records should create a suggestion and trigger a search for stronger evidence. Automatic merge is parked as bonus research: look at mature identity-resolution systems, strong identifiers, multi-signal scoring, false-positive rates, and reversible split/unmerge behavior. Name, email, or phone similarity alone is not enough for an irreversible merge.

Adjacent

Once #664 lands, the chat/transcript, visual-attachment, and attachment-document embedding lanes should pass a shared retrieval evaluation before the roadmap's semantic-search work is treated as complete.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions