Motivation
AskMyDocs ships with safe defaults: a fresh install behaves like a competent hybrid-RAG service out of the box. But every enterprise deployment eventually needs to tune something — the embedding provider, the reranker’s trust gradient, the refusal threshold, the retention windows. This page is the map of what is configurable, where the knob lives, and what it does. It is not an exhaustive env dump (see.env.example for that) — it argues the knobs that
change behaviour you can observe.
Theory: configuration is layered, not flat
A knob is never read directly from the environment by a service. The flow is always env var →config/*.php cast + default → service constructor /
config() call. This indirection matters:
config/*.phpis the single source of truth for the default and the cast ((float),(bool),(int)). An unset env var is not “null” — it is the documented default.- Tests and
config:cacheread the compiled config, not$_ENV. Readingenv()outsideconfig/*.phpis a bug (it returnsnullonce config is cached).
The config files
Configuration is split by concern. The files you will touch most:| File | Owns |
|---|---|
config/ai.php | Chat + embeddings providers, models, cost rates, agentic/MCP tool-calling |
config/kb.php | Retrieval, chunking, reranking, canonical, graph, refusal gate, soft-delete, embedding cache |
config/askmydocs.php | Scheduler slots (cron + enable toggles), composite gates |
config/admin.php | Maintenance command allow-list, confirm-token TTL, audit retention |
config/chat-log.php | Chat logging driver + retention |
config/permission.php / config/rbac.php | Spatie roles, RBAC enforcement |
config/filesystems.php | KB disk (kb) + raw disk (kb-raw) |
connectors, mcp-pack, mcp, widget,
laravel-flow, pii-redactor-admin, eval-harness, ai-act-compliance,
evidence-risk-review, …) each ship their own config/*.php. See
Sister packages.
Providers (config/ai.php)
Chat and embeddings are configured independently — Anthropic has no
embeddings endpoint, so you mix providers freely.
<NAME>_API_KEY, <NAME>_CHAT_MODEL, <NAME>_TEMPERATURE,
<NAME>_MAX_TOKENS, and <NAME>_TIMEOUT, but the rest of the surface is
provider-specific — Anthropic adds ANTHROPIC_API_VERSION and has no
*_BASE_URL or embeddings model; OpenAI / Gemini / OpenRouter add *_BASE_URL
and *_EMBEDDINGS_MODEL; Regolo exposes a REGOLO_CHAT_MODEL* cheapest/smartest
matrix plus REGOLO_EMBEDDINGS_DIMENSIONS. The full per-provider matrix —
including the dimension-safety auto-select order when AI_PROVIDER=anthropic —
is documented in AI providers.
Retrieval & reranking (config/kb.php)
The reranker is the trust gradient — it fuses several signals into one
score, then applies a canonical boost and a status penalty. Defaults
(kb.reranking.* and kb.canonical.*):
| Knob | Env | Default | Effect |
|---|---|---|---|
| Candidate multiplier | KB_RERANK_CANDIDATE_MULTIPLIER | 3 | Over-retrieve 3× the limit, then rerank down |
| Vector weight | KB_RERANK_VECTOR_WEIGHT | 0.55 | Cosine similarity signal |
| Keyword weight | KB_RERANK_KEYWORD_WEIGHT | 0.25 | Lexical overlap signal |
| Heading weight | KB_RERANK_HEADING_WEIGHT | 0.05 | Heading-path match signal |
| Tag overlap | KB_RERANK_TAG_OVERLAP_WEIGHT | 0.05 | Source-aware tag overlap |
| Preamble match | KB_RERANK_PREAMBLE_WEIGHT | 0.05 | Frontmatter/preamble signal |
| Recency | KB_RERANK_RECENCY_WEIGHT | 0.02 | Newer docs slightly favoured |
| Status active | KB_RERANK_STATUS_WEIGHT | 0.02 | Active-status nudge |
| Mention boost | KB_RERANK_MENTION_BOOST_WEIGHT | 0.50 | @slug explicit mention boost |
| Canonical priority | KB_CANONICAL_PRIORITY_WEIGHT | 0.001 | Multiplies retrieval_priority (0–100) |
| Superseded penalty | KB_CANONICAL_SUPERSEDED_PENALTY | 0.40 | Demote superseded canonical docs |
| Deprecated penalty | KB_CANONICAL_DEPRECATED_PENALTY | 0.40 | Demote deprecated canonical docs |
| Archived penalty | KB_CANONICAL_ARCHIVED_PENALTY | 0.60 | Demote archived canonical docs |
| Auto-tier penalty | KB_CANONICAL_AUTO_TIER_PENALTY | 0.02 | Keep auto-compiled docs below human-curated |
The refusal gate
The anti-hallucination firewall refuses to answer when retrieval is too weak — better a refusal than a fabrication. Three thresholds, all inconfig/kb.php:
Graph expansion & rejected-approach injection
Both features degrade to no-ops when a tenant has zero canonical docs — an existing consumer sees identical retrieval until it canonicalises.Deletion, retention & multi-tenancy
KB_PROJECT_ISOLATION_ENABLED is default-off by design: the v8.9 isolation
audit shipped it opt-in so existing deployments keep their behaviour. Cross-tenant
isolation is always enforced (see multi-tenant isolation
and security & threat model).
Worked example: switch chat to a local-EU Regolo model, keep OpenAI embeddings
Gotchas & operations
config:cachein production,config:clearafter edits. Cached config ignores live.env.- Never call
env()outsideconfig/*.php. It returnsnullunderconfig:cache. - CSV env vars (
SANCTUM_STATEFUL_DOMAINS,CORS_ALLOWED_ORIGINS,KB_GRAPH_EXPANSION_EDGE_TYPES) are trimmed + filtered on parse — leading whitespace is tolerated, but keep them comma-separated with no stray quotes. - Default-off flags ship off. When you enable a flag (project isolation, PII redaction, agentic tool-calling, the MCP HTTP server), verify the enabled and disabled paths — both must be healthy (see feature-flag discipline).
Self-hosting
Install, migrate, build the SPA, run the worker + scheduler.
Scheduler & maintenance
Every scheduled job, its cron, and its enable toggle.
AI providers
The full provider matrix and the dimension-safety auto-select.
Troubleshooting
Embedding-dimension gotcha, health checks, common failures.