Configuration¶
JSAT configuration lives in .jsat/config.yaml inside your project root (the canonical location). All JSAT state is co-located under .jsat/ to keep your repo root clean.
Config File Locations¶
JSAT searches for a config file in this order (first found wins):
- Explicit
--configCLI flag orconfig=SDK argument $JSAT_CONFIGenvironment variable{repo}/.jsat/config.yaml— canonical (recommended){repo}/.jsat.yaml— legacy fallback./.jsat/config.yaml— CWD canonical./.jsat.yaml— CWD legacy~/.config/jsat/config.yaml— user global/etc/jsat/config.yaml— system global
If no config file is found, JSAT uses built-in defaults and auto-detects everything.
Generate a Starter Config¶
jsat init --profile solo # recommended for individual devs
jsat init --profile team # for teams with Neo4j + Redis
jsat init --profile ci # for CI pipelines
jsat init --profile raspberry-pi # for low-RAM ARM devices
Full Config Reference¶
version: "1"
project_name: my-project
project_root: "."
# ── Graph backend ──────────────────────────────────────────────────────────────
graph:
backend: sqlite # "sqlite" | "neo4j" | "lightgraph"
path: .jsat/graph/graph.db # SQLite database path (relative to repo root)
remote_uri: null # Neo4j: "bolt://localhost:7687"
username: neo4j # Neo4j username
password_env: NEO4J_PASSWORD # env var holding the Neo4j password
max_nodes: 5000000
max_edges: 20000000
# ── Embeddings ─────────────────────────────────────────────────────────────────
embeddings:
provider: local # "local" | "openai" | "huggingface" | "none"
model: nomic-embed-code # local model name or OpenAI model
api_key_env: OPENAI_API_KEY # env var for embedding API key
dimensions: 768
batch_size: 64
vector_store:
backend: sqlite-vss # "sqlite-vss" | "qdrant" | "pgvector"
path: .jsat/vectors/ # local vector store directory
remote_uri: null # Qdrant: "http://localhost:6333"
collection: jsat_code
api_key_env: QDRANT_API_KEY
# ── AI provider ────────────────────────────────────────────────────────────────
ai:
provider: ollama # "ollama" | "anthropic" | "openai" | "openai_compat" | "none"
model: llama3.2
api_key_env: null # env var name, e.g. ANTHROPIC_API_KEY (read automatically)
base_url: null # for openai_compat (LM Studio, Gemini, custom)
max_tokens: 8192
temperature: 0.1
timeout_seconds: 120
retry_attempts: 3
# ── Cache ──────────────────────────────────────────────────────────────────────
cache:
enabled: true
backend: memory # "memory" | "disk" | "redis"
redis_uri: null # "redis://localhost:6379"
similarity_threshold: 0.95 # semantic dedup threshold
ttl_seconds: 3600
max_memory_mb: 512
disk_path: .jsat/cache/
# ── Indexer ────────────────────────────────────────────────────────────────────
indexer:
languages:
- python
- javascript
- go
exclude_patterns:
- .git
- node_modules
- __pycache__
- .venv
- vendor
- dist
- build
incremental: true # only re-index changed files
git_hooks: true # auto-index on git commit
max_file_size_kb: 500
follow_symlinks: false
embedding_batch_size: 64
# ── MCP server ─────────────────────────────────────────────────────────────────
mcp:
mode: embedded # "embedded" | "server"
port: 8765
auth: false # require JSAT_MCP_TOKEN header
auth_token_env: JSAT_MCP_TOKEN
# ── IThinking ─────────────────────────────────────────────────────────────────
ithinking:
enabled: true
mode: interactive # "interactive" | "silent" | "report-only"
prompt_review: true # pause for human review of the plan
decomposition_review: true # pause at decomposition step
assumption_audit: true # run assumption audit before execution
local_first: true # prefer local computation over LLM when possible
gate_level: medium # "low" | "medium" | "high"
reflection: true # generate phase 6 reflection
knowledge_update: true # update knowledge base after tasks
# ── Logging ────────────────────────────────────────────────────────────────────
log:
level: INFO # "DEBUG" | "INFO" | "WARNING" | "ERROR"
format: text # "text" | "json"
file: null # optional log file path
# ── Skills ─────────────────────────────────────────────────────────────────────
skills:
dir: skills/
auto_discover: true
override_builtins: true
clusters: {}
# ── Review ─────────────────────────────────────────────────────────────────────
review:
models:
- {provider: claude_cli, model: claude-sonnet-4-6}
- {provider: ollama, model: qwen2.5-coder:7b}
parallel_timeout_seconds: 90 # wall-clock deadline per model; exceeded models are skipped
min_confidence: medium # "low" | "medium" | "high"
# ── Prompt Optimizer ───────────────────────────────────────────────────────────
prompt:
enabled: true # auto-optimize all shell messages
mode: auto # "auto" | "always" | "never"
max_context_tokens: 8192 # max tokens allocated to injected graph context
few_shot_k: 3 # number of few-shot examples to inject
compress_threshold: 6000 # enable token compression above this count
context_depth: 2 # BFS depth for graph context injection
cot_tasks: [debug, plan, security] # task types that get chain-of-thought appended
history_path: .jsat/prompt-history.jsonl
history_max_entries: 10000
# ── Security ───────────────────────────────────────────────────────────────────
security:
cvss_threshold: medium # "low" | "medium" | "high" | "critical"
secret_entropy_threshold: 3.5 # Shannon entropy threshold for secret detection
# ── Privacy ────────────────────────────────────────────────────────────────────
privacy:
hash_pii: false # hash PII values before storing in the graph
audit_log: false # write an audit log of all JSAT operations
audit_log_path: .jsat/audit.log
Profiles¶
solo — Individual Developer¶
Good default for a single developer on a laptop. Uses SQLite (no services required) and Ollama for local AI. Embeddings with nomic-embed-code.
version: "1"
project_name: my-project
graph:
backend: sqlite
embeddings:
provider: local
model: nomic-embed-code
vector_store:
backend: sqlite-vss
ai:
provider: ollama
model: llama3.2
cache:
backend: memory
ithinking:
mode: interactive
gate_level: medium
Run:
team — Engineering Team¶
For teams with shared infrastructure. Uses Neo4j for the graph, Qdrant for vector search, Redis for caching, and the Anthropic API for AI.
version: "1"
project_name: my-project
graph:
backend: neo4j
remote_uri: bolt://localhost:7687
password_env: NEO4J_PASSWORD
embeddings:
provider: openai
model: text-embedding-3-small
vector_store:
backend: qdrant
remote_uri: http://localhost:6333
ai:
provider: anthropic
model: claude-sonnet-4-6
cache:
backend: redis
redis_uri: redis://localhost:6379
ithinking:
mode: interactive
gate_level: high
Run:
Requires pip install jsat[team] and Neo4j, Qdrant, and Redis running locally or in your infrastructure.
ci — Continuous Integration¶
For CI pipelines. No AI calls, memory-only cache, JSON log format for structured log ingestion, IThinking disabled.
version: "1"
project_name: my-project
graph:
backend: sqlite
embeddings:
provider: none
ai:
provider: none
cache:
backend: memory
ithinking:
enabled: false
mode: silent
log:
level: WARNING
format: json
Run:
When CI=true is set in the environment, JSAT automatically applies these overrides even without a config file.
raspberry-pi — Low-RAM ARM¶
For ARM devices with limited RAM (Raspberry Pi, older Apple M-series, similar). Uses phi3:mini (2 GB), smaller batch sizes, and disk cache.
version: "1"
project_name: my-project
graph:
backend: sqlite
embeddings:
provider: local
model: nomic-embed-code
dimensions: 384
batch_size: 8
vector_store:
backend: sqlite-vss
ai:
provider: ollama
model: phi3:mini
cache:
backend: disk
indexer:
embedding_batch_size: 8
max_file_size_kb: 100
ithinking:
mode: silent
gate_level: low
Run:
Key Sections Explained¶
graph¶
Controls where the codebase graph is stored.
sqlite— default, zero setup, all data in.jsat/graph/graph.dbneo4j— for teams; supports shared access, complex graph querieslightgraph— in-memory, for testing only
For Neo4j:
graph:
backend: neo4j
remote_uri: bolt://localhost:7687
username: neo4j
password_env: NEO4J_PASSWORD # read from env at runtime
Never put the Neo4j password directly in the config file.
embeddings¶
Controls how code is embedded for semantic search.
local— uses Ollama to embed locally withnomic-embed-codeopenai— usestext-embedding-3-smallvia the OpenAI APInone— skips embedding (no semantic search, graph queries only)
For CI or low-resource environments, set provider: none to skip embedding entirely.
ai¶
Controls which AI model answers natural language queries.
Do not put API keys here. Use environment variables:
For LM Studio or a custom OpenAI-compatible server:
cache¶
Semantic caching: identical or near-identical queries are served from cache without an LLM call.
memory— fast, lost on restartdisk— persists across restarts, stored in.jsat/cache/redis— shared cache for teams
similarity_threshold: 0.95 means queries with cosine similarity >= 0.95 are considered equivalent and served from cache.
mcp¶
Controls the MCP server used by Claude Code and Cursor.
mode: embedded— default; the MCP server runs as a subprocess started by the IDEmode: server— run JSAT as a long-running HTTP MCP server (not yet fully implemented)auth: true— requireJSAT_MCP_TOKENin the request header
ithinking¶
Controls structured planning behavior.
mode: interactive— pauses for human review before executing complex tasksmode: silent— never pauses; plans are generated internally but not shownmode: report-only— always shows the plan but never pauses
gate_level controls how aggressively the framework triggers:
low— triggers on all tasksmedium— triggers on medium+ complexity taskshigh— triggers only on high-complexity tasks
log¶
Controls structlog output.
level: DEBUG— verbose, useful for developmentformat: json— structured JSON logs, useful in CI and for log aggregation toolsfile: /var/log/jsat.log— additionally write logs to a file
review¶
Controls multi-model parallel code review (Tool 9 — MultiModelReview).
models— list of provider/model pairs to dispatch the diff to simultaneously. Each entry must specify aprovider(claude_cli,ollama,anthropic,openai,openai_compat) and amodelname.parallel_timeout_seconds— wall-clock deadline applied to every model dispatch. Models that exceed this are skipped; their timeout is recorded as a warning in the review output.min_confidence— controls which findings are surfaced:low— any single model's findingmedium— confirmed by 2 or more models (default)high— confirmed by all configured models
Do not put API keys in the models list. Keys are read from environment variables as usual (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.).
prompt¶
Controls the 7-stage prompt optimization pipeline. Auto-optimization rewrites every shell message before sending it to the AI — injecting codebase context, constraints, few-shot examples, and model-specific formatting.
enabled: true— turn auto-optimization on or off globally. Whenfalse, messages are sent as typed.mode— when optimization runs:auto— optimize only when the raw prompt is belowmax_context_tokensand the task classifier assigns a non-trivial labelalways— optimize every message unconditionallynever— disable the pipeline (equivalent toenabled: false)max_context_tokens— maximum tokens that can be consumed by injected graph context (stage 2). Larger values inject more codebase context but increase LLM cost.few_shot_k— number of past prompt/response pairs to inject as few-shot examples (stage 4). Set to0to disable few-shot injection.compress_threshold— if the assembled prompt exceeds this token count, stage 7 (token compression) activates. Lower values compress more aggressively; higher values leave prompts unchanged unless they are very large.context_depth— BFS depth used when traversing the codebase graph for context injection. Depth 1 includes only direct neighbors; depth 2 includes neighbors-of-neighbors. Higher values surface more context but increase token usage.cot_tasks— list of task types that automatically get chain-of-thought appended. Recognized values:debug,plan,security,review,refactor,code_gen,test,question.history_path— JSONL file where every prompt/response pair is appended for future few-shot retrieval.history_max_entries— maximum entries kept in the history file. Older entries are evicted when this limit is reached.
Set enabled: false or mode: never in the ci profile to skip optimization in pipelines where deterministic, unmodified prompts are required.
security¶
Controls thresholds for the SecurityReview tool.
cvss_threshold— minimum CVSS severity level to report in dependency CVE scans:low,medium,high, orcritical. Findings below this threshold are suppressed.secret_entropy_threshold— Shannon entropy value above which a string literal is flagged as a potential hardcoded secret. The default of3.5catches most API keys, tokens, and base64-encoded values while reducing false positives on normal strings. Lower values increase sensitivity; higher values reduce noise.
privacy¶
Controls how JSAT handles potentially sensitive data in the graph and logs.
hash_pii: true— before storing any value extracted from source code that matches a PII pattern (email addresses, phone numbers, national IDs), JSAT replaces the raw value with a SHA-256 hash. This prevents PII from being stored in the graph or sent to an LLM.audit_log: true— write a structured audit log of every JSAT operation (index, query, review, knowledge write, MCP tool call) toaudit_log_path. Each entry includes a timestamp, operation type, user identity (if available), and a summary of inputs/outputs with sensitive values redacted.audit_log_path— path to the audit log file (relative to repo root). Default:.jsat/audit.log.
Neither setting is enabled by default. Enable both in regulated environments or wherever a record of AI-assisted operations is required for compliance.
Environment Variables¶
All secrets should be passed via environment variables, never stored in config:
| Variable | Purpose |
|---|---|
JSAT_CONFIG |
Override config file path |
ANTHROPIC_API_KEY |
Anthropic API key |
OPENAI_API_KEY |
OpenAI API key |
GEMINI_API_KEY |
Gemini API key (GOOGLE_API_KEY also accepted) |
NEO4J_PASSWORD |
Neo4j password (key name configurable via password_env) |
QDRANT_API_KEY |
Qdrant API key (key name configurable via api_key_env) |
JSAT_MCP_TOKEN |
MCP server auth token |
CI |
If true/1/yes, forces CI profile overrides |