Summary
The heartbeat system needs a stronger generic model for tracking live subjects versus historical memory.
Right now, resolved or superseded things can keep resurfacing in heartbeat, internal/process-state chatter can leak into user-facing output, and downstream delivery may not have enough structure to consistently decide what should be surfaced.
This is a general memory/heartbeat architecture issue, not specific to GitHub.
Problem
The current system appears to mix three different concepts too loosely:
-
Live tracked subjects
- work that is currently active and may need attention
- examples: a task, a deployment blocker, a PR, an unresolved contradiction, a follow-up item
-
Historical memory
- useful background context
- examples: a past resolution, an old discussion, a completed task, a previous blocker
-
Internal process state
- monitoring / syncing / cleanup / planning / standby work done by the system itself
When these categories are not separated clearly, heartbeat can fail in predictable ways:
- resolved items resurface as if still active
- superseded items still influence user-facing heartbeat output
- internal monitoring chatter leaks into the same user-facing stream as meaningful alerts
- generic retrieval across active/stale/resolved memory confuses historical context with current work
- downstream consumers try to compensate with ad hoc suppression, reducing reliability
Desired behavior
Heartbeat should be driven by a clear model of tracked subjects with current state, while still using memory for context.
Live subject state should answer:
- what is currently active?
- what changed?
- is this resolved / superseded?
- was the user already informed?
- does it still deserve interruption?
Historical memory should answer:
- what relevant past context helps explain this?
- what prior outcomes / decisions are related?
Internal process state should usually remain internal:
- monitoring
- syncing
- cleanup
- standby
- planning preparation
Root cause hypothesis
Heartbeat candidate generation is relying too much on memory/event relevance and too little on a live invalidation-aware subject model.
That produces both:
- stale resurfacing
- and downstream over-filtering / inconsistent delivery
Proposed direction
1. Introduce a generic tracked-subject model
A subject can represent any ongoing or actionable thing, for example:
- plan / task
- deployment blocker
- contradiction / conflict
- follow-up item
- GitHub issue / PR (as one producer among many)
- calendar item / external thread / other integrations
Each subject should have at least:
- stable subject key
- subject type
- current state
- active / resolved / superseded status
- last meaningful change timestamp
- last surfaced / informed timestamp
- optional owner/source metadata
2. Add explicit invalidation / supersession rules
A subject should stop surfacing as active when it is:
- resolved
- superseded by a newer state
- invalidated by fresh evidence
- explicitly archived
Historical memory can remain available, but it should not continue to act like live work.
3. Separate live state from historical retrieval
Use:
- live subject state for whether to surface
- historical memory for why it matters / supporting context
Do not use generic resolved/stale memory retrieval as the main driver for active heartbeat output.
4. Normalize heartbeat payloads
Every user-facing heartbeat should identify:
- the subject
- what changed
- why now
- mode / urgency
- a recommended user-facing summary
Avoid vague payloads that only provide bucketed signal counts without a concrete delta.
5. Record suppression / handling state for dedup
If a heartbeat candidate is evaluated and intentionally suppressed, that decision should still leave enough state behind to avoid repeated resurfacing of the same candidate.
6. Make downstream delivery obey the heartbeat contract
If heartbeat emits a surfaceable result, downstream consumers should not silently replace that with broad anti-noise heuristics. Noise reduction should happen upstream through better candidate generation and subject invalidation.
Non-goals
- This issue is not GitHub-specific
- This issue is not only about prompt wording
- This issue is not asking to delete resolved memories from history
- This issue is not replacing memory search / retrieval in general
Likely implementation areas
- heartbeat candidate generation and evaluation
- resolved / superseded / active state modeling
- state invalidation rules
- dedup and suppression recording
- heartbeat payload schema / response contract
- historical-context enrichment rules
Acceptance criteria
- resolved / superseded subjects no longer resurface as active heartbeat work
- historical memory remains available for context but does not drive false active alerts
- internal process-state chatter does not leak into user-facing heartbeat by default
- each surfaced heartbeat identifies a concrete subject and meaningful change
- suppressed candidates do not reappear repeatedly due only to missing recorded state
- downstream consumers can rely on heartbeat mode / surfaceability without needing ad hoc reinterpretation
Follow-up
Integration-specific producers (GitHub, deployment monitors, task systems, etc.) can then map their events into this generic tracked-subject model instead of inventing ad hoc reminder behavior per connector.
Summary
The heartbeat system needs a stronger generic model for tracking live subjects versus historical memory.
Right now, resolved or superseded things can keep resurfacing in heartbeat, internal/process-state chatter can leak into user-facing output, and downstream delivery may not have enough structure to consistently decide what should be surfaced.
This is a general memory/heartbeat architecture issue, not specific to GitHub.
Problem
The current system appears to mix three different concepts too loosely:
Live tracked subjects
Historical memory
Internal process state
When these categories are not separated clearly, heartbeat can fail in predictable ways:
Desired behavior
Heartbeat should be driven by a clear model of tracked subjects with current state, while still using memory for context.
Live subject state should answer:
Historical memory should answer:
Internal process state should usually remain internal:
Root cause hypothesis
Heartbeat candidate generation is relying too much on memory/event relevance and too little on a live invalidation-aware subject model.
That produces both:
Proposed direction
1. Introduce a generic tracked-subject model
A subject can represent any ongoing or actionable thing, for example:
Each subject should have at least:
2. Add explicit invalidation / supersession rules
A subject should stop surfacing as active when it is:
Historical memory can remain available, but it should not continue to act like live work.
3. Separate live state from historical retrieval
Use:
Do not use generic resolved/stale memory retrieval as the main driver for active heartbeat output.
4. Normalize heartbeat payloads
Every user-facing heartbeat should identify:
Avoid vague payloads that only provide bucketed signal counts without a concrete delta.
5. Record suppression / handling state for dedup
If a heartbeat candidate is evaluated and intentionally suppressed, that decision should still leave enough state behind to avoid repeated resurfacing of the same candidate.
6. Make downstream delivery obey the heartbeat contract
If heartbeat emits a surfaceable result, downstream consumers should not silently replace that with broad anti-noise heuristics. Noise reduction should happen upstream through better candidate generation and subject invalidation.
Non-goals
Likely implementation areas
Acceptance criteria
Follow-up
Integration-specific producers (GitHub, deployment monitors, task systems, etc.) can then map their events into this generic tracked-subject model instead of inventing ad hoc reminder behavior per connector.