Appearance
Thread Briefs
Thread Briefs give Iris peripheral awareness of what's happening across all your conversations. Each brief is a short, 3-6 sentence digest of a thread's current state — what you're working on, key decisions made, and how you're feeling about it. They're generated automatically in the background and injected into other threads' system prompts, so Iris can connect ideas, reference related work, and avoid asking questions you've already answered elsewhere.
Why Thread Briefs?
Without briefs, every thread is an island. Memories and Truths capture who you are — your preferences, relationships, and stable facts — but they don't capture what you're actively working on. If you're debugging a database migration in one thread and designing an API in another, Iris has no way to connect the two.
Thread Briefs fill that gap. They're lightweight enough to include in every request (~100-200 tokens per brief) but rich enough to give Iris meaningful cross-thread context.
What briefs enable:
- Cross-thread connections: Iris can suggest that the schema decisions in Thread A affect the API design in Thread B
- No redundant questions: If you've established your database choice in one thread, Iris won't re-ask it in another
- Smarter proactive messages: The heartbeat uses briefs to understand what you're working on across threads, replacing noisy message fragments with semantic understanding
How They Work
Briefs generate automatically as you chat. After every 2 assistant responses (configurable), a background job dispatches that reads the thread's recent messages, previous brief, and latest summary (if one exists), then produces an updated digest using a fast, inexpensive model.
Generation Flow
- You exchange messages in a thread
- After the configured number of assistant responses,
GenerateThreadBriefdispatches - The job loads the last ~10 messages, the existing brief (for continuity), and the latest conversation summary (for structured context like decisions and goals)
- A fast model (Haiku by default) produces a 3-6 sentence digest
- The brief is stored on the thread and immediately available to other threads
What a Brief Captures
Each brief covers four dimensions:
- Topic: What the thread is about right now
- Key decisions and facts: Important choices or information established in the conversation
- Current status: Where things stand — in progress, stuck, resolved
- Emotional context: How you're feeling — frustrated, energized, in flow, stuck
The emotional dimension is particularly valuable for proactive messaging. It helps Iris decide whether to reach out ("you've been stuck for a while — want a hand?") or give you space ("you're in flow — no interruption needed").
Brief Continuity
Each generation includes the previous brief as input, so briefs evolve naturally as conversations progress. Early in a thread, a brief might be sparse: "Exploring options for background job monitoring in Laravel. Early conversation, no decisions yet." As the thread develops, it becomes richer and more specific.
When a conversation summary exists, the brief generator also incorporates its structured data — key decisions, accomplishments, active goals, and emotional markers. This means briefs stay informed even when the last 10 messages are a narrow window into a longer conversation.
Cross-Thread Context
The primary use of briefs is cross-thread awareness during regular chat. A CrossThreadContextPrompt loads briefs from your most recently active threads (up to 5 by default) and injects them into the system prompt.
Here's what Iris sees:
## Other Active Conversations
- **Database Migration Strategy** (last active: Apr 27, 1:00pm EDT):
TJ is migrating from MySQL to PostgreSQL. Decided on staged rollout
using Laravel migrations. Currently working on the user table schema.
TJ is frustrated with some foreign key constraint issues but making progress.
- **API Rate Limiting** (last active: Apr 26, 3:15pm EDT):
Discussed rate limiting approaches for the public API. Settled on token
bucket with Redis. TJ wants 100 req/min for free tier. TJ was energized
and in flow state during this design session.Key design decisions:
- Current thread excluded: Iris never sees a brief of the conversation you're actively in — that would be redundant and waste tokens
- Static timestamps: Timestamps use a fixed format (e.g., "Apr 27, 1:00pm EDT") rather than relative times ("2 hours ago"). This is critical for prompt caching — relative timestamps change every minute and invalidate the cache, while static timestamps only change when a thread actually updates
- Empty is silent: When no other threads have briefs, the prompt renders nothing — no "No active threads" placeholder
- User-scoped: The query only returns threads belonging to the authenticated user
Heartbeat Integration
The heartbeat uses the same briefs to understand what you're working on when deciding whether to proactively message you. Before briefs, the heartbeat loaded raw message fragments — the last 10 turns from your 3 most active threads, each truncated to 200 characters. This was noisy, token-expensive, and semantically shallow.
With briefs, the heartbeat gets dense, meaningful context: what each thread is about, what decisions were made, and how you're feeling. This produces better decisions about when to reach out and what tone to use.
Threads without briefs are excluded from heartbeat context — there's no fallback to raw messages.
Graceful Degradation
Briefs are designed to degrade silently:
- New threads don't have briefs until enough messages are exchanged — other threads and the heartbeat work with what's available
- Failed generation leaves the previous brief intact (or null if none existed) — no error surfaces to you
- Disabled briefs (
iris.briefs.enabled = false) turns everything off — no generation, no cross-thread injection, no heartbeat brief context
Configuration
All brief settings live under iris.briefs in config/iris.php:
| Setting | Default | Description |
|---|---|---|
briefs.enabled | true | Master toggle for all brief-related behavior |
briefs.frequency | 2 | Assistant responses between brief generations |
briefs.threshold | 2 | Minimum assistant responses before first brief |
briefs.max_threads | 5 | Maximum threads shown in cross-thread context |
briefs.provider | anthropic | Prism provider for brief generation |
briefs.model | claude-haiku-4-5 | Model for generating briefs |
briefs.timeout | 15 | Timeout in seconds for generation |
Customizing
php
// config/iris-custom.php
return [
'briefs' => [
'frequency' => 3, // Generate less often
'max_threads' => 3, // Show fewer threads in cross-thread context
],
];Disabling Briefs
Set the environment variable or config:
bash
# .env
IRIS_BRIEFS_ENABLED=falseWhen disabled, no GenerateThreadBrief jobs dispatch, the cross-thread context prompt renders empty, and the heartbeat includes no thread brief content.
TIP
Brief generation uses a fast, inexpensive model by default. At roughly $0.001 per brief, the cost is negligible — even with frequent generation across many threads.
How Briefs Relate to Other Systems
| System | Relationship |
|---|---|
| Memories | Memories capture stable facts about you. Briefs capture what you're actively working on. They're complementary — memories persist, briefs are ephemeral snapshots. |
| Summaries | Summaries are rich, structured compactions of conversation history within a thread. Brief generation uses the latest summary as input when available, distilling it into a few sentences for cross-thread use. |
| Proactive Messages | The heartbeat uses briefs instead of raw message fragments for "read the room" context. Emotional markers in briefs directly inform outreach decisions. |
| System Prompts | CrossThreadContextPrompt is registered in the pinned content cache group, sharing an ephemeral cache breakpoint. |
See Also
- Threads — how threads organize conversations
- System Prompts — how briefs are injected into the prompt pipeline
- Proactive Messages — how the heartbeat uses briefs
- Background Jobs — how
GenerateThreadBriefruns