CodeMind — gives your repo a memory that catches contradictions on PRs
Project description
CodeMind — The Repo That Remembers
Your repo has opinions. Watch it catch a teammate breaking one — live.
CodeMind is a persistent memory graph for a codebase that doesn't just store facts about why the code is the way it is — it watches new commits, detects when they contradict an established decision, and forces a reconciliation moment: confirm the change is intentional (memory revises itself) or catch a regression before it ships.
This isn't a linter. It's memory that can be wrong, get challenged, and correct itself — the way a real teammate's understanding would.
Built on Cognee Cloud for the wemaekdev hackathon.
The problem
Every team loses tribal knowledge constantly. A new hire "cleans up" code that looks redundant. It wasn't redundant. It ships. It breaks in prod. Static tools (linters, code-review bots, RAG-over-docs) only see the code as it is right now — they have no memory of why it got that way, and no mechanism to notice when someone unknowingly undoes a hard-won decision. Existing "repo assistant" tools read a repo once and summarize a snapshot. CodeMind's bet: the valuable thing isn't remembering the code, it's remembering the decisions — and noticing when new code violates them.
How the Cognee lifecycle maps to CodeMind
| Cognee primitive | What it does in CodeMind | Where it fires |
|---|---|---|
remember() |
Extracts a structured "decision fact" from a commit (what / why / scope / confidence) and stores it in the shared graph | ingest.py |
recall() |
Retrieves relevant past decisions when a new diff touches related code | contradiction.py (hybrid retrieval) |
improve() |
Re-weights the graph after a human confirms a contradiction is an intentional update — the old belief is revised, not just appended | reconcile.py confirm |
forget() |
Surgically retires the single superseded memory by data_id (not the whole dataset) — the old belief is visibly crossed out |
reconcile.py confirm |
Why Cloud specifically: if the memory graph lived on one laptop it wouldn't be team memory — it'd be personal notes. The graph has to be shared and consistent across every contributor and every CI run for it to reflect team-wide, ongoing consensus. That requires Cognee Cloud, not a self-hosted single instance.
🧠 Cognee operations callout (for "Best Use of Cognee" judges)
All four lifecycle verbs are used meaningfully and live, plus the deeper
cognee.search graph-node retrieval, and the GitHub commit-status + issue
integrations:
cognee.serve(url, api_key)— routes every op to the shared Cloud tenant (config.py); tenant/user headers patched into the session (cognee_client._inject_headers).cognee.remember(text, dataset_name, importance_weight, self_improvement=True)— each extracted decision is stored with an importance score;self_improvementauto-runsimprove(cognee_client.remember_decision, called fromingest.pyandreconcile.py). The new item'sdata_idis isolated by diffing the items list before/after (the list isn't in insertion order).cognee.recall(query_text, datasets, top_k, auto_route)— semantic retrieval over the graph (cognee_client.recall_decisions).cognee.search(query_text, datasets, only_context=True, feedback_influence=…, neighborhood_depth=…, include_references=True)— pulls the actual graph nodes (Decision + Rationale + keyword tags), deeper thanrecall's LLM answer. Used incontradiction.pyto cite the specific node a diff contradicts, and in the dashboard to render the live graph (cognee_client.search_graph_nodes).feedback_influenceis wired so the reconcileconfirm/rejectsignal can shape future retrieval.cognee.forget(data_id, dataset)— surgical single-memory deletion bydata_id(confirmed working on cloud). This is what makes "old belief crossed out" honest rather than faked (cognee_client.forget_one/forget_many).cognee.improve(dataset_name)— explicit re-weight after an update (cognee_client.improve_graph, best-effort — see note below). Auto-runs viaremember(self_improvement=True).
Honest caveat:
cognee.memify()andcognee.visualize()are blocked on this cloud tenant —memify404s (Empty graph projected) + 422 (LLM API key not set), andvisualize/datasets.list_datasetscrash on a broken local-SQLite path in cloud mode. Soimprovestays best-effort and the dashboard renders the live graph fromcognee.search(only_context=True)nodes instead ofvisualize(). The feedback-re-weight loop (cognee.add_feedback→memifyapplies the weights) is likewise blocked on cloud:add_feedbackisn't exposed on the cloud client and the local session manager no-ops (returnsFalse) in cloud mode;recallsurfaces no qa/session ids to feedback on. The "memory learns from human feedback" thesis is instead embodied by the confirm/reject loop —confirmrevises the belief (rememberUPDATE + surgicalforget+improve),rejectholds it. Every Cognee API the tenant does support is leaned on; the ones it blocks are documented rather than faked.
Integrations (the rules: "and integrations")
- GitHub PR comments — the conflict posts as a real comment citing the violated decision + Cognee graph evidence (
github.post_or_print). - GitHub commit-status check — green on clean PRs, red on conflict (lights up the PR check summary);
reconcile confirmflips red → green,rejectkeeps it red (github.post_commit_status). Usable as a required status check so a contradictory PR can't merge. - GitHub issue on reject —
reconcile rejectauto-opens an issue tracking the caught regression, labeledcodemind+regression(github.create_issue). - CI on every PR — two GitHub Actions workflows (
.github/workflows/) run detection + the comment-triggered reconcile loop (see "CI — runs on every PR" below). - Auto-ingest on merge — a third workflow (
codemind-ingest.yml, opt-in viavars.CODEMIND_AUTO_INGEST=true) runsingest.py --since $before --head $afteron every push tomain, so the graph grows itself with the team's merged history — "no action needed, just learning."
🌐 Cross-repo shared memory (the Cloud-native differentiator)
The Cognee Cloud graph is tenant-global: a decision remembered in repo A is retrievable from repo B's CI run. That's not a caveat here — it's the headline. It's the whole reason Cloud (not self-hosted) matters: one memory graph across your whole org's repos. A hard-won decision made in the payments repo protects a PR in the checkout repo. No local/self-hosted memory can do this.
Already proven live: PR #6 ran with local signals: 0 (no committed
memory_registry.json on that branch) and the shared Cloud graph still surfaced
12 graph nodes + the correct verdict via cognee.search(only_context=True) —
i.e. the run's only memory was the graph populated by other repos' ingests. The
dashboard pulls 16 live nodes from the same shared graph.
Proven locally too (read-only): with the local registry blanked (simulating
repo B's no-registry state), python -m codemind.runtime.contradiction --repo demo_repo --branch violation --no-post
still returns conflict: True citing "Cache layer must be Redis" — local signals: 0,
semantic recall: 1, graph nodes: 11, all from the shared Cloud graph. The catch
comes entirely from memory another repo populated.
Full two-repo theatrical demo (a second repo wired to the same tenant catches a Redis→Map PR citing a decision remembered in repo A):
gh repo create <you>/codemind-cross-b --private # you create repo B (one step)
bash scripts/setup_cross_repo.sh <you>/codemind-cross-b # pushes code, sets secrets, opens the violation PR
The script gives repo B NO memory_registry.json, so its only memory is the shared
Cloud graph. Within ~2 min the CodeMind bot comments on repo B's PR citing
"Cache layer must be Redis" — a decision remembered in repo A — and a red
CodeMind / memory check appears. That's org-wide shared memory, live.
The reconciliation moment — remember the update → forget the old belief → improve
re-weights → re-recall/search shows the changed answer — is the entire thesis, and it runs live.
Why this is different
Repo Guardian / CodeBase Navigator / Beetle AI / Congming / CodeSage all read a repo once and summarize/analyze it (a snapshot). CodeMind is the only entry making a claim about belief over time — the memory can be wrong, get corrected, and visibly change its mind. The contradiction moment is the demo, not "codebase assistant."
Architecture
demo_repo (git) ──▶ ingest.py ──▶ cognee.remember() ──▶ Cognee Cloud graph
(LLM extracts (dataset: codemind_repo_memory)
decision facts) │
│ recall()
▼
new diff ──▶ contradiction.py ──▶ hybrid retrieval ──▶ LLM judge ──▶ conflict
(semantic recall + (Ollama Cloud) │
path-scope + keyword ▼
overlap unioned) github.post_or_print
│
┌──────┴───────┐
▼ ▼
confirm (intentional) reject (bug)
remember UPDATE no memory change
forget old (data_id) ← caught a real mistake
improve()
│
▼
re-call() → answer CHANGED (the proof)
Local state: memory_registry.json maps each decision to its Cognee data_id so
forget can target a single memory. event_log.json is the append-only "belief changed"
timeline (feeds the dashboard).
Files
config.py— env, constants, Cognee connection helpercognee_client.py— async wrapper over the Cognee SDK (capturesdata_idat remember-time)llm.py— local LLM (Ollama, OpenAI-compatible) calls:extract_decision()+judge_contradiction()(JSON-structured)git_io.py— read commits/diffs/branch-diffs via the git CLIregistry.py— local registry + event log + hybrid-retrieval helpersingest.py— Phase 1: walk history → extract → remember → registrycontradiction.py— Phase 2: 3-signal retrieval → judge → surface conflictreconcile.py— Phase 3:confirm(remember+forget+improve) /reject(no change)github.py— optional real PR comment ifGH_TOKENset, else terminal+filespike.py— Phase 0 de-risk: confirms surgicalforgetworks before building on itscripts/seed_demo_repo.sh— builds demo_repo with 4 seeded decisions + violation/benign branchesscripts/setup.sh— one-time pre-demo prep (seed + ingest + recall check)scripts/run_demo.sh— the scripted 2-minute walkthroughcodemind dashboard— STRETCH: renders the memory graph + belief-changed timeline to HTML; pulls live Cognee graph nodes viacognee.search(only_context=True)and shows the Cognee lifecycle-API footprintcodemind doctor --cognee— live spike of the deeper Cognee APIs (search,visualize,memify,datasets) against the cloud tenant; documents which work vs. are blocked
Setup
Primary path
pip install codemind-ci # from PyPI
codemind init
For local development from this checkout:
python3.13 -m venv .venv && .venv/bin/pip install -e .
codemind init
codemind init detects the git repo, validates the Cognee + Ollama credentials, writes .env, copies the GitHub Actions workflows, sets GitHub secrets when gh is available, stores a retention policy, and runs the first bounded ingest.
Manual / advanced setup
cp .env.example .env
# Cognee Cloud: COGNEE_URL (tenant API Base URL), COGNEE_API_KEY (X-Api-Key),
# COGNEE_TENANT_ID (X-Tenant-Id), COGNEE_USER_ID (X-User-Id)
# Ollama Cloud: OLLAMA_API_KEY (https://ollama.com/settings/keys), OLLAMA_MODEL
# (optional: GH_TOKEN, GH_REPO, GH_PR_NUMBER for real PR comments)
Phase 0 spike
.venv/bin/python -m codemind.runtime.spike
# expect: remembered 2 -> forgot 1 -> 1 remains. Confirms surgical forget() works.
Prep the demo
bash scripts/setup.sh
# rebuilds demo_repo, ingests 4 decisions into Cognee, confirms the 'before' recall
# returns the clean answer ("no, must use Redis"). Re-runnable.
The demo (2 minutes)
bash scripts/run_demo.sh # press ENTER to advance each beat
| Time | Beat |
|---|---|
| 0:00–0:20 | The problem: teams lose why-code-is-the-way-it-is. CodeMind gives the repo a memory that argues back. |
| 0:20–0:40 | Show the seeded graph; recall("can I use an in-memory Map cache instead of Redis?") → the old answer ("no, must use Redis — Mar 2 stale-config incident"). Remember it. |
| 0:40–1:10 | Live commit: a teammate replaces Redis with a per-process in-memory Map. contradiction.py fires and posts the conflict citing the cache decision. |
| 1:10–1:30 | reconcile confirm → remember the UPDATE, forget the old belief (surgical, by data_id), improve re-weights. Old belief visibly crossed out. |
| 1:30–1:50 | recall("can I use an in-memory Map cache instead of Redis?") again → the answer has changed ("yes, superseded as of the update"). The before/after flip is the loop closing. |
| 1:50–2:00 | Close: memory that can be wrong, get challenged, and correct itself. |
Manual control (for testing)
.venv/bin/python -m codemind.runtime.contradiction --repo demo_repo --branch violation # should flag the Redis decision
.venv/bin/python -m codemind.runtime.contradiction --repo demo_repo --branch benign # should stay quiet (same-file refactor)
.venv/bin/python -m codemind.runtime.reconcile confirm --reason "intentional, rationale updated"
.venv/bin/python -m codemind.runtime.reconcile reject
.venv/bin/codemind dashboard && open dashboard/index.html # stretch visual
Verification (end-to-end)
python -m codemind.runtime.spike→ remember 2, forget 1, 1 remains. (Phase 0 gate — surgical forget works.)bash scripts/setup.sh→ rebuilds demo_repo, ingests 4 decisions; the pre-demo recall returns the clean before answer ("no, must use Redis"). Re-runnable:--resetsurgically forgets every registrydata_id(including any prior UPDATE) so the graph is clean each run.python -m codemind.runtime.contradiction --branch violation→ conflict citing the Redis decision;--branch benign(a same-fileDEFAULT_TTLrefactor) → no conflict. Both must hold.python -m codemind.runtime.reconcile confirm→event_log.jsongains remember+forget+improve; the contrastive recall now returns the updated belief ("yes, superseded"), different from step 2. (Proof the loop closed.)python -m codemind.runtime.reconcile reject→ registry unchanged; recall answer unchanged. (Bug-caught branch verified.)bash scripts/run_demo.sh→ full walkthrough runs clean.- CI (every PR): push the repo (with committed
memory_registry.json+.github/workflows/) to GitHub, add the Cognee/Ollama secrets, open a PR with the Redis→Map change →github-actions[bot]posts the CodeMind conflict comment citing the cache decision; push another commit → no duplicate (idempotency); reply/codemind confirm intentional, single-instance deploy→ after-recall comment shows the answer flipped ("superseded as of the update"); open a second PR with a different change → a fresh comment on that PR's number (proves it works on all PRs). - Green/red check: a clean PR →
CodeMind / memory→success("No contradiction with past decisions"); a conflicting PR →failure. Both verified live (PRs #4 red, #6 green on this repo). - Auto-ingest (dry-run):
python -m codemind.runtime.ingest --repo . --since <sha> --head <sha> --dry-run→ extracts decisions from the range and prints them, without callingremember(). Verified locally. The livecodemind-ingest.ymlruns the same in--since/--headmode on push to main (opt-in viavars.CODEMIND_AUTO_INGEST=true). - Cross-repo shared memory:
bash scripts/setup_cross_repo.sh <you>/codemind-cross-b→ repo B (no local registry) catches a Redis→Map PR citing a decision remembered in repo A, via the shared Cloud graph. Mechanism already proven live: PR #6 ran withlocal signals: 0and the shared graph surfaced 12 nodes + the correct verdict. - Unit tests:
.venv/bin/python -m unittest discover -s tests→ 11 tests covering the registry fuzzy-match (reconcile's data_id lookup), the hybrid-retrieval keyword/path signals, and the GitHub comment idempotency marker + graph-evidence formatting. (The fuzzy-match test caught a real punctuation bug —Redis;wasn't matchingredis— now fixed.)
CI demo (the live loop, ~90s — for the recording)
The terminal demo above is the thesis; this is the product running in real CI. Live artifacts on this repo to show on camera:
- PR #4 (https://github.com/kajal-jotwani/Hangover/pull/4) — a teammate's Redis→Map PR. Show the bot comment with the Graph evidence block (cites the actual Cognee node "Cache layer must be Redis") and the red
CodeMind / memorycheck in the PR summary. - PR #6 (https://github.com/kajal-jotwani/Hangover/pull/6) — a clean PR. Show the green
CodeMind / memorycheck ("No contradiction with past decisions"). Same check, green vs red. - Dashboard —
codemind dashboard→ the live Cognee memory graph (16 nodes), the lifecycle-footprint badges, the belief-changed timeline. A static snapshot is pushed to thegh-pagesbranch; enable GitHub Pages (Settings → Pages → Source:gh-pages) to get a live linkable dashboard athttps://<owner>.github.io/<repo>/. - Cross-repo (optional closer):
bash scripts/setup_cross_repo.sh <you>/codemind-cross-b→ repo B catches the same mistake using a decision remembered in repo A — org-wide memory. - Reconcile (optional): reply
/codemind confirm intentional, single-instance deployon PR #4 → the check flips red→green + an after-recall comment shows the answer changed. (Mutates the demo graph — runbash scripts/setup.shafter to reset.)
Why this scores on the rubric ("Best Use of Cognee")
The rubric: "must use Cognee for memory; the more deeply you lean on its lifecycle APIs (remember, recall, improve/memify, forget) and integrations, the stronger you score." CodeMind's alignment, honestly:
- All four lifecycle verbs, live:
remember(ingest + auto-ingest on merge + reconcile's UPDATE),recall(hybrid retrieval in every CI run),forget(surgical bydata_idon confirm — verified working on cloud),improve(best-effort on cloud; auto-runs viaself_improvement=True). - Deeper than the verbs:
cognee.search(only_context=True)pulls the actual graph nodes, cited as Graph evidence in PR comments and rendered in the dashboard — the deepest retrieval the tenant supports. - Integrations (4): PR comments, commit-status check (green/red, blocks merge when required), auto-issue on reject, and CI on every PR via two Actions workflows (+ auto-ingest on merge).
- Cloud-native, not Cloud-optional: cross-repo shared memory across the whole org — the one thing self-hosted memory structurally cannot do. The graph is tenant-global by design; CodeMind turns that into the product.
- Honest where the tenant is limited:
memify/visualize/datasets.*/add_feedbackare blocked on this cloud tenant — documented with the exact errors, not faked. The dashboard renders the graph fromsearch(only_context=True)nodes; the "learns from feedback" thesis is carried by the confirm/reject loop.
Tech stack
- Memory: Cognee Cloud (shared graph across contributors/CI — the whole point)
- LLM (extraction + judgment): Ollama Cloud via its OpenAI-compatible endpoint (
https://ollama.com/v1, Bearer key; e.g.gpt-oss:120b). Cognee Cloud runs its own LLM for graph ingestion server-side, so the two are independent. - Ingestion: Python + git CLI reading
git log -pand branch diffs - Integration: GitHub PR comments via GitHub API (env-gated; terminal fallback by default)
- Dashboard: static HTML generated from local state (stretch)
Cut list (if behind, in order)
dashboard → real GitHub PR comments (fall back to terminal) → second demo scenario → anything beyond the one scripted contradiction. Never cut the reconciliation loop — it's the thesis.
CI — runs on every PR (GitHub Actions)
The terminal demo is one thing; the real product runs in CI on every pull request,
not a hardcoded PR number. Two workflows live in .github/workflows/:
codemind-pr.yml— triggers onpull_request(opened / synchronize / reopened). Checks out the PR head, recalls relevant past decisions from the Cognee Cloud graph, judges whether the diff contradicts any of them, and posts a real PR comment when it does. Idempotent per head SHA (pushing another commit to the same PR does not spam a duplicate).codemind-reconcile.yml— triggers on anissue_commentstarting with/codemind. Re-derives the conflict from the PR diff (no duplicate comment), runs the reconcile loop, and posts the after-recall result as a new PR comment — the loop-closing beat, automated.
PR opened ── codemind-pr.yml ──▶ contradiction.py ──▶ PR comment (⚠️ conflict) ──▶ author/maintainer replies
│
/codemind confirm <reason> OR /codemind reject
▼
codemind-reconcile.yml ──▶ reconcile.py confirm|reject --ci ──▶ PR comment (✅/⛔ after-recall)
Required repo secrets (Settings → Secrets → Actions)
COGNEE_URL, COGNEE_API_KEY, COGNEE_TENANT_ID, COGNEE_USER_ID, OLLAMA_API_KEY
(and optional COGNEE_DATASET, OLLAMA_MODEL to override defaults). GITHUB_TOKEN is
auto-provided by Actions and posts comments as github-actions[bot]. To post under a
human identity instead, add a GH_PAT secret (classic PAT with repo scope, or
fine-grained with Issues: write + Pull requests: write). Both paths use the same
workflow — GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}.
Memory convention
Run bash scripts/setup.sh (or ingest.py) once locally to build the Cloud graph, then
commit memory_registry.json to the repo so CI has the local decision manifest for
the path-scope + keyword retrieval signals. If the registry is absent, detection
gracefully degrades to semantic-recall-only (no crash). Re-running ingest later refreshes
the graph; the committed registry keeps the local signals in sync.
Commands (reply to the CodeMind conflict comment)
/codemind confirm <reason>— the change is intentional: old belief crossed out (forget),UPDATEremembered,improve()re-weights, after-recall posted./codemind reject— the change is a bug: memory unchanged, old belief reaffirmed.
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 codemind_ci-0.2.0.tar.gz.
File metadata
- Download URL: codemind_ci-0.2.0.tar.gz
- Upload date:
- Size: 68.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d0804c20019dd142c6420d6706b7b1e0d6e994f68ae0f03c67e4f87b0c60c74
|
|
| MD5 |
f795d48e677d20c7cb087c3b1e6cd52c
|
|
| BLAKE2b-256 |
5dd0a35d318f7eedef66c6802847e8755c2a9304dca910f72cd979b9a2f4e8b2
|
File details
Details for the file codemind_ci-0.2.0-py3-none-any.whl.
File metadata
- Download URL: codemind_ci-0.2.0-py3-none-any.whl
- Upload date:
- Size: 64.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79c931d8f92679a77869a6087031119d389cd754ceccc3ccd19d36d5b01747e9
|
|
| MD5 |
c48f9e3c3b4cdaf194c58bb0ac649670
|
|
| BLAKE2b-256 |
2cdeb6e1367b37827e942039d4d158caf91e6ef8beb017c6d3ebe19e989d1dfc
|