Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions docs/CONTEXT_PULSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Context Pulse

Context Pulse is the incremental memory surface of OpenWorkGraph's compact Context MCP.
It complements, rather than replaces, `get_workflow_trace`.

## Purpose

A connected AI often does not need the entire retained workflow history on every turn.
`get_context_pulse` answers two narrower factual questions:

1. What canonical evidence arrived since this caller last checked?
2. Which evidence-backed long-horizon findings are new or materially changed?

The AI remains responsible for interpretation and suggestions. OpenWorkGraph does not
turn a repeated pattern into a recommendation, policy, permission, or productivity score.

## Cursor contract

The first call establishes a baseline and returns `next_cursor`. The caller should pass
that cursor back unchanged on its next check. The cursor is caller-owned and is not a
server-side subscription or timer.

Recent evidence is bookmarked by the monotonic local database arrival ID rather than by
`observed_at`. This means an event that arrives late with an older observation timestamp
is still returned on the next pulse.

If one pulse needs multiple pages, OpenWorkGraph freezes the event watermark and finding
snapshot until both are drained. Events that arrive during paging wait for the next
completed pulse, so they are neither mixed into the current snapshot nor skipped.

The encoded cursor contains no captured titles, names, surfaces, or other observed text.
It contains watermarks plus opaque finding IDs/versions needed to know what has already
been delivered.

## Findings v1

The initial factual finding set is intentionally conservative and uses the factual context
timeline, not inferred task labels:

- **Surface engagement**: engaged/foreground seconds, span count and active-day count for
a surface over the rolling lookback. A change becomes material after another active day
or another 15 minutes of engaged time.
- **Repeated surface transition**: a directional transition between two different work
surfaces observed at least three times within sessions. Each additional occurrence is
material.

Every emitted finding carries evidence event IDs and explicitly reports that it is a
factual aggregate, that task inference was not used, and that it is not advice.

The first call labels findings `baseline`. Later calls emit only `new` or `changed`
findings. If `finding_limit` is smaller than the number of changed findings, unseen
findings are not marked delivered; subsequent calls continue the same frozen snapshot.

## Privacy and disclosure

Context Pulse does not add new capture. It uses evidence OpenWorkGraph already stores.
Typed text and clipboard contents remain uncaptured.

The existing Context disclosure boundary applies to the entire Pulse response:

- **Redacted** remains the default AI representation.
- **Full** is available only when the user selected it and organization policy permits it.
- Organization policy can restrict disclosure.

Canonical local evidence is never rewritten by the Pulse or by AI redaction.

## Pull, not push

Context Pulse is a protocol capability, not an autonomous background sender. An MCP client
calls it when that client chooses to refresh context. Clients that support schedules,
loops, or long-running agent logic can call it periodically; ordinary conversational
clients can call it at session start or whenever fresh workflow context is relevant.

This keeps the core primitive portable across ChatGPT, Claude, Codex, other MCP clients,
and future local or Gateway-based integrations without requiring any one client's
scheduling model.
33 changes: 33 additions & 0 deletions mcp_server/compact_hardening.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,39 @@ def apply_compact_hardening(compact_module: ModuleType) -> None:
return
compact_module._is_readable_step_input = _readable_step_input
compact_module.secure_runtime = _CompactRuntimeProxy(compact_module.secure_runtime)

@compact_module.mcp.tool()
def get_context_pulse(
cursor: str | None = None,
recent_limit: int = 100,
finding_limit: int = 20,
lookback_days: int = 30,
) -> dict[str, Any]:
"""Return what changed since the last check plus changed factual findings.

Pass ``next_cursor`` back unchanged on the next call. The recent section is
canonical evidence that arrived since this caller's bookmark. Findings are
deterministic evidence-backed counts/aggregates over the rolling lookback,
never recommendations or task-label guesses. On the first call they are a
baseline; later calls omit findings that have not materially changed.
"""
name = "get_context_pulse"
compact_module.core._begin(name)
params: dict[str, Any] = {
"recent_limit": min(max(1, int(recent_limit)), 500),
"finding_limit": min(max(0, int(finding_limit)), 50),
"lookback_days": min(max(7, int(lookback_days)), 90),
}
if cursor not in (None, ""):
params["cursor"] = cursor
return compact_module.core._finish(
name,
compact_module.secure_runtime.secure_get("/v1/context-pulse", params),
)

# Keep the function addressable for direct unit tests/debugging in addition to
# registering it with both compact stdio and compact HTTP MCP transports.
compact_module.get_context_pulse = get_context_pulse
compact_module._V0873_HARDENING_APPLIED = True


Expand Down
3 changes: 2 additions & 1 deletion mcpb/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"display_name": "OpenWorkGraph",
"version": "0.91.0",
"description": "Connect Claude Desktop to the compact local OpenWorkGraph context surface.",
"long_description": "Uses the OpenWorkGraph installation already running on this computer. New connections expose canonical workflow evidence first through the compact read-oriented Context MCP surface, while derived task and pattern views remain optional and non-authoritative. The legacy 24-tool stdio entrypoint remains available for existing configurations. Workflow evidence remains in the local OpenWorkGraph store until Claude requests it through MCP. AI access can be turned off instantly from the OpenWorkGraph dashboard.",
"long_description": "Uses the OpenWorkGraph installation already running on this computer. New connections expose canonical workflow evidence first through the compact read-oriented Context MCP surface, while Context Pulse provides incremental factual updates and changed long-horizon findings. Derived task and pattern views remain optional and non-authoritative. The legacy 24-tool stdio entrypoint remains available for existing configurations. Workflow evidence remains in the local OpenWorkGraph store until Claude requests it through MCP. AI access can be turned off instantly from the OpenWorkGraph dashboard.",
"author": {
"name": "Koyar Afrasyab / Kinvectum"
},
Expand All @@ -23,6 +23,7 @@
},
"tools": [
{"name": "get_current_work_context", "description": "Read an optional compact derived overview with pointers to canonical evidence."},
{"name": "get_context_pulse", "description": "Read what changed since the last check plus new or materially changed factual findings; pass the returned cursor back next time."},
{"name": "search_work", "description": "Search prior work through evidence or semantic layers."},
{"name": "get_workflow_trace", "description": "Read the primary canonical paginated workflow evidence, optionally for one session."},
{"name": "get_work_profile", "description": "Read derived workflow signals without productivity scoring."},
Expand Down
Loading
Loading