This guide covers the server deployment path for DiffScope when you want persistent reviews, analytics artifacts, trend history, and operational diagnostics.
- Use the Helm chart in
charts/diffscope/for long-running server deployments. - Use
docker-compose.ymlfor local CLI + Ollama workflows only. The compose file runsdiffscope review, notdiffscope serve. - The container image itself defaults to
serve, so Kubernetes/Helm is the intended self-hosted server path.
- Mount a persistent volume at
/home/diffscope/.local/share/diffscope. - Keep the working tree at
/workspacewhen you want server-side Git and PR workflows. - Set a shared API key with
DIFFSCOPE_SERVER_API_KEYfor protected mutation routes. - Point every persisted analytics artifact into the mounted data directory.
- Schedule
diffscope evalanddiffscope feedback-evalif you want trend charts to stay fresh.
The server persists and reads these files during normal operation:
| Purpose | Default path | Recommendation for Helm |
|---|---|---|
| Review/event storage | ~/.local/share/diffscope/reviews.json |
keep default |
| Learned conventions | ~/.local/share/diffscope/conventions.json |
keep default |
| Feedback store | .diffscope.feedback.json |
move under /home/diffscope/.local/share/diffscope/feedback.json |
| Eval trend history | .diffscope.eval-trend.json |
move under /home/diffscope/.local/share/diffscope/eval-trend.json |
| Feedback-eval trend history | .diffscope.feedback-eval-trend.json |
move under /home/diffscope/.local/share/diffscope/feedback-eval-trend.json |
| Production replay pack | ~/.local/share/diffscope/eval/production_replay/replay.json |
keep default |
| Failure forensics bundles | ~/.local/share/diffscope/forensics/... |
keep default |
The Helm PVC only covers /home/diffscope/.local/share/diffscope, so the relative default paths for feedback_path, eval_trend_path, and feedback_eval_trend_path are not durable unless you override them.
diffscope:
model: claude-opus-4-6
adapter: anthropic
baseUrl: https://api.anthropic.com
gitRepo:
enabled: true
repository: https://github.com/your-org/your-repo.git
branch: main
persistence:
enabled: true
size: 20Gi
config:
configFile: |
model: claude-opus-4-6
model_reasoning: openai/o3
providers:
anthropic:
enabled: true
openrouter:
enabled: true
feedback_path: /home/diffscope/.local/share/diffscope/feedback.json
eval_trend_path: /home/diffscope/.local/share/diffscope/eval-trend.json
feedback_eval_trend_path: /home/diffscope/.local/share/diffscope/feedback-eval-trend.json
retention:
review_max_age_days: 30
review_max_count: 1000
eval_artifact_max_age_days: 30
trend_history_max_entries: 200
extraEnv:
DIFFSCOPE_SERVER_API_KEY: ${DIFFSCOPE_SERVER_API_KEY}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY}Notes:
providers.<name>.api_keyand provider-specific environment variables are the recommended way to run mixed-provider installs.openai/o3and other non-Anthropicvendor/modelids route through OpenRouter unless you explicitly force another adapter.config.configFileis mounted at/workspace/.diffscope.yml; it is easiest to use withgitRepo.enabled: trueso the working directory already matches/workspace.
For enterprise installs, prefer external secret injection over storing credentials in .diffscope.yml.
ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYDIFFSCOPE_SERVER_API_KEYGITHUB_TOKENDIFFSCOPE_GITHUB_APP_IDDIFFSCOPE_GITHUB_PRIVATE_KEYDIFFSCOPE_JIRA_BASE_URLDIFFSCOPE_JIRA_EMAILDIFFSCOPE_JIRA_API_TOKENDIFFSCOPE_LINEAR_API_KEY
diffscope doctor, the server doctor endpoint, and startup warnings now surface configuration issues for:
- mixed-provider installs that still rely on legacy top-level
api_key/base_url/adapter - missing provider-specific API keys for selected cloud providers
- incomplete GitHub App config (
github_app_id+github_private_keymust be paired) - incomplete Jira config (
jira_base_url,jira_email,jira_api_tokenmust be paired) - incomplete Vault config (
vault_addr,vault_path,vault_token)
Vault currently resolves only the legacy top-level api_key. For multi-provider installs, use provider-specific secrets from your runtime environment or secret store injection.
/api/eventsand/api/events/statscome from stored reviews and wide events./api/analytics/learned-rulesreads the convention store./api/analytics/rejected-patternsreads the feedback store./api/analytics/trendsand/api/analytics/attention-gapsread the eval and feedback-eval trend JSON files.
Run these on a schedule against a persisted artifact directory:
diffscope eval --fixtures eval/fixtures --artifact-dir /var/lib/diffscope/eval
diffscope feedback-eval --input /home/diffscope/.local/share/diffscope/reviews.json --eval-report /var/lib/diffscope/eval/report.jsonretention.review_max_age_daysretention.review_max_countretention.eval_artifact_max_age_daysretention.trend_history_max_entries
Completed reviews apply review retention automatically. Eval artifact pruning happens when you run diffscope eval --artifact-dir ....
Use these protected endpoints after scoring or schema changes:
POST /api/analytics/recompute
GET /api/analytics/recompute/{job_id}
The recompute job refreshes stored review summaries and event aggregates. It does not rebuild eval or feedback-eval trend files.
diffscope doctorGET /api/statusGET /api/doctorGET /metrics- Helm
test-connection
DiffScope now writes JSON forensics bundles for degraded review and eval runs.
- Review bundles:
~/.local/share/diffscope/forensics/reviews/<review-id>/ - Eval bundles:
~/.local/share/diffscope/forensics/eval/...or<artifact-dir>/forensics/...
Review manifests are available from the protected endpoint:
GET /api/review/{id}/forensics
Accepted and rejected review outcomes are captured into an anonymized replay pack at:
~/.local/share/diffscope/eval/production_replay/replay.json
Run it with the normal eval command:
diffscope eval --fixtures ~/.local/share/diffscope/eval/production_replay