Skip to content

Configuration reference

Complete reference for astrocyte.yaml — every key, type, default, and valid value.

Astrocyte loads configuration with this merge order (last wins):

  1. Compliance profile (compliance_profile: pdpa) — sets barriers, lifecycle, access control, DLP
  2. Profile (profile: personal) — sets defaults, homeostasis, signal quality
  3. Your astrocyte.yaml — overrides everything above

All string values support ${ENV_VAR} substitution — unresolved vars are left as-is.


Key Type Default Description
provider_tier "storage" | "engine" "engine" storage uses Astrocyte’s built-in pipeline with your own storage adapters (vector store, wiki store, etc.). engine delegates the entire pipeline to a full memory engine (Mystique, Mem0, Zep, etc.)
profile string | null null Built-in profile name (minimal, personal, research, coding, support) or path to custom profile file (./my-profile.yaml)
compliance_profile string | null null Pre-built compliance preset: gdpr, hipaa, or pdpa. Sets barriers, lifecycle, access control, and DLP automatically
fallback_strategy "error" | "local_llm" | "degrade" "error" How to handle provider failures

Used when provider_tier: storage.

Key Type Default Description
vector_store string | null null Vector store provider: in_memory, postgres, qdrant, etc.
vector_store_config dict | null null Provider-specific settings (connection URL, dimensions, etc.)
graph_store string | null null Graph store provider: neo4j, or in_memory for testing. Section-level graph traversal (entity bridging, causal links) runs over built-in flat SQL tables without a graph store adapter.
graph_store_config dict | null null Provider-specific settings
document_store string | null null Document store provider: postgres (pg_tsvector + GIN + BM25, same adapter as vector_store: postgres), elasticsearch, etc.
document_store_config dict | null null Provider-specific settings
# Example: pgvector + Neo4j hybrid
provider_tier: storage
vector_store: postgres
vector_store_config:
dsn: ${DATABASE_URL}
embedding_dimensions: 1536
bootstrap_schema: true
graph_store: neo4j
graph_store_config:
uri: bolt://localhost:7687
user: neo4j
password: ${NEO4J_PASSWORD}

Used when provider_tier: engine.

Key Type Default Description
provider string | null null Engine provider name: mystique, mem0, zep, etc.
provider_config dict | null null Engine-specific settings (endpoint, API key, etc.)
provider_tier: engine
provider: mystique
provider_config:
endpoint: ${MYSTIQUE_ENDPOINT}
api_key: ${MYSTIQUE_API_KEY}
Key Type Default Description
llm_provider string | null null LLM provider for reflect and extraction: openai, claude_cli, local_embeddings, litellm, mock, or any installed adapter. Also accepts a direct module:Class import path.
llm_provider_config dict | null null API key, model name, endpoint, etc.
embedding_provider string | null null Separate embedding provider (if different from LLM)
embedding_provider_config dict | null null Embedding-specific settings (dimensions, model, etc.)
llm_provider: openai
llm_provider_config:
api_key: ${OPENAI_API_KEY}
model: gpt-4o-mini
# The OpenAI provider handles both chat completions and embeddings.
# Use astrocyte-llm-litellm for Anthropic, Bedrock, Vertex, Ollama, and other providers.
Name Completions Embeddings Requires
openai OPENAI_API_KEY
litellm astrocyte-llm-litellm + the backing provider’s key
claude_cli Claude Code CLI on PATH (subscription auth — no API key)
local_embeddings sentence-transformers (pip install 'astrocyte[rerank]')
mock nothing (tests only)

Set embedding_provider when one backend can’t do both. The two are composed automatically: complete() routes to llm_provider, embed() to embedding_provider.

# Fully local / subscription-auth — no API keys anywhere.
llm_provider: claude_cli
llm_provider_config:
model: haiku # or sonnet / opus / a pinned model id
embedding_provider: local_embeddings

claude_cli caveats. Each call spawns a claude -p subprocess (~1-3s startup) with concurrency bounded by ASTROCYTE_CLAUDE_CLI_MAX_CONCURRENCY (default 4). The CLI exposes no sampling controls, so temperature and max_tokens are accepted but ignored, and native function calling (tools=) raises NotImplementedError rather than silently dropping tool calls. JSON response formats are emulated via prompt instruction. ANTHROPIC_API_KEY is deliberately stripped from the subprocess environment so calls always bill the CLI’s logged-in subscription.

local_embeddings caveats. Defaults to BAAI/bge-small-en-v1.5 (384-dim), zero-padded to 1536 so it drops into the reference schema’s vector(1536) columns with no migration — padding a normalized vector preserves cosine ordering exactly. A model wider than pad_to raises rather than truncating. Override with embedding_provider_config: {model_name: ..., pad_to: ...}; note that raising pad_to above 1536 requires a schema migration.


Rate limits, quotas, and token budgets.

homeostasis:
recall_max_tokens: 4096
reflect_max_tokens: 8192
retain_max_content_bytes: 51200
rate_limits:
retain_per_minute: 60
recall_per_minute: 120
reflect_per_minute: 30
global_per_minute: null # optional global cap
quotas:
retain_per_day: null # optional daily cap
reflect_per_day: null
Key Type Default Description
recall_max_tokens int | null null Max tokens per recall operation
reflect_max_tokens int | null null Max tokens per reflect operation
retain_max_content_bytes int | null null Max bytes per retain operation
rate_limits.retain_per_minute int | null null Max retain operations per minute
rate_limits.recall_per_minute int | null null Max recall operations per minute
rate_limits.reflect_per_minute int | null null Max reflect operations per minute
rate_limits.global_per_minute int | null null Global rate limit across all operations
quotas.retain_per_day int | null null Max retains per 24 hours
quotas.reflect_per_day int | null null Max reflects per 24 hours

Safety controls applied on every retain operation.

Key Type Default Description
mode string "regex" Detection mode: regex, ner, llm, rules_then_llm, disabled
action string "redact" What to do when PII is found: redact, reject, warn
countries list[string] | null null Country-specific patterns: SG (NRIC), IN (Aadhaar), GB (NINO), US (SSN), AU (TFN), CA, JP, CN, DE, FR, IT, ES
patterns list[dict] | null null Custom regex patterns: [{type: "custom_id", pattern: "\\d{8}"}]
type_overrides dict | null null Override action per PII type: {credit_card: {action: reject}}
barriers:
pii:
mode: rules_then_llm
action: redact
countries: [SG, IN, GB, US]
type_overrides:
credit_card: { action: reject }
name: { action: warn }
Key Type Default Description
max_content_length int 50000 Reject content over this many bytes
reject_empty_content bool true Reject empty or whitespace-only content
reject_binary_content bool true Reject non-text content
allowed_content_types list[string] | null null Optional content type whitelist
Key Type Default Description
blocked_keys list[string] ["api_key", "password", "token", "secret"] Keys to scrub from metadata
max_metadata_size_bytes int 4096 Max metadata size in bytes

Deduplication and noise detection.

Key Type Default Description
enabled bool true Enable duplicate detection
similarity_threshold float 0.95 Cosine similarity threshold for duplicates (0–1)
action string "skip" What to do with duplicates: skip, warn, update
Key Type Default Description
enabled bool true Enable noisy bank detection
retain_spike_multiplier float 5.0 Retain rate spike threshold
min_avg_content_length int 20 Minimum average chunk length (chars)
max_dedup_rate float 0.8 Max dedup rate before flagging
action string "warn" Action on noisy bank: warn, throttle, reject

Circuit breaker and degraded mode.

Key Type Default Description
degraded_mode string "empty_recall" Fallback on failure: empty_recall, error, cache
circuit_breaker.failure_threshold int 5 Failures before circuit opens
circuit_breaker.recovery_timeout_seconds float 30.0 Seconds before half-open attempt
circuit_breaker.half_open_max_calls int 2 Max calls in half-open state

Similarity-based caching for repeated queries.

Key Type Default Description
enabled bool false Enable recall cache
similarity_threshold float 0.95 Cache hit threshold
max_entries int 256 Max cached results
ttl_seconds float 300.0 Cache entry lifetime (seconds)

Progressive retrieval strategy — tries cheaper/faster tiers first.

Key Type Default Description
enabled bool false Enable tiered retrieval
min_results int 3 Min results per tier before advancing
min_score float 0.3 Min relevance score threshold
max_tier int 3 Maximum tier (0–4)
full_recall "pipeline" | "hybrid" "pipeline" Recall path for tier 3+. hybrid requires a hybrid engine provider

Defenses against adversarial / false-premise / prompt-injection-shaped queries. All knobs default to off so the framework stays accuracy-first; opt in selectively per preset. See benchmark-presets.md for measured impact per knob and the post-mortem on which combinations help vs hurt.

Key Type Default Description
abstention_enabled bool false When true, recall short-circuits to a stable “insufficient evidence” reply if the top semantic score falls below abstention_floor.
abstention_floor float 0.2 Score threshold below which abstention_enabled fires. Lower values trigger more aggressively.
abstention_floor_intent_only bool false When true, only fire the abstention floor for queries the intent classifier returns as EXPLORATORY or UNKNOWN (i.e. NOT a confidently well-formed FACTUAL / TEMPORAL / RELATIONAL / COMPARATIVE / PROCEDURAL query). Empirically the flat floor cratered single-hop (-10pp) and temporal (-10pp) on config-hindsight-balanced because legitimate factual / temporal queries occasionally have top scores below 0.2; intent-gating recovers those points while keeping the adversarial floor for query shapes where false-premise actually hides. See pipeline/query_intent.py for the classifier.
premise_verification_enabled bool false When true, decompose multi-claim queries into atomic premises and LLM-verify each before retrieval. Adds one LLM call per query; can interfere with rate limits at high concurrency.
adversarial_prompt_enabled bool false When true, prepend an adversarial-defense rule to the synthesis system prompt (“if the question’s premise is false, say so explicitly”). Cheap defense-in-depth — no extra LLM calls.
adversarial_defense:
abstention_enabled: true
abstention_floor: 0.2
abstention_floor_intent_only: true # v0.11.0+
premise_verification_enabled: false
adversarial_prompt_enabled: true

Structured truth precedence — labels fused hits for synthesis.

Key Type Default Description
enabled bool false Enable recall authority
rules_inline string | null null Inline authority rules
rules_path string | null null Path to authority rules file
tiers list [] Precedence tiers: [{id: "primary", priority: 1, label: "Verified"}]
tier_by_bank dict {} Map bank IDs to tier IDs: {bank-1: "primary"}
apply_to_reflect bool true Inject authority context into reflect prompts
recall_authority:
enabled: true
tiers:
- id: primary
priority: 1
label: "Verified sources"
- id: secondary
priority: 2
label: "Inferred knowledge"
tier_by_bank:
verified-bank: primary
inferred-bank: secondary
apply_to_reflect: true

LLM-scored selective retention — only stores content above an importance threshold.

Key Type Default Description
enabled bool false Enable curated retain
model string | null null LLM model for importance scoring
context_recall_limit int 5 Max context items for scoring

Multi-factor ranking — blends recency, reliability, salience, and similarity.

Key Type Default Description
enabled bool false Enable curated recall
freshness_weight float 0.3 Recency bonus weight
reliability_weight float 0.2 Authority/source weight
salience_weight float 0.2 Relevance/importance weight
original_score_weight float 0.3 Vector similarity weight
freshness_half_life_days float 30.0 Decay curve for recency
min_score float | null null Min final score threshold

Key Type Default Description
enabled bool false Enable ACL enforcement
default_policy string "owner_only" Default when no grants match: owner_only, open, deny

Identity-driven bank resolution.

Key Type Default Description
auto_resolve_banks bool false Auto-create banks from principal
user_bank_prefix string "user-" Prefix for user-scoped banks
agent_bank_prefix string "agent-" Prefix for agent-scoped banks
service_bank_prefix string "service-" Prefix for service-scoped banks
resolver "convention" | "config" | "custom" | null null Bank resolution strategy
obo_enabled bool false Enable on-behalf-of permission intersection

Top-level access grants (merged with per-bank banks.*.access).

access_grants:
- bank_id: "shared-*"
principal: "agent:support-bot"
permissions: [read, write]
- bank_id: "user-alice"
principal: "user:alice"
permissions: [read, write, forget, admin]
Field Type Description
bank_id string Bank ID or glob pattern (* for all)
principal string Principal: user:X, agent:X, service:X, or *
permissions list[string] Permissions: read, write, forget, admin, *

Data Loss Prevention — output scanning for PII in recall and reflect results.

Key Type Default Description
scan_recall_output bool false Scan recall results for PII
scan_reflect_output bool false Scan reflect output for PII
output_pii_action string "warn" Action on detected PII: redact, reject, warn

Automatic memory archival and deletion based on age and activity.

Key Type Default Description
enabled bool false Enable lifecycle management
ttl.archive_after_days int 90 Archive if not recalled in N days
ttl.delete_after_days int 365 Delete if older than N days
ttl.exempt_tags list[string] | null null Tags that skip TTL (e.g. pinned, compliance)
ttl.fact_type_overrides dict | null null Override archive_after_days by fact type: {world: 180, experience: null}
lifecycle:
enabled: true
ttl:
archive_after_days: 90
delete_after_days: 365
exempt_tags: [pinned, compliance]
fact_type_overrides:
world: 180
experience: null # never auto-archive

Per-profile reasoning defaults — affect reflect synthesis behavior.

Key Type Default Description
skepticism int 3 How critical to source (1–5)
literalism int 3 How literal vs. interpretive (1–5)
empathy int 3 How empathetic in synthesis (1–5)
preferred_fact_types list[string] | null null Preference order: [experience, world, observation]
tags list[string] | null null Default tags for all retained content

Key Type Default Description
otel_enabled bool false Enable OpenTelemetry spans
prometheus_enabled bool false Enable Prometheus metrics
log_level string "info" Log level: debug, info, warn, error

MCP (Model Context Protocol) server settings — used by astrocyte.mcp and the astrocyte-mcp CLI.

Key Type Default Description
default_bank_id string | null null Default bank for MCP calls
expose_reflect bool true Allow reflect via MCP
expose_forget bool false Allow forget via MCP
expose_admin bool false Allow lifecycle, bank health, and legal-hold admin tools via MCP
max_results_limit int 50 Max items returned per request
principal string | null null Principal for MCP operations

Key Type Default Description
mip_config_path string | null null Path to MIP routing rules file (./mip.yaml)

See Memory Intent Protocol for the full MIP DSL — match operators, actions, override hierarchy, and intent policy.


Per-bank overrides. Each key is a bank ID. Any top-level section can be overridden per bank.

banks:
sensitive-bank:
profile: research
barriers:
pii:
mode: rules_then_llm
action: reject
homeostasis:
recall_max_tokens: 2048
rate_limits:
recall_per_minute: 60
signal_quality:
dedup:
similarity_threshold: 0.90
access:
- bank_id: sensitive-bank
principal: "agent:analyst"
permissions: [read, write]
Key Type Default Description
profile string | null null Override profile for this bank
access list[dict] | null null Bank-specific access grants
homeostasis HomeostasisConfig | null null Override homeostasis settings
barriers BarrierConfig | null null Override barrier settings
signal_quality SignalQualityConfig | null null Override signal quality settings

External data source definitions for ingestion. See poll ingest guide for webhook, stream, and poll setup.

sources:
my-webhook:
type: webhook
extraction_profile: builtin_text
target_bank: webhook-data
auth:
type: hmac_sha256
secret: ${WEBHOOK_SECRET}
github-issues:
type: poll
driver: github
path: owner/repo
interval_seconds: 300
target_bank: github-issues
auth:
token: ${GITHUB_PAT}
type: bearer
redis-events:
type: stream
driver: redis
url: redis://localhost:6379
topic: my-stream
consumer_group: astrocyte-group
target_bank: events
external-api:
type: proxy
url: "https://api.example.com/search?q={query}"
target_bank: external
Key Type Description
type string Source type: webhook, stream, poll / api_poll, proxy
driver string | null Driver name: github, redis, kafka
extraction_profile string | null Extraction profile name for ingested content
target_bank string | null Destination bank ID
target_bank_template string | null Template: "bank-{source_id}"
auth dict | null Auth config (type-specific: hmac_sha256, bearer, etc.)
path string | null Source-specific path (e.g. owner/repo for GitHub)
url string | null Source URL (Redis URL, Kafka bootstrap servers, proxy endpoint)
topic string | null Stream topic or Redis stream key
consumer_group string | null Consumer group name
interval_seconds int | null Poll interval (min 60 for GitHub)
recall_method string | null Proxy only: GET (default) or POST
recall_body dict | null Proxy POST only: request body template

Registered agents with bank access and rate hints.

agents:
support-bot:
principal: "agent:support-bot"
default_bank: shared-support
banks: [shared-support, team-*]
permissions: [read, write]
max_retain_per_minute: 60
max_recall_per_minute: 120
Key Type Default Description
principal string | null null Agent principal (e.g. agent:my-bot)
banks list[string] | null null Allowed bank IDs (glob patterns supported)
allowed_banks list[string] | null null Alias for banks
default_bank string | null null Default bank when not specified
permissions list[string] | null null Declared permissions (documentation/validation)
max_retain_per_minute int | null null Per-agent retain rate hint
max_recall_per_minute int | null null Per-agent recall rate hint

Reusable extraction configurations for ingestion sources.

extraction_profiles:
conversation:
chunking_strategy: dialogue
entity_extraction: llm
content_type: text/plain
chunk_size: 512
fact_type: experience
metadata_mapping:
speaker: "$.participant_name"
tag_rules:
- match: { source: slack }
tags: [slack, chat]
Key Type Default Description
content_type string | null null Expected content type
chunking_strategy string | null null Strategy: sentence, paragraph, fixed, dialogue
chunk_size int | null null Max characters per chunk
entity_extraction bool | string | null null Extract entities: true, false, ner, llm
fact_type string | null null Default fact type: world, experience, observation
authority_tier string | null null Recall authority tier ID (overrides recall_authority.tier_by_bank)
metadata_mapping dict | null null Map source fields to metadata keys
tag_rules list[dict] | null null Generate tags from metadata patterns

Built-in profiles: builtin_text and builtin_conversation.


Standalone gateway settings — ignored in library mode.

deployment:
mode: standalone
host: "0.0.0.0"
port: 8000
workers: 4
cors_origins:
- "https://example.com"
- "http://localhost:3000"
tls:
cert_path: /path/to/cert.pem
key_path: /path/to/key.pem
Key Type Default Description
mode "library" | "standalone" | "plugin" "library" Deployment mode
host string | null null Bind address (standalone only)
port int | null null Port (standalone only)
workers int | null null Worker processes (standalone only)
cors_origins list[string] | null null CORS allowed origins
tls.cert_path string | null null TLS certificate path
tls.key_path string | null null TLS private key path

Pre-built compliance presets that configure barriers, lifecycle, access control, and DLP. Set compliance_profile at the top level — your explicit config overrides any values the profile sets.

Profile PII mode PII action Lifecycle Access default DLP
pdpa rules_then_llm redact 5-year retention owner_only Reflect output scanned
gdpr rules_then_llm redact 2-year retention deny Reflect output scanned
hipaa rules_then_llm reject 7-year retention deny Recall + reflect scanned

Any string value in astrocyte.yaml can reference environment variables with ${VAR_NAME}:

vector_store_config:
dsn: ${DATABASE_URL}
llm_provider_config:
api_key: ${OPENAI_API_KEY}
sources:
my-webhook:
auth:
secret: ${WEBHOOK_SECRET}

Unresolved variables (not set in the environment) are left as the literal string ${VAR_NAME}.


provider_tier: storage
vector_store: in_memory
llm_provider: mock
barriers:
pii:
mode: disabled

Production (pgvector + OpenAI + PDPA compliance)

Section titled “Production (pgvector + OpenAI + PDPA compliance)”
profile: personal
provider_tier: storage
vector_store: postgres
vector_store_config:
dsn: ${DATABASE_URL}
llm_provider: openai
llm_provider_config:
api_key: ${OPENAI_API_KEY}
model: gpt-4o-mini
compliance_profile: pdpa
mip_config_path: ./mip.yaml
lifecycle:
enabled: true
ttl:
archive_after_days: 90
delete_after_days: 365
access_control:
enabled: true
default_policy: owner_only