An agent working from msgvault should be able to answer "what's been going on?" in one read: who I talked to, which meetings happened, what's still open, and what's coming up. Today it has to piece that together from search, calendar, meetings, loops and people tools. Timeline adds that one bounded read, with three views: a day view, a relationship view for one person, and an anchor view around one message or moment. Every entry carries a reference the existing tools already open, so an agent reads the overview first and fetches only the bodies it needs. The pattern comes from claude-mem's search, then timeline, then fetch. This issue tracks the direction while the work lands as a stacked series after the PRs it builds on.
What works today, and why it is not enough
- The activity spine already dates every eligible message and links it to people, and
/days/{date}and/people/{id}/daysserve it over HTTP. No CLI command or MCP tool reads it. It only shows saved people, and it doesn't apply a delegated agent's source scope. - The relationship timeline covers contacts you never saved, but it reads the Parquet cache, so delegated agents and PostgreSQL archives can't use it.
- Calendar occurrences (#1251), meeting links (#1252), call evidence (#1406), open loops (#1305) and signal tiers (#1344) each answer one question well. Putting a day together from them takes an agent five to ten calls, with no shared rule for noise, duplicate copies, or what counts as talking to someone.
https://github.com/user-attachments/assets/a1dd8510-d42d-4f9f-960c-e3515dc5538d
Outcomes
msgvault timelineshows today and yesterday by default: meetings, conversations collapsed to one row per conversation per day, calls, open loops, and the next 48 hours.--days,--dateand--from/--tocover up to 31 days, with older days summarized to one line.msgvault timeline --with <person>shows one relationship: first and last contact, channels, cadence, who usually starts the conversation, monthly counts, open loops, upcoming meetings, then the last 20 entries. It works for saved people and for contacts you never saved.msgvault timeline --around <message|conversation|event|datetime>shows what else was going on around one moment, across the whole archive by default.--withand--conversationnarrow it.--briefis a small version for the start of an agent session, andmsgvault skills install --briefingadds it as an opt-in session-start hook.- The same result through the CLI,
GET /api/v1/timeline, an MCPtimelinetool, a web page, and a TUI mode. Compact markdown by default, JSON on request. - Each entry names the existing tool and arguments that open it:
get_message,list_messages,get_calendar_eventorget_meeting_context. - Responses fit a byte budget (16 KiB by default), continue with a cursor, and say what they left out and why.
# 2026-10-22 · America/Toronto
⚠ calendar work stale since Oct 21 09:00 → msgvault sync-calendar work
Open (1)
- owed Alice T1 4d #9031 "Contract draft v2"
Wed Oct 22
- 09:30 Weekly sync ✓ Alice T1, Bob T2 · notes #8840 · e8812@20261022T1330Z
- Alice T1 · iMessage ↓14 ↑9 · 18:02 · c412
- Bob T2 · email "Q3 budget" ×3, 2 copies · c977
Upcoming
- Thu 10:00 Dinner w/ Alice · e8901Delivery sequence
No PRs are published yet. Each part stacks only on its own prerequisites and retargets main as those land. Parts 1 through 6 add no user-facing surface. Parts 7 through 10 are reviewed together and merge together, so the API, CLI, MCP tool, skill, web page and TUI mode arrive at once.
- One shared counted-event rule, adopted by signal tiers with unchanged results, plus a reader for persisted tiers. Builds on #1353.
- Scoped activity readers for the archive, a conversation, a saved person or an unsaved contact's linked addresses: complete conversation-day groups, a scoped person resolver, and contact aggregates. Builds on #1394, #1431, #1361 and part 1.
- Batch reader for meeting identity, so an event, its copies and its exact-linked notes merge while unlinked ones stay separate. Builds on #1279 and #1263.
- Call identity and per-person credit by participant, so unsaved contacts count too. Builds on #1406.
- Read-time adapter for quiet large rooms, so
--include-coldworks after the policy retracts their activity. Builds on part 2. - The timeline composer: merging, ordering, budget, continuation and rendering. Builds on parts 1 to 5, #1305, #1311 and #1251.
- HTTP route, OpenAPI, CLI and MCP tool. Builds on #1224 for delegated person grants.
- Agent skill and the opt-in briefing hook.
- Web UI timeline page.
- TUI timeline mode.
Design constraints
- Read-only. No schema, migration or cache format change. The only indirect write is the loop reader keeping its evidence cache, inside the daemon, as
loops listdoes today. - A delegated agent's source scope applies inside every reader, before anything is counted. Changing data in a source it can't see leaves its response unchanged. Calls, loops, link suggestions, briefs, agenda, cadence and daily notes stay owner-only.
- Days follow
[activity].timezone, which defaults to UTC. There is no per-request time zone. - Noise filtering uses stored facts only: list mail, the shared counted-event rule, and the tier address exclusions. Quiet large rooms follow #1361, with
--include-coldto add them back. - A meeting is attended when an exact-linked transcript exists. RSVP means invited. Calls follow #1406's answered rule, and time overlap alone only marks an item as possibly related.
- Email copies across accounts collapse by Message-ID. Meetings merge by #1252 and #1279 identity. Invitation emails are never hidden.
- Text written by other people is marked untrusted, and messages flagged by #1431 show no snippet.
- SQLite and PostgreSQL behave the same. Public fixtures and examples use synthetic identities.
Adjacent
- #534: the People roadmap. The relationship view reads its people, briefs and cadence.
- #1200: calendar events and meetings as first-class records. The timeline reads occurrences and links; it doesn't own them.
- #1369: open loops. The timeline shows loops and points to their own actions.
- #1172: MCP Events push IDs when something arrives. The timeline is the pull and catch-up side an agent calls with those IDs.
- #1326: multi-user authorization. The timeline registers in today's read gates and moves into the operation table when that lands.
Questions for review
- Is today plus yesterday at 16 KiB the right default for an agent starting a session?
- Delegated agents can't use the relationship view for unsaved contacts, since there's no person to grant. Is that the right line, or should a grant cover an observed contact too?
- Does the briefing hook belong in
skills install, or somewhere else? - What would you want an agent to see first that isn't here?
@rodboev inspired by
timelinein https://github.com/thedotmack/claude-mem