Working with the manage database (Doltgres)
Copy page
How branch-scoped database connections work in the Inkeep Agent Framework
Overview
The management database is a Doltgres instance — a PostgreSQL-compatible database with Git-like versioning built in.
Branch naming convention
Each project gets its own main branch, namespaced as:
For example, a project with tenantId: "acme" and projectId: "proj_123" has a main branch named acme_proj_123_main.
Connections to doltgres default to the main branch, so it is critical that every connection checks out the correct project branch before performing any operations. The framework provides two mechanisms for this depending on where your code runs.
Mechanism 1: middleware (manage routes)
All /manage API routes pass through the branchScopedDbMiddleware. This middleware:
- Acquires a dedicated connection from the pool
- Checks out the correct branch (resolved from the request's
refquery parameter) - Creates a Drizzle ORM client scoped to that connection
- Injects it into the Hono context as
'db' - Executes the route handler
- Auto-commits changes on success for write operations (POST, PUT, PATCH, DELETE)
- Cleans up: checks out
mainand releases the connection
Usage in manage routes
Inside any /manage route handler, retrieve the branch-scoped database client from context:
Mechanism 2: withRef
When you need to read or write manage data from outside the /manage routes — for example from the /run domain, /evals domain, or other packages — use the withRef wrapper from @inkeep/agents-core.
withRef handles the full lifecycle of a branch-scoped connection:
- Acquires a dedicated connection from the pool
- Checks out the specified branch
- Executes your callback with a scoped Drizzle client
- Optionally auto-commits on success for write operations
- Cleans up: checks out
main, releases the connection
Read example
Write example with auto-commit
Batching multiple operations
You can batch multiple reads or writes in a single withRef call. This uses one connection and one branch checkout for all operations:
Obtaining a resolvedRef
Most runtime code paths already have a resolvedRef available — either through the Hono context (c.get('resolvedRef')) or via an execution context (this.executionContext.resolvedRef).
If you need to resolve a ref manually, use getProjectScopedRef and resolveRef:
Decision guide
| Where is your code? | What to use |
|---|---|
/manage route handler | c.get('db') — the middleware handles checkout and commit |
/run or /evals route handler | withRef(manageDbPool, resolvedRef, (db) => ...) |
| Service class or utility | withRef(manageDbPool, resolvedRef, (db) => ...) |
Already inside a withRef callback | Use the db from the callback argument directly |
Key files
| File | Purpose |
|---|---|
agents-api/src/middleware/branchScopedDb.ts | Middleware for /manage routes |
packages/agents-core/src/dolt/ref-scope.ts | withRef wrapper and nesting detection |
packages/agents-core/src/dolt/ref-middleware.ts | Ref resolution middleware (resolves ref query param to ResolvedRef) |
packages/agents-core/src/dolt/ref-helpers.ts | Helper functions for ref resolution and management |
packages/agents-core/src/validation/dolt-schemas.ts | ResolvedRef type and Zod schemas |
agents-api/src/data/db/manageDbPool.ts | The connection pool singleton |