Skip to content

feat(knowledge-store): git-native knowledge base - #1651

Merged
CREDO23 merged 1 commit into
MODSetter:devfrom
CREDO23:kb-git-mvp-onto-dev
Jul 31, 2026
Merged

feat(knowledge-store): git-native knowledge base#1651
CREDO23 merged 1 commit into
MODSetter:devfrom
CREDO23:kb-git-mvp-onto-dev

Conversation

@CREDO23

@CREDO23 CREDO23 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Brings the git-native knowledge base to dev. Same content as #1649, which was reverted from main in #1650 so it wouldn't ship in the last release.

Why this is a revert-of-the-revert and not a merge of kb_git_mvp

Merging the feature branch into dev would make its commits an ancestor of both dev and main. Since main's history now contains a commit deleting all of these files, the next merge in either direction would pick the feature branch tip as the merge base, see main's deletion as the only change, and silently remove the feature again — no conflict, no warning.

Reverting the revert carries the content without the history. dev and main share no ancestor that knows about these files, so the eventual dev -> main merge sees them as added on one side only and keeps them.

The cost is that the individual commits from #1649 aren't preserved here. That PR has the granular history if anyone needs it.

What it does

Git becomes the source of truth for knowledge base content. Postgres and pgvector become a derived index that can be rebuilt from git at any time. Agent turns commit through a KnowledgeStore.transaction() unit of work, and a Celery consumer converges the index from the committed revision.

Safety

Two independent switches guard every new path, both defaulting to off:

  • KNOWLEDGE_STORE_ENABLED, an env var, default FALSE
  • workspaces.knowledge_store_enabled, a per-workspace column, default false

With either off, the existing write path runs unchanged, so merging this changes no runtime behaviour.

Migrations 175 and 176 only add columns and are written with ADD COLUMN IF NOT EXISTS. They are already applied on production, where alembic_version was rolled back to 174 during the revert, so re-running them is a no-op.

Verification on this branch

The single collection error under tests/unit/platforms/google_maps is a fixture file that is untracked on both dev and main; it predates this change and is unrelated.

High-level PR Summary

This PR introduces a git-native knowledge base to the dev branch, making Git the single source of truth for workspace knowledge content while demoting Postgres to a derived, rebuildable index. The implementation pivots from a custom virtual filesystem over Postgres to using dulwich (pure-Python Git) for versioned storage, with each workspace getting its own Git repository. The change is controlled by two feature flags (KNOWLEDGE_STORE_ENABLED environment variable and per-workspace knowledge_store_enabled database column), both defaulting to off, so merging changes no runtime behavior. Key components include: a framework-agnostic KnowledgeStore facade over Git storage, per-turn working copies for agent operations, end-of-turn commit middleware, an indexer that rebuilds Postgres chunks from Git, migration tooling to seed existing workspaces, and drift monitoring. The architecture follows ports-and-adapters pattern where deepagents is just one adapter. Database migrations 175 and 176 add nullable columns with IF NOT EXISTS clauses for safety. The implementation deletes three hand-rolled versioning systems (DocumentVersion, DocumentRevision/FolderRevision, AgentActionLog) in favor of native Git history, and includes extensive unit and integration tests covering the full stack from Git engine to agent middleware.

⏱️ Estimated Review Time: 3+ hours

💡 Review Order Suggestion
Order File Path
1 docs/adr/0001-git-native-knowledge-base.md
2 docs/adr/0002-knowledge-core-ports-and-adapters.md
3 plans/git-native-kb/00-umbrella-plan.md
4 plans/git-native-kb/00c-shared-contract.md
5 surfsense_backend/alembic/versions/175_add_workspace_knowledge_store_flag.py
6 surfsense_backend/alembic/versions/176_add_derived_index_columns.py
7 surfsense_backend/app/config/__init__.py
8 surfsense_backend/app/db.py
9 surfsense_backend/app/knowledge_store/settings.py
10 surfsense_backend/app/knowledge_store/engines/base.py
11 surfsense_backend/app/knowledge_store/engines/git.py
12 surfsense_backend/app/knowledge_store/store_path.py
13 surfsense_backend/app/knowledge_store/write_lock.py
14 surfsense_backend/app/knowledge_store/transaction.py
15 surfsense_backend/app/knowledge_store/store.py
16 surfsense_backend/app/knowledge_store/identities.py
17 surfsense_backend/app/agents/chat/runtime/path_resolver.py
18 surfsense_backend/app/agents/chat/multi_agent_chat/shared/middleware/filesystem/backends/git_tree.py
19 surfsense_backend/app/agents/chat/multi_agent_chat/shared/middleware/filesystem/backends/resolver.py
20 surfsense_backend/app/agents/chat/multi_agent_chat/shared/middleware/filesystem/backends/local_folder.py
21 surfsense_backend/app/agents/chat/multi_agent_chat/shared/middleware/filesystem/backends/multi_root_local_folder.py
22 surfsense_backend/app/agents/chat/multi_agent_chat/shared/middleware/filesystem/tools/read_file/description.py
23 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/middleware/knowledge_store_persistence/commit_message.py
24 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/middleware/knowledge_store_persistence/commit_turn.py
25 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/middleware/knowledge_store_persistence/middleware.py
26 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/middleware/knowledge_store_persistence/builder.py
27 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/middleware/stack.py
28 surfsense_backend/app/agents/chat/multi_agent_chat/main_agent/runtime/factory.py
29 surfsense_backend/app/tasks/chat/streaming/agent/event_loop.py
30 surfsense_backend/app/indexing_pipeline/document_chunker.py
31 surfsense_backend/app/indexing_pipeline/chunk_reconciler.py
32 surfsense_backend/app/indexing_pipeline/cache/cached_indexing.py
33 surfsense_backend/app/indexing_pipeline/indexing_pipeline_service.py
34 surfsense_backend/app/knowledge_store/index/converge.py
35 surfsense_backend/app/knowledge_store/index/queue.py
36 surfsense_backend/app/tasks/celery_tasks/knowledge_store/index_tasks.py
37 surfsense_backend/app/tasks/celery_tasks/knowledge_store/drift_monitor_task.py
38 surfsense_backend/app/knowledge_store/migrate.py
39 surfsense_backend/scripts/migrate_knowledge_store.py
40 surfsense_backend/app/services/document_revision_recorder.py
41 surfsense_backend/app/routes/documents_routes.py
42 surfsense_backend/app/routes/editor_routes.py
43 surfsense_backend/app/knowledge_store/janitor.py
44 surfsense_backend/app/tasks/celery_tasks/knowledge_store/janitor_task.py
45 surfsense_backend/app/observability/metrics.py
46 surfsense_backend/app/celery_app.py
47 surfsense_backend/pyproject.toml

Need help? Join our Discord

Restores the work from MODSetter#1649, which was reverted on main in MODSetter#1650 to keep
it out of the last release. Content is identical to that merge.

This is a revert of the revert (a8292f5) rather than a merge of
kb_git_mvp, deliberately. Merging the branch would make its commits an
ancestor of both dev and main; main's side deleted those files, so the
next merge between the two branches would silently delete them again. A
revert carries the content without the history, so dev and main share no
ancestor that knows about these files, and the eventual dev -> main merge
sees them as added on one side only and keeps them.

Git becomes the source of truth for knowledge base content; Postgres and
pgvector become a derived, rebuildable index. Both switches guarding the
new path default to off: the KNOWLEDGE_STORE_ENABLED env var and the
per-workspace knowledge_store_enabled column, so merging this changes no
runtime behaviour.

Migrations 175 and 176 only add columns and use ADD COLUMN IF NOT EXISTS.
They are already applied on production, where alembic_version was moved
back to 174 during the revert, so they will re-run harmlessly.

Verified on this branch: 0 conflicts against dev, every app.* import in
the restored files resolves, 2251 unit tests pass. The one collection
error (platforms/google_maps) is missing a fixture that is untracked on
both dev and main, and predates this change.
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

@CREDO23 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fa82909a-abd1-4824-b649-f6c34920937b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CREDO23
CREDO23 merged commit 96314a0 into MODSetter:dev Jul 31, 2026
4 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant