feat(home-feed): action append semantics + per-source cap [JARVIS-512]#25584
Conversation
Drop the 24h auto-fade default on action items — they're the feed's activity log and must persist until the user dismisses them. Callers that want expiry now set expiresAt explicitly. Exempt action items from (type, source) collapse in mergeIncoming so multiple background-job events for the same source don't overwrite each other. Bound per-source action volume via MAX_ACTIONS_PER_SOURCE (20) in a new pruneActionsPerSource pass — keeps the log file from ballooning as producers get instrumented. Digest/thread/nudge merge semantics are untouched. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| // until the user dismisses them. The writer used to fill in a | ||
| // 24h default expiresAt; that behavior is intentionally gone. |
There was a problem hiding this comment.
🔴 Test comment narrates removed code history, violating AGENTS.md comment rule
The comment at lines 279-280 says "The writer used to fill in a 24h default expiresAt; that behavior is intentionally gone." This violates the mandatory rule in assistant/AGENTS.md:21: "do not reference code that has been removed. Comments should describe the current state of the codebase, not narrate its history. Avoid phrases like 'no longer does X', 'previously used Y', or 'was removed in PR Z'." The phrases "used to fill in" and "intentionally gone" directly narrate the codebase's history rather than describing its current state.
| // until the user dismisses them. The writer used to fill in a | |
| // 24h default expiresAt; that behavior is intentionally gone. | |
| // Action items are the feed's activity log — they persist | |
| // until the user dismisses them or the per-source cap prunes them. |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d44177a0d5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (item.type !== "action") return true; | ||
| if (!item.source) return true; | ||
| if (!overflowing.includes(item.source)) return true; | ||
| return keepIds.has(item.id); |
There was a problem hiding this comment.
Retain capped actions by unique entry, not shared id
The cap logic keeps overflowed actions via keepIds and later checks keepIds.has(item.id), which means retention is keyed only by id. If a source emits duplicate action IDs (or two overflowing sources reuse the same ID), an older action can be incorrectly preserved because a newer action with the same ID marked it as kept, so that source can stay above MAX_ACTIONS_PER_SOURCE and stale rows remain visible. Track retained rows by a per-entry key (e.g., source + createdAt + id, or item identity/index) instead of id alone.
Useful? React with 👍 / 👎.
Summary
First step of JARVIS-512 (follow-up to JARVIS-511). Reshapes the home-feed writer so
actionitems behave like an activity log instead of a one-slot-per-source overwrite:.actedOnpath already wired end-to-end). Callers that want expiry setexpiresAtexplicitly.mergeIncomingshort-circuits before the(type, source)collapse so multiple background-job events for the same source don't overwrite each other. Digest/thread/nudge merge semantics are untouched.MAX_ACTIONS_PER_SOURCE = 20+pruneActionsPerSourcepass. Keeps the log file from ballooning once producers get instrumented. Sourceless actions are unbounded.The wrapper helper (
emit-feed-event.ts) and the background-job instrumentation that depends on these semantics ship in follow-up PRs.Test plan
bun test src/home/— 137/137 passbun run typecheck— cleanbun run lint— clean🤖 Generated with Claude Code