Associative memory for event streams: link moments by co-presence (what was there), not just similarity (what it resembles).
Project description
copresence
Associative memory for event streams: link moments by co-presence (what was there), not just similarity (what it resembles). A complement to embedding recall, not a replacement.
Zero dependencies. Pure stdlib. pip install copresence
The black t-shirt law
You're trying to remember a conversation from years ago. Searching your memory by content gives you nothing — the conversation doesn't resemble anything you can name. Then a friend says: "you were wearing that black t-shirt… the kettle was on… it was the day the heater broke" — and the whole context rebuilds itself.
The t-shirt never resembled the conversation. It was simply there.
Embedding-based recall (RAG, vector search) is content-similarity: it finds what
resembles the query. It systematically misses everything that was merely
co-present — the peripheral details, the same-day decisions, the parallel
threads. copresence adds that missing axis: it links moments by having shared
a scene, a day, an era, and recalls by spreading activation through those
links.
Quickstart
from copresence import Store, ref, hash_embedder, probe
events = [ # any event stream: chat logs, journals, tickets, commits…
{"timestamp": "2026-01-05T10:00:00+00:00", "speaker": "a", "content": "…"},
# {"timestamp": ISO-8601, "speaker": str, "content": str}
]
store = Store("./layers")
store.link(events) # co-presence links: scene + day + era
store.notice(ref(events[3]), "me", "this mattered") # authored mark
# recall by cascade: seeds spread through co-presence, not similarity
adj = store.graph("me")
context = store.cascade({ref(events[3])}, adj)
Or just run the built-in demonstration:
pip install copresence
copresence demo
which builds a small synthetic corpus where a red kettle whistles near lighthouse work (separate moments, same scenes), shows that similarity recall ranks the target poorly for the kettle cue, and then rebuilds it through the co-presence cascade. Deterministic; runs anywhere; no model download.
Concepts
- Layers are sovereign. Every member (person, agent) gets their own link
files.
links.jsonlis authored — appended, never rebuilt.auto_links.jsonlis derived — rebuilt by the linker on every run. Structural co-presence is shared because it's computable from timestamps alone. - "That day" is a memory node. Co-presence works at three scales: adjacency (the scene), day-hubs, era-hubs (the week). Touching one moment can pull what else the day held.
- Presence weighting. Not every co-occurrence is equal: moments carrying gravity markers or notice-marks weigh their links up; incidental co-occurrence weighs half.
- Decay with resurrection. Unused links fade toward a dormant floor — dormancy, never death. When a cascade touches a dormant link, it re-animates the whole scene around it, not just the node.
- Warming.
warm()scores which dormant moments are heating up under the current context (heat = kinship-to-now × dormancy), with ashould_interruptattention boundary — the caller decides whether to speak. Feed it the record's tail, not a query: continuity anchors in time, not similarity. We learned that from a failed probe and kept the law. - Discovery.
discover_regular()maps the day-to-day roads (themes alive across many days);discover_deep()hunts dormant chains — strong kinship across a long gap, never cross-referenced. These are candidates, not claims: whether a deep pair "hits" is the member's subjective call. - Resonance. Which moments live in one member's layer (private wealth), two, or all? The field is computed; verdicts are not — private wealth is never forced shared.
Embedders
The cascade, linker, notices and layers are pure stdlib. discover, warm and
probe need an embedder — any callable list[str] -> vectors:
from copresence import hash_embedder # zero-dep hashing bag-of-words (a TOY —
# fine for demos/tests, no real semantics)
from copresence import st_embedder # real: pip install copresence[embeddings]
embed = st_embedder() # sentence-transformers MiniLM
Honest notes
- The mechanism is young. In our own (private) corpus of ~520 events, a target that content-recall ranked 265th was rebuilt by a two-hop cascade from six peripheral cues (similarity 0.03–0.18 to the query), and a negative control — the same cues against a different-day target — was correctly not reached. The bundled demo reproduces the same geometry synthetically on your machine; it proves the mechanism, not magic on your data.
- Mood/register link heuristics exist but are experimental and off by default
(
Store(registers=...)) — our own instance is too young to have proven them. - The hashing embedder is a toy. Real corpora deserve a real embedder.
discover_deepcan surface echo-shaped pairs (a summary of a moment vs the moment). The identity cap catches most; your judgment catches the rest.
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file copresence-0.1.0.tar.gz.
File metadata
- Download URL: copresence-0.1.0.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6a68c9869b669a78ac675205fb666eb88bfa7c4f874b175422e7435404ca69a
|
|
| MD5 |
97843964fe2eb17e17ca03172471665b
|
|
| BLAKE2b-256 |
b1651fba57f46685c14a9ecbb6dea2709970f2c1a043f7c669b9deb49804a964
|
File details
Details for the file copresence-0.1.0-py3-none-any.whl.
File metadata
- Download URL: copresence-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3ed6f6db0ca13aedc94fd37182f74259e1b75a1ed4e5bde3adb547b3888fbfe
|
|
| MD5 |
21ffe42b5c3a7e1a45ee3ceaf493094e
|
|
| BLAKE2b-256 |
0557b8b90a12a1a20a8db0be6eb64e0c464b7c3829d10ac6692d716a6722f886
|