Graph Kernel
**Version**: 1.1.0 **Last Updated**: 2026-01-03 **Status**: Production **Parent**: [02-TRAJECTORY_OS.md](02-TRAJECTORY_OS.md) **Related**: [08-RAG_PLUS_PLUS.md](08-RAG_PLUS_PLUS.md), [09-ORBIT.md](09-ORBIT.md), [17-AGENT_SDK.md](17-AGENT_SDK.md) **Crate (Rust)**: `core/cc-graph-kernel/` **Service**: Cloud Run `graph-kernel` **Tests**: 140+ passing **Schema Version**: 1.0.0
Full Public Reader
Graph Kernel
Deterministic Context Slicing & Admissibility Authority
Version: 1.1.0
Last Updated: 2026-01-03
Status: Production
Parent: [02-TRAJECTORY_OS.md](02-TRAJECTORY_OS.md)
Related: [08-RAG_PLUS_PLUS.md](08-RAG_PLUS_PLUS.md), [09-ORBIT.md](09-ORBIT.md), [17-AGENT_SDK.md](17-AGENT_SDK.md)
Crate (Rust): `core/cc-graph-kernel/`
Service: Cloud Run `graph-kernel`
Tests: 140+ passing
Schema Version: 1.0.0
---
Executive Summary
The Graph Kernel is the central authority for determining what context is admissible during retrieval and response generation. It answers the fundamental question:
> Given a target turn, which other turns are allowed to influence meaning?
Unlike traditional RAG systems that rely on similarity thresholds, the Graph Kernel provides:
1. Deterministic Slicing: Same anchor + policy + graph state → identical slice
2. Unforgeable Admissibility: HMAC-signed tokens prove kernel authorization
3. Cryptographic Provenance: Every slice carries complete audit trail
4. Policy-Driven Expansion: Configurable, versioned expansion rules
---
Core Contract
The Graph Kernel enforces three production invariants:
| ID | Invariant | Description |
|---|---|---|
| INV-GK-001 | Slice Boundary | Any turn in slice-mode must satisfy `turn_id ∈ slice.turn_ids` |
| INV-GK-002 | Provenance Completeness | Every response includes `(slice_id, policy_ref, schema_version, graph_snapshot_hash, admissibility_token)` |
| INV-GK-003 | No Phantom Authority | Missing `admissibility_token` means non-admissible by definition |
Critical: Violation of INV-GK-001 triggers `SLICE_BOUNDARY_VIOLATION` log and should alert immediately.
---
Architecture
┌──────────────────────────────────────────────────────────────────────────────────┐
│ GRAPH KERNEL SERVICE │
│ │
│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────────┐ │
│ │ API Layer │ │ Slicer Engine │ │ Token Authority │ │
│ │ │ │ │ │ │ │
│ │ POST /api/slice │───▶│ ContextSlicer │───▶│ AdmissibilityToken │ │
│ │ POST /api/verify │ │ SlicePolicyV1 │ │ HMAC-SHA256 Signing │ │
│ │ GET /health/* │ │ GraphStore │ │ Verification │ │
│ │ GET /api/policies│ │ │ │ │ │
│ └───────────────────┘ └───────────────────┘ └───────────────────────┘ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌───────────────────────┐ │ │
│ │ │ PostgreSQL Store │ │ │
│ │ │ (memory_turns) │ │ │
│ │ │ Connection Pool │ │ │
│ │ └───────────────────────┘ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Observability Stack │ │
│ │ ┌─────────────┐ ┌─────────────────┐ ┌────────────────────────────┐ │ │
│ │ │ JSON Logs │ │ Prometheus │ │ Health Probes │ │ │
│ │ │ (tracing) │ │ Metrics :9000 │ │ /live /ready /startup │ │ │
│ │ └─────────────┘ └─────────────────┘ └────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────┘Data Flow
flowchart LR
subgraph Client [Downstream Service]
RAG[RAG++ Service]
Orbit[Orbit Server]
end
subgraph GraphKernel [Graph Kernel]
API[Axum Router]
Slicer[ContextSlicer]
Policy[PolicyRegistry]
Store[PostgresGraphStore]
Token[HMAC Authority]
end
subgraph Database [PostgreSQL]
MT[(memory_turns)]
CV[(conversations)]
end
RAG -->|POST /api/slice| API
Orbit -->|POST /api/verify| API
API --> Slicer
Slicer --> Policy
Slicer --> Store
Store --> MT
Store --> CV
Slicer --> Token
Token -->|HMAC-SHA256| API
API -->|SliceExport| RAG---
Slicing Algorithm
The `ContextSlicer` implements priority-queue expansion around an anchor turn:
pub struct ContextSlicer<S: GraphStore> {
store: Arc<S>,
policy: SlicePolicyV1,
hmac_secret: Vec<u8>, // Kernel-only secret
}Algorithm Steps
1. Initialize: Start with anchor turn at distance 0
2. Queue: Add to frontier priority queue (max-heap by priority score)
3. Expand: While frontier not empty and `nodes < max_nodes`:
- Pop highest priority candidate
- Add to slice
- Add unvisited parents/children to frontier (`distance + 1`)
- If `include_siblings`: add siblings up to limit
4. Collect: Gather edges between selected turns
5. Hash: Compute `GraphSnapshotHash` from content hashes
6. Sign: Issue `AdmissibilityToken` via HMAC-SHA256
7. Export: Return sorted `SliceExport` with full provenance
Priority Scoring
priority_score =
base_salience * policy.phase_weights[turn.phase] *
policy.distance_decay.powf(distance as f64)| Factor | Description |
|---|---|
| `base_salience` | Turn's inherent importance (0.0-1.0) |
| `phase_weights` | Per-phase multipliers (exploration, planning, execution, etc.) |
| `distance_decay` | Exponential decay by graph distance (default: 0.8) |
---
Slice Policy
Policies control expansion behavior and are immutable once registered:
pub struct SlicePolicyV1 {
/// Maximum turns in slice
pub max_nodes: usize,
/// Maximum graph distance from anchor
pub max_radius: usize,
/// Distance decay factor (0.0-1.0)
pub distance_decay: f64,
/// Include sibling turns?
pub include_siblings: bool,
/// Maximum siblings per node
pub max_siblings_per_node: usize,
/// Phase-specific weights
pub phase_weights: PhaseWeights,
}Default Policy
| Parameter | Default | Description |
|---|---|---|
| `max_nodes` | 50 | Maximum turns in slice |
| `max_radius` | 5 | Maximum graph hops |
| `distance_decay` | 0.8 | 20 |
| `include_siblings` | true | Include sibling turns |
| `max_siblings_per_node` | 3 | Limit siblings per parent |
Phase Weights
| Phase | Default Weight | Purpose |
|---|---|---|
| Exploration | 0.8 | Ideation, brainstorming |
| Planning | 0.9 | Structuring, organizing |
| Execution | 1.0 | Active development |
| Synthesis | 1.1 | Integration, review |
| Consolidation | 0.7 | Archival, cleanup |
| Unknown | 0.5 | Unclassified turns |
Policy Registration
// Register a custom policy
let mut registry = PolicyRegistry::new();
let custom_policy = SlicePolicyV1 {
max_nodes: 100,
max_radius: 8,
distance_decay: 0.85,
..Default::default()
};
let policy_ref = registry.register(custom_policy);
// policy_ref.params_hash is stable across restarts---
Admissibility Tokens
The `AdmissibilityToken` is an unforgeable proof that a slice was issued by the kernel:
Token Computation
[sensitive field redacted]
secret,
canonical_string(
slice_id,
anchor_turn_id,
policy_id,
policy_params_hash,
graph_snapshot_hash,
schema_version,
"admissibility_token_v2_hmac"
)
)[..16] // First 128 bits as hexVerification Flow
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ RAG++ uses │ │ Graph Kernel │ │ Token Valid? │
│ slice turns │─────▶│ POST /api/verify │─────▶│ │
│ │ │ │ │ Yes → Proceed │
│ │ │ │ │ No → Reject │
└─────────────┘ └──────────────────┘ └─────────────────┘Token Properties
| Property | Value |
|---|---|
| Algorithm | HMAC-SHA256 |
| Length | 32 hex characters (128 bits) |
| Secret | `KERNEL_HMAC_SECRET` env var |
| Verification | Constant-time comparison |
---
Graph Snapshot Hash
The `GraphSnapshotHash` ensures content immutability for replay:
Content-Based Hashing (Production)
snapshot_hash = xxHash64(
edge_count ||
schema_version ||
fold(sorted_turns, (turn_id, content_hash))
)This guarantees:
- Any content change → different hash
- Same content → identical hash
- Turn reordering doesn't affect hash (sorted)
Legacy Stats-Based Hashing
For backwards compatibility when `content_hash` is missing:
snapshot_hash = canonical_hash(max_updated_at, turn_count, edge_count, schema_version)Note: Run the `content_hash` backfill migration for full immutability guarantees.
---
Slice Export
The complete `SliceExport` contains everything needed for provenance:
pub struct SliceExport {
pub anchor_turn_id: TurnId,
pub turns: Vec<TurnSnapshot>, // Sorted by TurnId
pub edges: Vec<Edge>, // Sorted by (parent, child)
pub policy_id: String,
pub policy_params_hash: String,
pub schema_version: String,
pub slice_id: SliceFingerprint, // Deterministic selection hash
pub graph_snapshot_hash: GraphSnapshotHash, // Content immutability
pub admissibility_token: AdmissibilityToken, // Unforgeable proof
}Provenance Fields
| Field | Purpose |
|---|---|
| `slice_id` | Uniquely identifies the selection (anchor + policy + turns) |
| `policy_id` + `policy_params_hash` | Identifies exact policy used |
| `schema_version` | Graph Kernel version for compatibility |
| `graph_snapshot_hash` | Detects content drift |
| `admissibility_token` | Proves kernel authorization |
---
API Reference
POST `/api/slice`
Generate a context slice around an anchor turn.
Request:
{
"anchor_turn_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "a1b2c3d4e5f6"
}
}Response:
{
"slice": {
"anchor_turn_id": "550e8400-e29b-41d4-a716-446655440000",
"turns": [...],
"edges": [...],
"slice_id": "7f8a9b0c...",
"graph_snapshot_hash": "c3d4e5f6...",
"admissibility_token": "1a2b3c4d5e6f7890...",
"policy_id": "slice_policy_v1",
"policy_params_hash": "a1b2c3d4e5f6",
"schema_version": "1.0.0"
},
"policy_ref": {
"policy_id": "slice_policy_v1",
"params_hash": "a1b2c3d4e5f6"
}
}POST `/api/slice/batch`
Generate multiple slices in one request.
Request:
{
"anchor_turn_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
],
"policy_ref": null
}POST `/api/verify_token`
Verify an admissibility token without exposing the secret.
Request:
{
"admissibility_token": "1a2b3c4d5e6f7890...",
"slice_id": "7f8a9b0c...",
"anchor_turn_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_id": "slice_policy_v1",
"policy_params_hash": "a1b2c3d4e5f6",
"graph_snapshot_hash": "c3d4e5f6...",
"schema_version": "1.0.0"
}Response:
{
"valid": true,
"reason": null
}GET `/api/policies`
List all registered policies.
Response:
{
"policies": [
{
"policy_id": "slice_policy_v1",
"params_hash": "a1b2c3d4e5f6"
}
],
"registry_fingerprint": "abc123..."
}Health Endpoints
| Endpoint | Purpose | Cloud Run Probe |
|---|---|---|
| `GET /health` | Detailed status with DB info | - |
| `GET /health/live` | Process running? | Liveness |
| `GET /health/ready` | Ready for traffic? | Readiness |
| `GET /health/startup` | Initialization complete? | Startup |
Health Response:
{
"status": "healthy",
"version": "0.1.0",
"schema_version": "1.0.0",
"policy_count": 1,
"registry_fingerprint": "a1b2c3d4e5f6",
"database": {
"connected": true,
"pool_size": 5,
"pool_idle": 3,
"pool_max": 10
}
}---
Database Integration
PostgresGraphStore
pub struct PostgresConfig {
pub database_url: String,
pub max_connections: u32, // Default: 10
pub min_connections: u32, // Default: 2
pub connect_timeout_secs: u64, // Default: 10
pub idle_timeout_secs: u64, // Default: 300 (5 min)
pub max_lifetime_secs: u64, // Default: 1800 (30 min)
}GraphStore Trait
#[async_trait]
pub trait GraphStore: Send + Sync {
async fn get_turn(&self, id: &TurnId) -> Result<Option<TurnSnapshot>, Error>;
async fn get_parents(&self, id: &TurnId) -> Result<Vec<TurnId>, Error>;
async fn get_children(&self, id: &TurnId) -> Result<Vec<TurnId>, Error>;
async fn get_siblings(&self, id: &TurnId, limit: usize) -> Result<Vec<TurnId>, Error>;
async fn get_edges(&self, turn_ids: &[TurnId]) -> Result<Vec<Edge>, Error>;
}Required Table: `memory_turns`
CREATE TABLE memory_turns (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
conversation_id UUID REFERENCES conversations(id),
session_id TEXT,
role TEXT NOT NULL CHECK (role IN ('user', 'assistant', 'system')),
phase TEXT,
content_text TEXT NOT NULL,
content_hash TEXT, -- SHA-256 of content_text
salience FLOAT DEFAULT 0.5,
depth INTEGER DEFAULT 0,
parent_turn_id UUID REFERENCES memory_turns(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
trajectory_coord JSONB
);
CREATE INDEX idx_memory_turns_parent ON memory_turns(parent_turn_id);
CREATE INDEX idx_memory_turns_content_hash ON memory_turns(content_hash);Content Hash Backfill
Run the incremental backfill for existing turns:
-- migrations/012_content_hash_backfill_incremental.sql
DO $$
DECLARE
batch_size INTEGER := 10000;
rows_updated INTEGER;
BEGIN
LOOP
UPDATE memory_turns
SET content_hash = encode(sha256(content_text::bytea), 'hex')
WHERE id IN (
SELECT id FROM memory_turns
WHERE content_hash IS NULL AND content_text IS NOT NULL
LIMIT batch_size
FOR UPDATE SKIP LOCKED
);
GET DIAGNOSTICS rows_updated = ROW_COUNT;
IF rows_updated = 0 THEN EXIT; END IF;
PERFORM pg_sleep(0.1);
END LOOP;
END $$;---
Deployment
Cloud Run Configuration
# cloudbuild-service.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/graph-kernel:latest',
'-f', 'Dockerfile.service', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/graph-kernel:latest']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- 'run'
- 'deploy'
- 'graph-kernel'
- '--image=gcr.io/$PROJECT_ID/graph-kernel:latest'
- '--platform=managed'
- '--region=us-central1'
- '--no-allow-unauthenticated'
- '--port=8001'
- '--memory=1Gi'
- '--cpu=1'
- '--timeout=60'
- '--concurrency=50'
- '--min-instances=0'
- '--max-instances=10'
- '--cpu-throttling=true'
- '--set-secrets=KERNEL_HMAC_SECRET=kernel-hmac-[sensitive field redacted],DATABASE_URL=database-url:latest'
- '--set-env-vars=RUST_LOG=info,HOST=[ip]'Dockerfile
FROM rust:1.80.0-slim as builder
WORKDIR /app
RUN apt-get update && apt-get install -y pkg-config libssl-dev
COPY Cargo.toml Cargo.lock* ./
COPY src ./src
RUN cargo build --release --features service --bin graph_kernel_service
FROM debian:bookworm-slim
WORKDIR /app
RUN apt-get update && apt-get install -y ca-certificates libssl3 curl
COPY --from=builder /app/target/release/graph_kernel_service /app/
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
ENV PORT=8001 HOST=[ip] RUST_LOG=info
EXPOSE 8001
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -f http://localhost:8001/health || exit 1
CMD ["/app/graph_kernel_service"]Environment Variables
| Variable | Required | Description |
|---|---|---|
| `KERNEL_HMAC_SECRET` | Yes | Secret for signing tokens (32+ bytes) |
| `DATABASE_URL` | Yes | PostgreSQL connection string |
| `RUST_LOG` | No | Log level (default: `info`) |
| `PORT` | No | HTTP port (default: `8001`) |
| `HOST` | No | Bind address (default: `[ip]`) |
| `DB_MAX_CONNECTIONS` | No | Pool max (default: `10`) |
| `DB_MIN_CONNECTIONS` | No | Pool min (default: `2`) |
Secrets Management
# Create HMAC secret
openssl rand -base64 32 | gcloud secrets create kernel-hmac-secret --data-file=-
# Grant Cloud Run access
gcloud secrets add-iam-policy-binding kernel-hmac-secret \
--member="serviceAccount:[email]" \
--role="roles/secretmanager.secretAccessor"---
Observability
Metrics (Prometheus)
Exposed on port 9000 (`/metrics`):
| Metric | Type | Labels | Description |
|---|---|---|---|
| `graph_kernel_requests_total` | Counter | method, path, status | HTTP requests |
| `graph_kernel_request_duration_seconds` | Histogram | method, path | Request latency |
| `graph_kernel_slices_generated_total` | Counter | - | Slices created |
| `graph_kernel_slice_turns_count` | Histogram | - | Turns per slice |
| `graph_kernel_slice_edges_count` | Histogram | - | Edges per slice |
| `graph_kernel_slice_latency_ms` | Histogram | - | Slice generation time |
| `graph_kernel_token_verifications_total` | Counter | result | Token checks |
Structured Logging
JSON logs for Cloud Logging:
{
"timestamp": "2026-01-02T10:00:00.000Z",
"level": "INFO",
"target": "graph_kernel_service",
"trace_id": "abc123def456",
"message": "slice generated",
"slice_id": "7f8a9b0c...",
"anchor_turn_id": "550e8400-...",
"turn_count": 25,
"edge_count": 42,
"latency_ms": 45
}Critical Log Patterns
| Pattern | Severity | Action |
|---|---|---|
| `SLICE_BOUNDARY_VIOLATION` | CRITICAL | Immediate alert, investigate |
| `TOKEN_MISMATCH` | Warning | Check HMAC secret consistency |
| `DB_CONNECTION_ERROR` | Error | Check DATABASE_URL, pool stats |
| `KERNEL_HMAC_SECRET not set` | Warning | Set for production |
Alerting Recommendations
# High Priority
- alert: GraphKernelSliceBoundaryViolation
expr: count_over_time({job="graph-kernel"} |= "SLICE_BOUNDARY_VIOLATION" [5m]) > 0
severity: critical
- alert: GraphKernelHighErrorRate
expr: sum(rate(graph_kernel_requests_total{status=~"5.."}[5m])) / sum(rate(graph_kernel_requests_total[5m])) > 0.05
severity: warning
# Medium Priority
- alert: GraphKernelHighLatency
expr: histogram_quantile(0.95, rate(graph_kernel_slice_latency_ms[5m])) > 5000
severity: warning
- alert: GraphKernelTokenFailures
expr: sum(rate(graph_kernel_token_verifications_total{result="invalid"}[5m])) > 0.1
severity: warning---
Type-Level Admissibility Safety
Version: 1.1.0 (Added 2026-01-02)
The Graph Kernel enforces admissibility at the type system level, making it physically impossible to pass unverified evidence to promotion pipelines.
AdmissibleEvidenceBundle
The `AdmissibleEvidenceBundle` type is the sole representation of kernel-authorized evidence:
pub struct AdmissibleEvidenceBundle {
slice: SliceExport,
verified_at_unix_ms: i64,
}
impl AdmissibleEvidenceBundle {
/// ONLY way to construct - requires HMAC verification
pub fn from_verified(
slice: SliceExport,
hmac_secret: &[u8],
) -> Result<Self, VerificationError> {
// Verifies HMAC token before constructing
if !slice.admissibility_token.verify_hmac(...) {
return Err(VerificationError::TokenMismatch);
}
Ok(Self { slice, verified_at_unix_ms: now() })
}
}Security Guarantee
INV-GK-003 Enforcement: No Phantom Authority
By making `AdmissibleEvidenceBundle` the required type for promotion APIs, we enforce admissibility at compile time:
// OLD (unsafe - accepts any slice):
fn promote_turn(turn_id: TurnId, evidence: Vec<TurnSnapshot>) { ... }
// NEW (type-safe - only accepts verified bundles):
fn promote_turn(turn_id: TurnId, evidence: &AdmissibleEvidenceBundle) { ... }With the new signature:
- ✅ Cannot call `promote_turn` with raw `SliceExport`
- ✅ Cannot bypass token verification
- ✅ Cannot forge admissibility claims
- ✅ Compiler enforces the security boundary
Usage Example
// Downstream service (RAG++ promotion pipeline)
use cc_graph_kernel::{AdmissibleEvidenceBundle, VerificationError};
async fn promote_turn_lifecycle(
turn_id: TurnId,
slice: SliceExport,
kernel_secret: &[u8],
) -> Result<(), PromotionError> {
// Verify admissibility
let bundle = AdmissibleEvidenceBundle::from_verified(slice, kernel_secret)?;
// Type system guarantees bundle is verified
promote_turn_internal(turn_id, &bundle)?;
Ok(())
}
// This function signature makes forgery impossible
fn promote_turn_internal(
turn_id: TurnId,
evidence: &AdmissibleEvidenceBundle, // Must be verified
) -> Result<(), PromotionError> {
// Can safely use evidence.turn_ids() knowing it's admissible
let admissible_ids = evidence.turn_ids();
// ... promotion logic
}Breach Prevention
This design prevents entire classes of security bugs:
| Attack Vector | Prevention Mechanism |
|---|---|
| Forged tokens | `from_verified()` checks HMAC before construction |
| Bypassed verification | Cannot construct `AdmissibleEvidenceBundle` without secret |
| Accidental unverified use | Type error at compile time if passing raw `SliceExport` |
| Logic bugs in downstream | Even buggy code can't promote unverified evidence |
Performance Note
Token verification is performed once when constructing the bundle. Subsequent use of the bundle carries zero verification overhead.
---
Integration with RAG++
Request Flow
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ User Query │────▶│ RAG++ Service │────▶│ Graph Kernel │
│ │ │ │ │ │
│ │ │ 1. Get anchor │ │ 2. Generate │
│ │ │ turn ID │ │ slice │
│ │ │ │◀────│ │
│ │ │ 3. Filter turns │ │ │
│ │◀────│ by slice │ │ │
│ Response │ │ │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘RAG++ Integration Code
# In RAG++ retrieval pipeline
from httpx import AsyncClient
async def get_admissible_context(anchor_turn_id: str, graph_kernel_url: str):
async with AsyncClient() as client:
response = await client.post(
f"{graph_kernel_url}/api/slice",
json={"anchor_turn_id": anchor_turn_id}
)
slice_data = response.json()["slice"]
# Only use turns from the slice
admissible_turn_ids = {t["id"] for t in slice_data["turns"]}
# Carry provenance forward
provenance = {
"slice_id": slice_data["slice_id"],
"admissibility_token": slice_data["admissibility_token"],
"graph_snapshot_hash": slice_data["graph_snapshot_hash"],
"schema_version": slice_data["schema_version"],
}
return admissible_turn_ids, provenance---
Testing
Unit Tests
cd core/cc-graph-kernel
cargo test --all-featuresKey Test Cases
| Test | Purpose |
|---|---|
| `test_slice_includes_anchor` | Anchor always in slice |
| `test_slice_respects_max_nodes` | Budget enforcement |
| `test_slice_respects_max_radius` | Radius enforcement |
| `test_slice_determinism` | Same input → same output |
| `test_hmac_token_verification` | Token signing/verification |
| `test_content_hash_snapshot` | GraphSnapshotHash determinism |
| `test_turn_admissibility` | Slice boundary checks |
Integration Test
# Start service locally
KERNEL_HMAC_SECRET=test_secret_32bytes_minimum!! \
DATABASE_URL=postgresql://localhost/orbit_test \
cargo run --release --features service --bin graph_kernel_service
# Test slice generation
curl -X POST http://localhost:8001/api/slice \
-H "Content-Type: application/json" \
-d '{"anchor_turn_id": "YOUR_TURN_ID"}'
# Test health
curl http://localhost:8001/health | jq---
Atlas Module (Advanced)
The Atlas module provides advanced analysis capabilities:
GraphSnapshot
Capture complete graph state for offline analysis:
let snapshot = GraphSnapshot::capture(&store, config).await?;BatchSlicer
Generate slices for many anchors efficiently:
let slicer = BatchSlicer::new(store, policy);
let results = slicer.slice_all(&anchor_ids).await?;OverlapAnalyzer
Find overlapping context between slices:
let analyzer = OverlapAnalyzer::new();
let overlap_graph = analyzer.analyze(&slices)?;TurnInfluence
Compute influence scores for turns:
let influence = compute_influence(&slice, &graph)?;
// influence.scores contains per-turn influence metrics---
Performance Targets
| Operation | Target | Measured |
|---|---|---|
| Slice Generation (50 turns) | < 100ms | ~45ms |
| Token Verification | < 5ms | ~2ms |
| Health Check | < 10ms | ~3ms |
| Cold Start | < 5s | ~3s |
---
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-01-02 | Production release with HMAC tokens, connection pooling, structured logging |
| 0.2.0 | 2025-12-15 | Added GraphSnapshotHash, Atlas module |
| 0.1.0 | 2025-12-01 | Initial implementation |
---
Agent SDK Integration
The Agent SDK (`@comp-core/agent-sdk`) provides 4 Graph Kernel MCP tools:
| Tool | Description |
|---|---|
| `graphKernelSliceTool` | Generate deterministic context slice |
| `graphKernelVerifyTool` | Verify admissibility token |
| `graphKernelBatchSliceTool` | Batch slice generation |
| `graphKernelHealthTool` | Health check endpoint |
import { getGraphKernelTool } from '@comp-core/agent-sdk/tools';
const sliceTool = getGraphKernelTool('graphKernelSliceTool');
const slice = await sliceTool.handler({
anchor_turn_id: 'turn_123',
depth: 3,
max_turns: 100,
}, context);See: [17-AGENT_SDK.md](17-AGENT_SDK.md) and [16-GRAPH_KERNEL_INTEGRATION.md](16-GRAPH_KERNEL_INTEGRATION.md) for full details.
---
Further Reading
- [08-RAG_PLUS_PLUS.md](08-RAG_PLUS_PLUS.md) — Memory layer that consumes slices
- [09-ORBIT.md](09-ORBIT.md) — Orchestration layer
- [12-DEPLOYMENT.md](12-DEPLOYMENT.md) — Cloud Run deployment details
- [13-DATA_CONTRACTS.md](13-DATA_CONTRACTS.md) — Frozen schemas
- [16-GRAPH_KERNEL_INTEGRATION.md](16-GRAPH_KERNEL_INTEGRATION.md) — Full integration guide
- [17-AGENT_SDK.md](17-AGENT_SDK.md) — Agent SDK with Graph Kernel tools
- [diagrams/graph-kernel-architecture.md](diagrams/graph-kernel-architecture.md) — Visual architecture
---
AUDIT STATUS
| Finding | Severity | Status | Notes |
|---|---|---|---|
| HMAC token implementation | ✓ | Pass | HMAC-SHA256 with constant-time comparison |
| Connection pooling | ✓ | Pass | Configurable pool with health checks |
| Structured logging | ✓ | Pass | JSON format for Cloud Logging |
| Health probes | ✓ | Pass | Liveness, readiness, startup probes |
| Graceful shutdown | ✓ | Pass | SIGTERM handling |
| Content hash backfill | ✓ | Pass | Incremental migration available |
| Prometheus metrics | ✓ | Pass | Request and slice metrics exposed |
| Secret management | ✓ | Pass | Uses Google Secret Manager |
Promotion Decision
Promote into a technical note or architecture paper with implementation anchors.
Source Anchor
Comp-Core/docs/architecture/15-GRAPH_KERNEL.md
Detected Structure
Method · Evaluation · References · Math · Architecture