Core Direct Lanes and Policy
Policy contract for direct core query routes and safe rollout guidance.
Direct core routes expose low-level retrieval behavior and are intentionally policy-gated.
Route policy contract
Always allowed:
/v2/core/health/v2/core/auth/*
Policy-gated:
POST /v2/core/searchrequiresMUBIT_CORE_ENABLE_DIRECT_SEARCH/v2/core/pubsub/subscribe,/v2/core/pubsub/unsubscribe,/v2/core/pubsub/listrequireMUBIT_CORE_ENABLE_DIRECT_PUBSUB
Other external /v2/core/* routes are denied by default middleware.
Core route reference
These routes are available at /v2/core/*. Routes beyond auth and health require appropriate policy flags or internal access.
Data operations
| Route | Method | Purpose |
|---|---|---|
/v2/core/insert | POST | Insert a single node |
/v2/core/batch_insert | POST | Batch insert multiple nodes (always allowed) |
/v2/core/node/:id | GET | Retrieve a node by ID |
/v2/core/node/:id | DELETE | Delete a node by ID |
/v2/core/runs/:run_id | DELETE | Delete all nodes in a run |
/v2/core/search | POST | Semantic vector search (policy-gated) |
Agent scratchpad memory
Per-session key-value scratchpad for agent working memory.
| Route | Method | Purpose |
|---|---|---|
/v2/core/memory/:session_id | POST | Write to session scratchpad |
/v2/core/memory/:session_id | GET | Read session scratchpad |
/v2/core/memory/:session_id | DELETE | Clear session scratchpad |
SDM (Sparse Distributed Memory) operations
POST /v2/core/sdm/write and POST /v2/core/sdm/read endpoints have been removed and now return HTTP 410 Gone. SDM writes happen implicitly on /v2/core/insert, and SDM reads happen implicitly on /v2/core/search — there is no separate SDM surface to call.Session management
Transactional sessions for atomic multi-operation commits.
| Route | Method | Purpose |
|---|---|---|
/v2/core/session/create | POST | Create a new session |
/v2/core/session/:id/commit | POST | Commit session changes |
/v2/core/session/:id/drop | DELETE | Drop session without committing |
/v2/core/session/:id/snapshot | POST | Snapshot current session state |
/v2/core/session/load | POST | Load a previously snapshotted session |
Storage maintenance
| Route | Method | Purpose |
|---|---|---|
/v2/core/storage/stats | GET | RocksDB storage statistics (size, keys, compaction) (always allowed) |
/v2/core/storage/compact | POST | Trigger manual compaction (always allowed) |
ACL (Access Control)
| Route | Method | Purpose |
|---|---|---|
/v2/core/acl/grant | POST | Grant permission to a user/agent |
/v2/core/acl/revoke | POST | Revoke a permission |
/v2/core/acl/check | POST | Check if a permission is granted |
PubSub
Data-plane subscriptions fire on Node insert / update / delete and on session memory writes. Filters are all, node (specific node_id), semantic (vector similarity over query_text with a threshold), or session (session scope).
| Route | Method | Response | Purpose |
|---|---|---|---|
/v2/core/pubsub/subscribe | POST | text/event-stream (SSE) | Open a server-sent-event stream. First event is subscribed with {subscription_id}; subsequent events are node.inserted, node.updated, node.deleted, or memory.added with flat JSON payloads (see schema below). The subscription lives for the lifetime of the HTTP connection and is cleaned up automatically on disconnect. |
/v2/core/pubsub/unsubscribe | POST | JSON | Explicitly remove a subscription by ID (primarily an admin/debugging surface — normal clients just close the SSE connection). |
/v2/core/pubsub/list | POST | JSON | List active subscription IDs for the calling user, plus the server-wide total. |
gRPC equivalent: CoreService.Subscribe(CoreSubscribeRequest) → stream PubSubEvent on the same data-plane gRPC surface.
Request body for /v2/core/pubsub/subscribe:
| Field | Type | Required | Description |
|---|---|---|---|
filter_type | string | yes | "all", "node", "semantic", or "session". |
node_id | uint64 | when filter_type == "node" | Node to watch. |
query_text | string | when filter_type == "semantic" | Encoded server-side; events fire when an inserted/updated node's vector exceeds similarity threshold. |
threshold | float | no | Cosine-similarity floor for semantic filters. Defaults to 0.8. |
Event payload schema (each SSE data: line + each gRPC PubSubEvent message decode to the same JSON shape):
type | Populated fields |
|---|---|
subscribed | subscription_id |
node.inserted / node.updated | node_id, run_id, metadata_json, created_at, updated_at |
node.deleted | node_id |
memory.added | session_id, entry_json |
metadata_json and entry_json are JSON-encoded strings on the wire. The official SDK wrappers parse them into native metadata / entry objects, coerce uint64 / int64 fields to numbers, and drop irrelevant proto defaults before yielding the event. Clients speaking the raw HTTP / gRPC surface need to do the same translation themselves.
Control parity rule
The same policy gates apply when control.query runs in direct bypass mode.
Rollout guidance
- Start with both direct lane flags disabled.
- Enable one lane at a time outside production.
- Monitor lane-specific request/error metrics.
- Keep routed mode fallback active.
Failure modes and troubleshooting
| Symptom | Root cause | Fix |
|---|---|---|
| Direct lane request denied | Required flag disabled | Use routed retrieval or enable lane explicitly |
| Increased production error rate | Lane enabled without guardrails | Roll back lane and re-enable with staged traffic |
| Unclear fallback behavior | No route policy decision tree | Define mode fallback rules per feature |
Next steps
- Review integration guardrails at Data guardrails.
- Review retrieval implementation choices at Retrieve data.