> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gildea.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Update context

> Pull only what's changed into your context store.

**Update** your context layer incrementally as signals land and change. Rebuilding the store from scratch is wasteful, and re-reading by hand misses things. A **cursor** remembers exactly where you left off, so each refresh pulls only what's changed into your store, in order, with nothing missed or double-counted.

## The recipe

`sort=changed` is a change feed: signals ordered by when they last changed. You page it with a cursor, and the cursor is a bookmark you keep between runs. Poll hourly, daily, or after a week away, and you always pick up exactly where you left off.

<Steps>
  <Step title="Resume from your cursor">
    Pass your saved `cursor` to `signals.list(sort="changed")`. It returns everything that changed since that point. The first run has no cursor, so it does a full initial sync; every run after is just the delta.
  </Step>

  <Step title="Upsert by signal id">
    Replace each changed signal in your store by its `signal_id`: newest wins, wholesale. A signal's entities can change over time as they're merged or renamed, so you replace the whole record; merging would leave stale parts behind.
  </Step>

  <Step title="Save the cursor for next time">
    Persist the updated store and the new cursor. Poll on any cadence (hourly, daily, after a week away) and your territory stays current, so [Search](/guides/search) and the rest of your loop always read fresh, verified data.
  </Step>
</Steps>

Install `gildea`, set `GILDEA_API_KEY`, then (pure SDK, no model calls):

```python theme={null}
import json
import pathlib
from gildea import Gildea

gildea = Gildea()
CURSOR = pathlib.Path("update_cursor.txt")    # remembers exactly where the last sync ended
STORE = pathlib.Path("signals.jsonl")         # your local copy of the signals you track

# 1. Resume from your saved cursor (none on the first run -> a full initial sync).
cursor = None
if CURSOR.exists():
    cursor = CURSOR.read_text().strip() or None

# 2. Page the change feed: everything changed since last sync, in document order.
#    The first run has no cursor, so it backfills; we cap the initial pull to keep the demo
#    quick (raise MAX_PAGES, or drop the cap, to backfill the full history). Steady-state runs
#    resume from the saved cursor and only pull the small delta. Pull the whole feed (not
#    filtered by entity) so you also catch signals that *lost* an entity (merge/rename); route
#    to your tracked scope client-side from each signal's entities.
changed, MAX_PAGES = [], 5
for _ in range(MAX_PAGES):
    page = gildea.signals.list(sort="changed", cursor=cursor, limit=50)
    changed.extend(page["signals"])
    cursor = page.get("next_cursor") or cursor        # advance; keep old if nothing newer
    if not page["has_more"]:
        break

# 3. Upsert by signal_id: newest version wins, replace the whole record (don't merge: a
#    signal's entities can change (merge/rename), so stale parts must drop out).
store = {}
if STORE.exists():
    store = {s["signal_id"]: s for s in map(json.loads, STORE.read_text().splitlines()) }
for s in changed:
    store[s["signal_id"]] = s

# 4. Persist the store and the cursor for next time.
STORE.write_text("\n".join(json.dumps(s) for s in store.values()))
CURSOR.write_text(cursor or "")

print(f"{len(changed)} signals changed this sync; {len(store)} tracked total")
```

## What you get

A self-healing watch on your scope: poll on any cadence (hourly, daily, after a week off) and you always get exactly what changed since last time, with nothing missed or repeated. The cursor makes it incremental; the upsert keeps every record current. It writes to the same `signals.jsonl` your other recipes read, so your context layer stays current without a full rebuild.

<CardGroup cols={2}>
  <Card title="Search for signals" icon="magnifying-glass" href="/guides/search" />

  <Card title="Embed signals" icon="layer-group" href="/guides/embed" />
</CardGroup>
