Skip to content

feat(mobile): add morning briefings for overnight agent activity - #7602

Merged
iscekic merged 14 commits into
mainfrom
igor/agent-morning-briefing
Oct 19, 2026
Merged

iscekic merged 14 commits into
mainfrom
igor/agent-morning-briefing

Conversation

@iscekic

@iscekic iscekic commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds a morning briefing for cloud and CLI coding sessions. The backend prepares one report per Personal or organization context from timestamped overnight evidence. Each morning, the mobile Home card shows the briefing in place of live status until the user dismisses it or the morning ends.

Behavior

  • Schedule: users set a saved time zone, a night start, a shared night-end/morning-start, and a morning end. Schedule changes apply only to future nights.
  • Scope: reports include only the user's own sessions, with Personal and each organization kept separate. A context gets a report only when it had overnight activity. An older blocker that did not change overnight is not included.
  • Scorecard:
    • The scorecard shows sessions active overnight, PRs opened, new unresolved blockers, and overnight spend.
    • Spend counts only what was charged during the night, not each session's lifetime total.
    • If some evidence is missing, the value is shown as a lower bound or as unknown, never as a zero.
  • Home: the briefing uses the same card space as the live-status card, so dismissing it does not shift the layout. Dismissal applies across devices, and the card disappears at morning end, even offline. Reports stay in the history for 30 days.
  • Late evidence: overnight activity that arrives late revises the report until morning end. After that, the report is frozen.
  • AI summary:
    • The AI summary is optional, enabled separately per context, and billed to that context's balance.
    • Kilo picks the default model, and the user can choose another.
    • Before a user enables it or retries it, the app shows an estimate that is tied to the chosen settings.
    • Each generation has a time limit and a spend limit (defaults: 10 minutes and $2). Users can change both, but not remove them.
    • A report is published once its summary is ready, or after five minutes at most. In the second case the summary attaches when it finishes. A failed generation that incurred a charge is never retried automatically.
  • Notifications: a separate, default-off category. Each user gets at most one generic push per morning, sent when the first report is ready.
  • Privacy:
    • Excerpts are redacted before they are stored or sent to the model.
    • When a source session is deleted or moved out of the context, the summary text that used it is removed.
    • When a user loses access to an organization, the app purges only that organization's cached reports.
    • Deleting an account also deletes all briefing data.

Implementation notes

  • Session ingest now writes every activity and status change to a durable outbox. A Durable Object alarm retries failed writes. A status_transition_id ordering marker keeps an older, delayed status from overwriting a newer one.
  • The gateway checks the spend limit after provider-specific request rewriting and before the single upstream request. Allowing fallback providers is turned off, and a model with unknown pricing is rejected.
  • One additive migration: four new agent_briefing_* tables and a nullable cli_sessions_v2.status_transition_id column.
  • This PR adds two protected cron routes. Their schedules are configured in apps/web/vercel.json.
  • Schedule times use the @expo/ui 57 community datetime-picker, which is already installed, so the PR adds no new dependency. There is no time zone picker in the existing UI library, so the app keeps a validated IANA text field with a "Use device time zone" action.
  • The 86 locale catalogs have translations for every new key.

Dependency

  • The CLI must report when each status change happened and in what order. Kilo-Org/kilocode#15124 adds this. Until it ships, sessions from older CLI versions are shown with partial blocker coverage, not exact counts.

Verification

I ran the following on an isolated VM with a fake database and fake accounts. No real pushes and no paid model calls were made.

  • Targeted tests passed for the web briefing, gateway cost limit, GitHub PR evidence, user deletion, session ingest (full package), notifications, and the mobile briefing state, cache, filter and notification route.
  • Typecheck passed for web, mobile, session-ingest, notifications, app-shared, db and web-shared. Lint, the catalog and plural checks, the unused-code check and the formatter passed for the changed packages.
  • The squashed migration applied to a fresh database.
  • A backend smoke test exercised the real HTTP session ingest, the scheduler, and authenticated tRPC calls. It covered scoped reports, merging child sessions into their parent, removing duplicate PRs, overnight-only spend, denial across users and organizations, persistence of read and dismiss state, late revision, and the freeze at morning end.
  • A smoke test of the AI summary used a local fixture provider. It covered the consent estimate, a model override, publication at five minutes with the summary attached afterwards, charge reconciliation, a billable failure with no automatic retry, the time limit, and the Claude text-block cost check.
  • The native iOS check is blocked. The prebuilt dev client for this fingerprint was built with Xcode 17F113 and simulator SDK 26.5. The host has Xcode 27A9275 with SDK 27.1, so the compatibility check rejects the artifact.

Adds backend-scheduled overnight reports for cloud and CLI coding sessions, a Home card that temporarily replaces live status, report history, schedule settings, an optional paid AI summary with finite safeguards, and a separate opt-in briefing notification.
@iscekic iscekic self-assigned this Oct 15, 2026
Comment thread apps/mobile/src/lib/agent-briefing.ts Resolved
Comment thread services/kilo-mcp/catalog.json Resolved
@kilo-code-bot

kilo-code-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The only PR-owned change since the previous review is the default briefing summary model swap to the ~deepseek/deepseek-flash-latest alias (store.ts) plus its DEVELOPMENT.md note and the origin/main merge resolution; all verified consistent, with no new findings.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0

What Changed Since The Last Review

  • apps/web/src/lib/agent-briefing/store.ts now defines DEFAULT_BRIEFING_MODEL = '~deepseek/deepseek-flash-latest' and uses it for defaultModel and per-context model, replacing PRIMARY_DEFAULT_MODEL. No dangling import references remain (grep PRIMARY_DEFAULT_MODEL in the file returns nothing), and no PR test asserts the previous default.
  • The origin/main merge resolved conflicts in packages/db/src/migrations/meta/_journal.json, packages/db/src/migrations/meta/0281_snapshot.json, and .kilo/skills/kilo-mcp/SKILL.md. The migration was renamed 0281_agent_briefing.sql → 0283_tired_gideon.sql (content identical), and the journal/snapshot chain is consistent: 0281_drop_unused_tables (id c02a3b39) → 0282_sleepy_stature (id 3817863b) → 0283_tired_gideon (id ec40d619), with no stale 0281_agent_briefing tag and no leftover conflict markers.
  • .kilo/skills/kilo-mcp/SKILL.md counts (900 procedures = 384 queries + 516 mutations, 55 prefixes) match catalog.json. The catalog.json delta is only main's organizations.autoTopUp additions; agentBriefing still exposes only dismiss, estimateSummary, get, list, preferences, read, and updatePreferences, so the charging mutations remain withheld.

Note: the merge also pulled in unrelated origin/main commits that are not part of this PR's diff; those were not re-reviewed here.

Files Reviewed (7 files)
  • apps/web/src/lib/agent-briefing/store.ts - no issues
  • DEVELOPMENT.md - no issues
  • packages/db/src/migrations/0283_tired_gideon.sql - rename only, content unchanged
  • packages/db/src/migrations/meta/_journal.json - consistent
  • packages/db/src/migrations/meta/0281_snapshot.json / 0283_snapshot.json - consistent chain
  • .kilo/skills/kilo-mcp/SKILL.md - counts match catalog
  • services/kilo-mcp/catalog.json - native-only withholding intact
Previous Review Summaries (5 snapshots, latest commit a00239e)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit a00239e)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Since the previous review the branch merged origin/main and the only PR-owned changes are the generated agentBriefing MCP catalog refresh, the matching SKILL.md counts, and a conflict-free migration rename to 0281; all verified consistent with the withholding logic and the router, so no new findings.

Files Reviewed (7 files)
  • .kilo/skills/kilo-mcp/SKILL.md - procedure/query/mutation/prefix counts verified against catalog.json (899 / 384 / 515 / 55)
  • services/kilo-mcp/catalog.json - exposes only agentBriefing dismiss, estimateSummary, get, list, preferences, read, updatePreferences
  • packages/db/src/migrations/0281_agent_briefing.sql - content unchanged; rename only
  • packages/db/src/migrations/meta/_journal.json - 0281_agent_briefing entry present, no stale 0280_agent_briefing references
  • packages/db/src/migrations/meta/0281_snapshot.json - regenerated snapshot
  • apps/web/src/routers/agent-briefing-router.ts - verified exposed vs withheld procedures and the estimate-token gate
  • apps/web/src/scripts/mcp-catalog/catalog.ts - NATIVE_ONLY_PATHS still withholds generateSummary, retrySummary, and updateContextPreferences

The merge of origin/main pulled in unrelated commits (for example the AI gateway secure-proxy and cloud-agent-profile work) that are not part of this PR's diff and were not re-reviewed here.

Fix these issues in Kilo Cloud

Previous review (commit 7f1a3a2)

Status: No Issues Found | Recommendation: Merge

Executive Summary

This incremental commit fixes every finding from the previous review (NOT_FOUND no longer treated as access denial, the evidence flush now honors the retry backoff and clears its pending flag, the session scan is bounded to active sessions plus ancestors, group status merges all sessions, the gateway counts all request text, and the charging agentBriefing mutations are withheld from MCP) and I found no new issues in the changed code.

Files Reviewed (21 changed files plus 12 locale catalogs and 7 test files)
  • .kilo/skills/kilo-mcp/SKILL.md - procedure counts match the regenerated catalog
  • apps/mobile/src/components/agent-briefing/briefing-context-settings.tsx - validation now bounded to the server's 600s cap
  • apps/mobile/src/components/agent-briefing/briefing-detail-screen.tsx - NOT_FOUND handled as a missing report, query cache scoped removal
  • apps/mobile/src/components/agent-briefing/briefing-list-screen.tsx - import move
  • apps/mobile/src/components/agent-briefing/briefing-settings-screen.tsx - import move
  • apps/mobile/src/components/agent-briefing/briefing-sync-mount.tsx - dismissal journal sync now backs off and stops, timer cleaned up
  • apps/mobile/src/lib/agent-briefing-state.ts - new state/parse helpers, bounded safeguards
  • apps/mobile/src/lib/agent-briefing.ts - NOT_FOUND removed from access denial, no longer purges read-cache
  • apps/mobile/src/i18n/locales/*.json (12 catalogs) - added the four estimate keys
  • apps/web/src/lib/agent-briefing/evidence.ts - bounded session load with ancestor walk, group status from every merged session, status provenance query
  • apps/web/src/routers/agent-briefing-router.test.ts - coverage for the ancestor load and provenance
  • apps/web/src/scripts/mcp-catalog/catalog.ts - charging agentBriefing mutations withheld from MCP
  • packages/web-shared/src/lib/ai-gateway/request-cost-limit.ts - input ceiling counts every request text field
  • services/kilo-mcp/catalog.json - regenerated without the withheld mutations
  • services/session-ingest/src/dos/SessionIngestDO.ts - retry backoff honored on ingest, pending flag cleared, in-flight evidence re-flushed
  • services/session-ingest/src/ingest/briefing-evidence.ts - deleted-session drop documented as intentional

Previous review (commit 07ed6e3)

Status: 10 Issues Found | Recommendation: Address before merge

Executive Summary

The accidental 1,478-file duplicate of the mobile source under apps/mobile/src/work/cloud/ is now deleted (the earlier CRITICAL is resolved), while the remaining ten findings are unchanged code and still present in the current tree.

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 5
Issue Details (click to expand)

WARNING

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 837 Ingest-driven evidence flush ignores briefingEvidenceRetryAt, retrying Postgres at ingest rate.
apps/web/src/lib/agent-briefing/evidence.ts 308 Every session the user owns is loaded (unbounded, no time window) on each briefing refresh.
apps/mobile/src/lib/agent-briefing.ts 34 NOT_FOUND counts as access denial, so a stale deep link purges the read-cache blob.
apps/mobile/src/components/agent-briefing/briefing-sync-mount.tsx 96 A persistently failing journal write loops dismiss requests and KV writes with no backoff.
services/kilo-mcp/catalog.json 171 agentBriefing.generateSummary/retrySummary are newly MCP-exposed mutations that charge the user's balance.

SUGGESTION

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 143 briefingEvidencePending is never reset to false, so every ingest/alarm scans the drained outbox.
services/session-ingest/src/ingest/briefing-evidence.ts 134 Evidence is acked and deleted when the session row is missing, instead of being retried.
apps/web/src/lib/agent-briefing/evidence.ts 236 Merged group status only reads the root session, missing child-only status transitions.
packages/web-shared/src/lib/ai-gateway/request-cost-limit.ts 97 Input ceiling ignores non-messages input (for example Anthropic top-level system).
apps/mobile/src/components/agent-briefing/briefing-context-settings.tsx 99 Local validation allows maxDurationSeconds above the server cap of 600.
Files Reviewed (3 changed files plus 1,478 deleted duplicate files)
  • apps/mobile/src/components/agent-briefing/briefing-card.tsx - cosmetic size/color/affordance change, no issue
  • apps/mobile/src/components/agent-briefing/briefing-detail-screen.tsx - coverage hint now shows only when a coverage field is not complete, no issue
  • dev/seed/app/agent-briefing.ts - seed fixture now writes per-session status evidence and backfills created_at, no issue
  • apps/mobile/src/work/cloud/** (1,478 duplicate files) - deleted by this commit, prior CRITICAL resolved

Fix these issues in Kilo Cloud

Previous review (commit 5539807)

Status: 11 Issues Found | Recommendation: Address before merge

Executive Summary

This follow-up commit accidentally commits a full 1,478-file duplicate of the mobile app source under apps/mobile/src/work/cloud/; all ten findings from the previous review are still present in the current code.

Overview

Severity Count
CRITICAL 1
WARNING 5
SUGGESTION 5
Issue Details (click to expand)

CRITICAL

File Line Issue
apps/mobile/src/work/cloud/apps/mobile/src/lib/utils.ts 1 1,478 files duplicating apps/mobile/src/** were committed under apps/mobile/src/work/cloud/.

WARNING

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 837 Ingest-driven evidence flush ignores briefingEvidenceRetryAt, retrying Postgres at ingest rate during an outage.
apps/web/src/lib/agent-briefing/evidence.ts 308 Every session the user owns is loaded (unbounded, no time window) on each briefing refresh.
apps/mobile/src/lib/agent-briefing.ts 34 NOT_FOUND counts as access denial, so a stale deep link deletes the entire read-cache blob and shows a permission error.
apps/mobile/src/components/agent-briefing/briefing-sync-mount.tsx 96 A persistently failing journal write loops dismiss requests and KV writes with no backoff.
services/kilo-mcp/catalog.json 171 agentBriefing.generateSummary/retrySummary are newly MCP-exposed mutations that charge the user's balance.

SUGGESTION

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 143 briefingEvidencePending is never reset to false, so every ingest/alarm scans the drained outbox.
services/session-ingest/src/ingest/briefing-evidence.ts 134 Evidence is acked and deleted when the session row is missing, instead of being retried.
apps/web/src/lib/agent-briefing/evidence.ts 236 Merged group status only reads the root session, missing child-only status transitions counted as blockers.
packages/web-shared/src/lib/ai-gateway/request-cost-limit.ts 97 Input ceiling ignores non-messages input (for example Anthropic top-level system), weakening the spend safeguard.
apps/mobile/src/components/agent-briefing/briefing-context-settings.tsx 99 Local validation allows maxDurationSeconds above the server cap of 600, failing later with a generic error.
Files Reviewed (98 changed files plus the 1,478-file duplicate)
  • apps/mobile/src/components/agent-briefing/* (card, context/detail/schedule/summary settings) - reviewed
  • apps/mobile/src/components/home/* (agent-sessions-section, home-agent-sessions-section, home-screen) - reviewed
  • apps/mobile/src/lib/agent-briefing.ts, agent-briefing-state.ts, agent-briefing-dismissals.ts - reviewed
  • apps/mobile/src/lib/persist/cache-scope.ts, read-cache.ts - reviewed
  • apps/web/src/lib/agent-briefing/evidence.ts - 2 issues
  • dev/seed/app/agent-briefing.ts - reviewed
  • apps/mobile/src/i18n/locales/* (75 catalogs) - reviewed
  • mobile/web test files - reviewed
  • apps/mobile/src/work/cloud/** (1,478 duplicate files) - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit a83f36a)

Status: 10 Issues Found | Recommendation: Address before merge

Executive Summary

The highest-risk findings are in the session-ingest evidence outbox (an ingest-driven flush that bypasses its own retry backoff) and in the mobile briefing client (NOT_FOUND wrongly treated as access denial, wiping the whole persisted read cache); no memory leaks, cross-tenant leakage, or cron-auth problems were found.

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 5
Issue Details (click to expand)

WARNING

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 837 Ingest-driven evidence flush ignores briefingEvidenceRetryAt, retrying Postgres at ingest rate during an outage.
apps/web/src/lib/agent-briefing/evidence.ts 266 Every session the user owns is loaded (unbounded, no time window) on each briefing refresh.
apps/mobile/src/lib/agent-briefing.ts 34 NOT_FOUND counts as access denial, so a stale deep link deletes the entire read-cache blob and shows a permission error.
apps/mobile/src/components/agent-briefing/briefing-sync-mount.tsx 96 A persistently failing journal write loops dismiss requests and KV writes with no backoff.
services/kilo-mcp/catalog.json 171 agentBriefing.generateSummary/retrySummary are newly MCP-exposed mutations that charge the user's balance.

SUGGESTION

File Line Issue
services/session-ingest/src/dos/SessionIngestDO.ts 143 briefingEvidencePending is never reset to false, so every ingest/alarm scans the drained outbox.
services/session-ingest/src/ingest/briefing-evidence.ts 134 Evidence is acked and deleted when the session row is missing, instead of being retried.
apps/web/src/lib/agent-briefing/evidence.ts 202 Merged group status only reads the root session, missing child-only status transitions counted as blockers.
packages/web-shared/src/lib/ai-gateway/request-cost-limit.ts 97 Input ceiling ignores non-messages input (e.g. Anthropic top-level system), weakening the spend safeguard.
apps/mobile/src/components/agent-briefing/briefing-context-settings.tsx 98 Local validation allows maxDurationSeconds above the server cap of 600, failing later with a generic error.
Files Reviewed (71 files)
  • apps/mobile/src/components/agent-briefing/* (card, context/detail/list/notification/schedule/settings/summary/sync-mount) - 3 issues
  • apps/mobile/src/components/home/* (agent-sessions-section, glanceable-active-card, adaptive-home-card-frame) - reviewed
  • apps/mobile/src/components/notifications-screen.tsx, profile-screen.tsx - reviewed
  • apps/mobile/src/app/(app)/agent-briefing/*, _layout.tsx - reviewed
  • apps/mobile/src/lib/agent-briefing*.ts, lib/hooks/use-briefing-list-filters.ts, lib/persist/read-cache.ts - 2 issues
  • apps/mobile/src/i18n/locales/*.json (86 catalogs) - reviewed
  • apps/web/src/lib/agent-briefing/* (evidence, schedule, store, summary, sweep) - 2 issues
  • apps/web/src/app/api/cron/agent-briefing*/route.ts - reviewed
  • apps/web/src/routers/agent-briefing-router.ts, cli-sessions-v2-router.ts, root-router.ts - reviewed
  • apps/web/src/lib/integrations/platforms/github/*, lib/user/index.ts - reviewed
  • packages/app-shared/src/agent-briefing.ts, packages/db/* (schema, migration 0280) - reviewed
  • packages/notifications/src/*, packages/trpc/src/mobile.ts - reviewed
  • packages/web-shared/src/lib/ai-gateway/* - 1 issue
  • packages/web-shared/src/lib/notifications-worker-client.ts - reviewed
  • services/notifications/* - reviewed
  • services/session-ingest/* - 3 issues
  • services/kilo-mcp/catalog.json, .kilo/skills/kilo-mcp/SKILL.md - 1 issue
  • DEVELOPMENT.md, apps/web/vercel.json, tools/i18n/check-catalogs.mjs - reviewed

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 98.4K · Output: 26K · Cached: 2.4M

Review guidance: REVIEW.md from base branch main

…rting

Fixes device-found briefing defects, native module import boundaries in mounted tests, coverage computation from evidence, seed topic, and translations for all briefing keys.
@iscekic
iscekic force-pushed the igor/agent-morning-briefing branch from 5539807 to d928d7e Compare October 15, 2026 18:14
iscekic and others added 6 commits October 15, 2026 20:27
…off and cost ceiling

- bound the briefing evidence read path to active sessions and their ancestors
- derive merged group status from every session in the group
- count all request text in the gateway spend ceiling, not only messages
- honor the evidence flush backoff on ingest, clear the pending flag once drained
- withhold paid summary generation and consent mutations from the MCP catalog
…iefing

# Conflicts:
#	.kilo/skills/kilo-mcp/SKILL.md
#	packages/db/src/migrations/meta/0280_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
#	services/kilo-mcp/catalog.json
@iscekic

iscekic commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Native iOS proof from the CI-built dev client against a VM stack. Home shows the briefing card in place of Live Now. Dismissal restores Live Now with no layout shift. The list, detail, settings, per-context AI section, and the morning-briefing notification opt-in were exercised on device.

03-home-briefing

04-detail

06-dismissed-later

07-list

08-settings

09-settings-ai

14-home-footer

iscekic and others added 2 commits October 16, 2026 20:46
…iefing

# Conflicts:
#	.kilo/skills/kilo-mcp/SKILL.md
#	packages/db/src/migrations/meta/0281_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
'[redacted key]'
)
.replace(
/(?:bearer\s+|(?:api[_-]?key|token|password|secret)\s*[:=]\s*)[^\s,;"}]+/gi,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: Compound cloud-secret labels can bypass excerpt redaction

Suggested fix: This pattern only redacts secret when it is immediately followed by : or =. A common value such as AWS_SECRET_ACCESS_KEY=<40-character-value> does not match that branch, and the generic long-value rule does not catch a 40-character value. The raw value can therefore pass through redactBriefingExcerpt and be stored as session evidence, then surfaced in a report or sent in an AI prompt. Recognize compound environment/JSON credential labels and add regression cases for AWS secret access keys and similar formats before persisting excerpts.

return [
{
kind: 'status',
identity: `status:${item.data.transitionId ?? `${occurredAt}:${status}`}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: Fallback status identity can merge distinct transitions

Suggested fix: When transitionId is absent, the identity uses only normalized occurredAt and status; persistence uses the same timestamp/status components for the event ID and ignores conflicts. Two distinct same-status transitions at the same timestamp with different predecessor statuses therefore collapse to one event, potentially losing a blocker onset or other state transition. Include predecessor information or another stable discriminator in the fallback identity, and add a test for same-time, same-status transitions without IDs that have different predecessors.

…iefing

# Conflicts:
#	packages/db/src/migrations/meta/0283_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
#	packages/db/src/schema.ts
@iscekic
iscekic added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit e781956 Oct 19, 2026
95 checks passed
@iscekic
iscekic deleted the igor/agent-morning-briefing branch October 19, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants