feat(home-feed): instrument scheduler + sequence with emitFeedEvent [JARVIS-512]#25593
Merged
Merged
Conversation
…JARVIS-512]
First batch of background-job instrumentation for the home activity
log. Wires emitFeedEvent into the safe, bounded completion points
where a real user-visible signal lands:
scheduler.ts — 4 emit points:
- notify-mode one-shot success (dedupKey: oneshot:<jobId>)
- notify-mode recurring success (dedupKey: schedule-run:<runId>)
- execute-mode task success (dedupKey: schedule-run:<runId>)
- execute-mode message success (dedupKey: schedule-run:<runId>)
Execute-mode emits are gated on !job.quiet to match the existing
notifySchedule behavior; notify-mode emits always fire since
notify-mode IS a notification by design.
sequence/engine.ts — emit after recordSend on each successful step
(dedupKey: sequence-step:<enrollmentId>:<stepIndex>). Skipped for
requireApproval draft steps — those pause without sending, so
there's no real signal yet.
All emits use source="assistant", are fire-and-forget via .catch so
a writer hiccup can never interrupt the 15s scheduler tick, and key
on the schedule-run / enrollment-step identifier so each run is a
distinct activity-log entry (the writer's per-source cap bounds
total volume).
Deferred to follow-up:
- Gmail watcher event processing (loop-risk if the LLM-processing
path re-triggers work)
- task-runner direct (manual non-schedule task runs) — needs a
dedup story with the scheduler layer to avoid double-emits
- skill runner completion — no single well-defined hook to latch
onto yet
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tasks
5 tasks
Jasonnnz
pushed a commit
that referenced
this pull request
Apr 15, 2026
…JARVIS-512] (#25593) First batch of background-job instrumentation for the home activity log. Wires emitFeedEvent into the safe, bounded completion points where a real user-visible signal lands: scheduler.ts — 4 emit points: - notify-mode one-shot success (dedupKey: oneshot:<jobId>) - notify-mode recurring success (dedupKey: schedule-run:<runId>) - execute-mode task success (dedupKey: schedule-run:<runId>) - execute-mode message success (dedupKey: schedule-run:<runId>) Execute-mode emits are gated on !job.quiet to match the existing notifySchedule behavior; notify-mode emits always fire since notify-mode IS a notification by design. sequence/engine.ts — emit after recordSend on each successful step (dedupKey: sequence-step:<enrollmentId>:<stepIndex>). Skipped for requireApproval draft steps — those pause without sending, so there's no real signal yet. All emits use source="assistant", are fire-and-forget via .catch so a writer hiccup can never interrupt the 15s scheduler tick, and key on the schedule-run / enrollment-step identifier so each run is a distinct activity-log entry (the writer's per-source cap bounds total volume). Deferred to follow-up: - Gmail watcher event processing (loop-risk if the LLM-processing path re-triggers work) - task-runner direct (manual non-schedule task runs) — needs a dedup story with the scheduler layer to avoid double-emits - skill runner completion — no single well-defined hook to latch onto yet Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Third step of JARVIS-512, stacked on #25584 and #25586 (both merged). Wires
emitFeedEventinto the first batch of background-job completion points so real assistant activity starts showing up in the home feed's activity log.What lands
scheduler.ts— 4 emit pointsnotifyScheduleOneShot+completeOneShotschedule-notify-oneshot:<jobId>completeScheduleRun(ok)schedule-run:<runId>completeScheduleRun(ok)in therun_task:branch (gated on!job.quiet)schedule-run:<runId>completeScheduleRun(ok)in the plain-message branch (gated on!job.quiet)schedule-run:<runId>Execute-mode emits mirror the existing
notifySchedulegating on!job.quiet— users who opted out of push notifications also opt out of activity log entries. Notify-mode emits always fire because notify-mode IS notification by design.A small
emitScheduleFeedEventhelper at the bottom of the file wrapsemitFeedEventwith fire-and-forget.catchhandling so a schema error or writer hiccup can never interrupt the 15s scheduler tick.sequence/engine.ts— 1 emit pointAfter
recordSendinprocessEnrollment, keyed onsequence-step:<enrollmentId>:<stepIndex>. Placed after thestep.requireApprovalgate so draft-only steps (which pause without sending) don't show up in the log — only actual sends produce a real signal.Loop / runaway-cost audit (per the concern raised in-thread)
home_feed_updatedwas found in the audit (only the macOS client consumes it). Emits can't trigger more background work.MAX_ACTIONS_PER_SOURCE = 20, from feat(home-feed): action append semantics + per-source cap [JARVIS-512] #25584) keeps totalsource: "assistant"actions at ≤20 most-recent. Older emits fall off deterministically.Deferred to follow-ups (with specific reasons)
watcher/engine.ts:222) — loop-risk: the LLM event-processing path could itself re-trigger watcher polling if we're not careful. Needs its own audit.task-runner.ts:102) — needs a dedup story with the scheduler layer so schedule-triggered tasks don't double-emit (scheduler AND task-runner both firing).Testing
bun run typecheck— cleanbun run lint— cleanbun test src/home/— 144/144 pass (regression check; no new tests in this PR — see below)No new unit tests in this PR. The scheduler and sequence modules don't have existing test harnesses (no
src/schedule/__tests__, nosrc/sequence/__tests__) — standing one up just for these pass-through emits is significant scope creep. TheemitFeedEventhelper itself has thorough unit coverage in #25586. Manual smoke after merge will verify end-to-end wiring.🤖 Generated with Claude Code