Daily Digest — Authoring Contract
Overview
<mount>/digests/ is a relayfile-managed directory containing deterministic, pre-computed Markdown summaries of provider activity over fixed time windows. Digests are the cheap entry point for activity-summary queries (see the activity-summary skill). This skill is for producers — adapter authors, provider integrators, and anyone extending what shows up in a digest.
When to use this skill
- You are writing a new relayfile adapter (Notion, Linear, …) and need to wire it into the digest pipeline.
- You want a new digest window (e.g.
last-30-days.md) and need to know the contract. - A digest is missing a provider's content and you need to know why.
- You need to debug why
yesterday.mdwas empty or stale this morning.
If you're an agent reading the digest to answer a user question, switch to the activity-summary skill instead.
Digest file taxonomy
| File | Window | Mutability |
|---|---|---|
today.md |
00:00 local → now | Updated on every change-event for the current day |
yesterday.md |
full prior calendar day | Generated at 00:00 local, immutable for the rest of the day |
YYYY-MM-DD.md |
that calendar day | Immutable once the day closes |
this-week.md |
Mon 00:00 → now (ISO week) | Updated on every change-event |
last-week.md |
full prior ISO week | Immutable |
A digest file is always present for each window even if the window contains no activity (the body says _no activity_). Agents can detect empty windows without retrying.
File header
Every digest starts with a frontmatter-style header that callers can verify before trusting the body:
# Activity for 2026-05-12
> window: 2026-05-12T00:00:00-07:00 → 2026-05-13T00:00:00-07:00
> generated: 2026-05-13T00:01:14Z
> providers: linear, github, notion, slack
> events: 47
windowis the half-open interval in the workspace's configured timezone.providerslists every adapter that contributed (or attempted to). A missing provider here means the adapter never ran, not that it had zero activity.eventsis the raw change-event count over the window — useful for sanity-checking against the body.
Per-provider section format
Each provider gets exactly one ## <provider> section, in alphabetical order. Bullets within a section are sorted by event time, ascending. Each bullet must:
- Start with the canonical record identifier the provider uses (
AGE-16,#412, page title, etc.). - Describe the change in past tense — "moved to Blocked", "merged to main", "edited".
- End with a Markdown link to the canonical file path in the mount, in square brackets.
## linear
- AGE-16 moved to Blocked (waiting on design) — [/linear/issues/AGE-16__87389837-62b1-4e1a-a237-59218bab2974.json]
- AGE-9 closed — [/linear/issues/AGE-9__2bb2c00f-ee93-4c73-a793-df5b725d9a1a.json]
The link target is what makes the digest interactive — a follow-up "tell me more about AGE-16" is one cat away from the digest line.
Adapter contract
For an adapter to contribute to digests it must export a digest() function in addition to its sync/writeback handlers:
import type { DigestContext, DigestSection } from '@relayfile/adapter-sdk';
export async function digest(ctx: DigestContext): Promise<DigestSection | null> {
const events = await ctx.changeEvents({
window: ctx.window, // { from: ISO8601, to: ISO8601 }
providers: [ctx.provider],
});
if (events.length === 0) return null;
return {
provider: ctx.provider,
bullets: events.map((e) => ({
text: renderBullet(e),
canonicalPath: e.resource.path,
})),
};
}
Returning null is correct for "ran successfully, no activity"; throwing is reserved for "could not produce a digest" and surfaces as a warning in the digest header.
Regeneration
- Rolling windows (
today.md,this-week.md) are regenerated on every change event for the current window, coalesced to a max of one rebuild per 30 seconds. - Closing windows (
yesterday.md,YYYY-MM-DD.md,last-week.md) are produced once at window close (00:00 local for daily, Monday 00:00 for weekly) and never modified afterward. This is what makes them safe to cache and quote verbatim. - If you need to force a rebuild (e.g. after fixing an adapter bug),
relayfile digest rebuild --window yesterdayre-derives from the change log.
Common mistakes when adding a new digest
- Don't inline raw provider payloads. Bullets are one line. Anything larger belongs in the canonical file the bullet links to.
- Don't summarize across providers in one section. Cross-provider correlation is the agent's job; the digest's job is exhaustive per-provider listing.
- Don't omit the canonical link. A digest line without a link is dead weight — the agent can't follow up without re-deriving the path.
- Don't generate non-deterministic content. Two runs over the same change-event window must produce byte-identical output. LLM-generated prose belongs in the agent, not the digest.