The Research Project Template provides two main entry points for pipeline operations:
run.sh- Main entry point for manuscript pipeline operations (interactive menu and flags)uv run python scripts/execute_pipeline.py --project {name} --core-only- Core pipeline viainfrastructure/core/pipeline/pipeline.yaml: 8 DAG stages (clean → copy) withllm-tagged stages removed. The default full run executes 10 core+LLM stages, while the YAML declares 12 stages including the opt-in bundle and archival contracts.
The Research Project Template follows a thin orchestrator pattern where all business logic resides in infrastructure/ and projects/{name}/src/ modules, while entry points and scripts act as lightweight coordinators.
flowchart TB
UI["User Interface<br/>run.sh / secure_run.sh → infrastructure.orchestration"]
ORCH["Orchestration Layer<br/>scripts/00_*.py … scripts/07_*.py → infrastructure<br/>projects/<name>/scripts/*.py → projects/<name>/src/"]
LOGIC["Business Logic<br/>infrastructure/ (reusable) + projects/<name>/src/ (custom)"]
UI -- delegates to --> ORCH
ORCH -- implements --> LOGIC
classDef ui fill:#1e3a8a,stroke:#0f172a,color:#fff
classDef orch fill:#0f766e,stroke:#0f172a,color:#fff
classDef logic fill:#7c2d12,stroke:#0f172a,color:#fff
class UI ui
class ORCH orch
class LOGIC logic
Layer 1: Entry Points (Thin Orchestrators)
run.sh/secure_run.sh: Bootstrapuv, thenexec uv run python -m infrastructure.orchestration(interactive menu, pipeline, multi-project, and secure subcommands)infrastructure.orchestration:PipelineRunnerwrappingPipelineExecutor; menu rendering inmenu.pyexecute_pipeline.py: Alternate non-interactive pipeline entry usingPipelineExecutordirectlyexecute_multi_project.py: Multi-project orchestration usingMultiProjectOrchestrator- Purpose: User interface and high-level coordination only
Layer 2: Stage Scripts (Thin Orchestrators)
scripts/00_*.py–scripts/09_*.py: Import frominfrastructure/for business logic (numbered entry points; script numbers are not pipeline stage indices —00–05cover the core stages,06_llm_review.pybacks the two[llm]stages,07_generate_executive_report.pyruns in multi-project mode, and08_executable_bundle.py/09_archive_publication.pyback the opt-in[bundle]/[archival]stages 10-11, which are declared inpipeline.yamlbut excluded from default runs)projects/{name}/scripts/*.py: Import fromprojects/{name}/src/for business logic- Purpose: Stage-specific coordination and I/O handling
Layer 3: Business Logic (Actual Implementation)
Live test and coverage totals: docs/_generated/COUNTS.md.
| Stage (default full run) | Root orchestrator | Primary infrastructure modules | Typical project script |
|---|---|---|---|
| 0 Clean outputs | built-in (PipelineExecutor) |
infrastructure.core.files |
— |
| 1 Environment setup | scripts/00_setup_environment.py |
infrastructure.project.discovery |
— |
| 2 Infrastructure tests | scripts/01_run_tests.py --infra-only |
infrastructure.core.test_runner |
— |
| 3 Project tests | scripts/01_run_tests.py --project-only |
infrastructure.core.test_runner |
— |
| 4 Project analysis | scripts/02_run_analysis.py |
infrastructure.core.pipeline |
projects/templates/<name>/scripts/*.py |
| 5 PDF rendering | scripts/03_render_pdf.py |
infrastructure.rendering |
optional render_*.py in project |
| 6 Output validation | scripts/04_validate_output.py |
infrastructure.validation |
— |
| 7–8 LLM stages | scripts/06_llm_review.py |
infrastructure.llm |
— |
| 9 Copy outputs | scripts/05_copy_outputs.py |
infrastructure.core.files |
— |
Qualified discovery names (templates/<name>, active/<name>) resolve under
projects/ via infrastructure.project.discovery.
infrastructure/: Generic, reusable algorithms and utilitiesprojects/{name}/src/: Project-specific scientific code and analysis- Purpose: All computational logic and algorithms
graph TD
A[User] --> B[run.sh or secure_run.sh]
B --> C[infrastructure.orchestration]
C --> D[PipelineRunner]
D --> E[PipelineExecutor]
E --> F[scripts/00_setup_environment.py]
E --> G[scripts/01_run_tests.py]
E --> H[scripts/02_run_analysis.py]
E --> I[scripts/03_render_pdf.py]
F --> J[infrastructure.core.runtime.environment]
G --> K[infrastructure.reporting.pipeline_test_runner]
H --> L[infrastructure.core.script_discovery]
I --> M[infrastructure.rendering]
L --> N["projects/{name}/scripts/*.py"]
N --> O["projects/{name}/src/"]
- Separation of concerns — clear boundaries between orchestration and computation
- Reusability — infrastructure modules work across all projects
- Testability — business logic isolated and thoroughly tested
- Maintainability — changes to algorithms do not affect orchestration
- Extensibility — new projects inherit infrastructure
Correct: thin orchestrator pattern
# scripts/03_render_pdf.py (orchestrator)
from infrastructure.rendering import RenderManager
def run_render_pipeline():
renderer = RenderManager() # Import business logic
pdf = renderer.render_pdf("manuscript.tex") # Delegate computation
return validate_output(pdf) # Orchestrate validationIncorrect: violates architecture
# scripts/03_render_pdf.py (WRONG - implements logic)
def render_pdf_to_tex(content):
# Business logic in orchestrator - WRONG!
lines = content.split('\n')
tex_lines = []
for line in lines:
if line.startswith('# '):
tex_lines.append(f'\\section{{{line[2:]}}}')
# ... complex rendering logic ...
return '\n'.join(tex_lines)The template now supports multiple research projects in a single repository. You can:
- Run individual projects:
./run.sh --project <name> --pipeline - Run all projects sequentially:
./run.sh --all-projects --pipeline - Interactive project selection:
./run.sh(shows menu of available projects)
Projects are discovered dynamically from projects/ (see infrastructure.project.discovery.discover_projects()). Authoritative names: _generated/active_projects.md (see _generated/README.md for policy and regeneration). Examples in this guide use template_code_project as the stable control-positive layout under projects/.
Archived and in-progress work lives under projects/archive/ and
projects/working/ and is not executed by default ./run.sh discovery. Render
it explicitly with a qualified name such as --project working/<name>, or
deliberately restore it through optional sidecar active/ when it should appear
in the normal menu.
Private work normally lives in the sibling repo configured by
$TEMPLATE_PRIVATE_PROJECTS_ROOT. The simplified sidecar uses working/ and
archive/ by default; optional legacy active/, published/, and other/
folders are still linked when present. run.sh auto-syncs existing lifecycle
folders into matching template/projects/<subfolder>/ symlinks before
discovery. Use
uv run python -m infrastructure.orchestration link-projects --dry-run to
preview link changes, TEMPLATE_PRIVATE_PROJECTS_ROOT or
.private_projects_root to override the sibling repo, and
TEMPLATE_SKIP_LINK_SYNC=1 to skip auto-sync for a command.
# Interactive project selection
./run.sh
# Run specific project
./run.sh --project template_code_project --pipeline
# Run all projects sequentially
./run.sh --all-projects --pipeline
# Alternative orchestrator (all projects)
uv run python scripts/execute_multi_project.pyrun.sh is a thin bootstrap shell: it sources scripts/shell_bootstrap.sh,
then exec uv run python -m infrastructure.orchestration. Bare ./run.sh
opens the interactive menu; uv run syncs the workspace on demand. Invocations
with pipeline flags also run uv sync when .venv is missing.
For pipeline + steganography, use ./secure_run.sh --project <name> or
./run.sh --secure-run --project <name> (see
docs/security/secure_execution.md).
Both run.sh and secure_run.sh source
scripts/shell_bootstrap.sh only — not
scripts/bash_utils.sh (operational backup/health scripts).
| Helper | Role |
|---|---|
setup_orchestration_sandbox_env |
Sets MPLCONFIGDIR and UV_CACHE_DIR under $TMPDIR for headless/cache-safe runs |
ensure_uv |
Locates or installs uv (quiet; no colored logging) |
print_uv_install_instructions |
Prints install guidance when uv is unavailable |
run.sh-specific behaviour:
- Internal
PIPELINE_MODE(bash-local, not exported) triggers conditionaluv syncwhen.venvis missing on pipeline-capable flags. - Argv shaping:
--pipeline/--all-projects→ prependpipelinesubcommand;--secure-run→ prependsecure; other flags forward verbatim topython -m infrastructure.orchestration. FEP_LEAN_GAUSS_WORKFLOWS: defaults to1;--no-lean-workflowssets it to0.
secure_run.sh-specific behaviour:
- Always runs
uv sync --group steganographybefore exec (except--helpfast path). - No args → exit 2 with quick-start stderr;
--helpskips stego sync. - Forwards all flags (including
--deterministic) to the Pythonsecuresubcommand.
./run.shThe menu is rendered by render_menu() (template_code_project shown as an example project name):
+========================================================================+
| MANUSCRIPT PIPELINE · thin orchestrator template |
| project > template_code_project |
+========================================================================+
Single stages 0-7 · Presets 8 / 9 / f · Multi a-d · p · i · q
Keys 0-5: setup, tests, analysis, render, validate, copy | 6-7: LLM (Ollama) | 8/9/f: pipelines | a-d: all projects
Flow: [0..5] script chain + (6,7) LLM | 8/9/f DAG presets | a-d multi-project
-- INDIVIDUAL STAGES - one script per key --------------------------------
0 | Environment Setup | 00_setup_environment.py
1 | Run Tests | 01_run_tests.py (infra + project)
2 | Run Analysis | 02_run_analysis.py
3 | Render PDF | 03_render_pdf.py
4 | Validate Output | 04_validate_output.py
5 | Copy Outputs | 05_copy_outputs.py
6 | LLM Review | 06_llm_review.py reviews (Ollama)
7 | LLM Translations | 06_llm_review.py translations (Ollama)
-- ORCHESTRATION - full DAG, current project -----------------------------
8 | Core Pipeline | current project · infra on · LLM off · 8 stages
9 | Full Pipeline | current project · infra on · LLM on · 10 stages
f | Full Pipeline (fast) | current project · skip infra · LLM on
-- MULTI-PROJECT - every discovered project ------------------------------
a | All projects full | all projects · infra on · LLM on · report
b | All projects full (fast) | all projects · skip infra · LLM on · report
c | All projects core | all projects · infra on · LLM off · report
d | All projects core (fast) | all projects · skip infra · LLM off · report
-- PROJECT ---------------------------------------------------------------
p | Change Project
i | Show Project Info
q | Quit
--------------------------------------------------------------------------
Infra tests: Layer-1 pytest (tests/infra_tests/), then project tests.
LLM: optional Ollama stages; pipeline skips them when Ollama is unavailable.
Executive report: written after all projects finish (keys a-d only).
--------------------------------------------------------------------------
Tip: chain stage digits (e.g. 234 = analyze -> render -> validate); comma or space also work.
use p to switch project · i for current name · q to quit.
After the menu, the interactive loop prints a one-line key legend, a blank line, then Choice: before reading input. Choosing p prints the project list to stdout and then Choice [index / a=all / q=quit]: before reading the picker line.
Progress logs use a pre-step [0/9] Clean Output Directories, then [1/9] through [9/9] for the nine tracked steps in the default core+LLM path (see STAGE_NAMES in infrastructure/orchestration/menu.py; run.sh is a thin shell dispatcher into infrastructure.orchestration). The Python executor follows pipeline.yaml, which declares 12 stages total: 8 core, 2 optional LLM, and 2 opt-in bundle/archival stages.
Verifies the environment is ready for the pipeline.
- Checks Python version (requires >=3.10)
- Verifies dependencies are installed
- Confirms build tools (pandoc, xelatex) are available
- Validates directory structure
- Sets up environment variables
Executes the test suite with coverage validation.
- Runs infrastructure tests (
tests/infra_tests/) with 60%+ coverage threshold - Runs project tests (
projects/{name}/tests/) with 90%+ coverage threshold - Generates HTML coverage reports for both suites
- Generates structured test reports (JSON, Markdown)
Coverage Reports: htmlcov/index.html
Executes project analysis scripts with progress tracking.
- Discovers scripts in
projects/{name}/scripts/ - Executes each script in order with progress tracking
- Collects outputs to
projects/{name}/output/
Generates manuscript PDFs with progress tracking.
- Processes
projects/{name}/manuscript/markdown files - Converts to LaTeX via pandoc
- Compiles to PDF via xelatex
- Also runs analysis scripts first (option 2)
Output: projects/{name}/output/pdf/
Validates build quality with reporting.
- Checks generated PDFs for issues
- Validates markdown references
- Checks figure integrity
- Generates validation reports (JSON, Markdown)
Copies final deliverables into the repo-level output/{name}/ tree (and related publishing outputs per project settings).
Generates AI-powered manuscript reviews using local Ollama LLM.
- Checks Ollama availability and selects best model
- Extracts full text from combined PDF manuscript
- Generates executive summary, quality review, methodology review, and improvement suggestions
- Saves all reviews to
projects/{name}/output/llm/
Requires: Running Ollama server with at least one model installed. Skips gracefully if unavailable.
Generates multi-language technical abstract translations.
- Translates abstract to configured languages (see
projects/{name}/manuscript/config.yaml) - Uses local Ollama LLM for translation
- Saves translations to
projects/{name}/output/llm/
Requires: Running Ollama server and translation configuration in config.yaml.
Runs execute_pipeline.py with --core-only (default pipeline.yaml: 8 stages, no LLM-tagged steps).
- Stops on first failure with clear error messages
- Suitable for CI/CD environments
Runs the full default DAG (10 stages in pipeline.yaml, including clean, both LLM stages, and copy).
- LLM stages are optional at runtime (exit code 2 skip) if Ollama is unavailable
- Bash progress lines use
[0/9]for clean, then[1/9]–[9/9]for the nine entries inSTAGE_NAMESininfrastructure/orchestration/menu.py(see menu block above)
Same as full pipeline but skips infrastructure tests (--skip-infra / fast path in run.sh).
# Core Build Operations
./run.sh --pipeline # Full DAG (10 stages in pipeline.yaml; bash shows [0/9] clean + [1/9]–[9/9] tracked steps)
./run.sh --pipeline --resume # Resume from last checkpoint
uv run python scripts/01_run_tests.py --infra-only # Run infrastructure tests only
uv run python scripts/01_run_tests.py --project-only # Run project tests only
uv run python scripts/03_render_pdf.py --project {name} # Render PDF manuscript only
# LLM Operations (requires Ollama)
uv run python scripts/06_llm_review.py --reviews-only # LLM manuscript review only (English)
uv run python scripts/06_llm_review.py --translations-only # LLM translations only
# Show help
./run.sh --helpFor programmatic access or CI/CD integration, use the Python orchestrator:
# Core pipeline (8 DAG stages in default pipeline.yaml — excludes LLM-tagged stages)
uv run python scripts/execute_pipeline.py --project {name} --core-onlyFeatures:
- Eight DAG stages by default: clean → setup → infrastructure tests → project tests → analysis → PDF → validation → copy. Omit infrastructure tests with
--skip-infra(seven stages). - No LLM-tagged stages (
06_llm_review.py/07_generate_executive_report.pyare not part of--core-only;07is for multi-project executive reporting) - No LLM dependencies required for
--core-only - Suitable for automated environments
- Checkpoint/resume support:
uv run python scripts/execute_pipeline.py --project {name} --core-only --resume
The canonical pipeline-stage table (rendered from pipeline.yaml):
| Stage | Script | Tags | Failure mode |
|---|---|---|---|
| 0 Clean Output Directories | built-in _run_clean_outputs |
core, clean |
soft fail |
| 1 Environment Setup | 00_setup_environment.py |
core |
hard fail |
| 2 Infrastructure Tests | 01_run_tests.py --infra-only --verbose --infra-scope pipeline-smoke |
core, tests |
configurable tolerance |
| 3 Project Tests | 01_run_tests.py --project-only --verbose |
core, tests |
configurable tolerance |
| 4 Project Analysis | 02_run_analysis.py |
core |
hard fail |
| 5 PDF Rendering | 03_render_pdf.py |
core |
hard fail |
| 6 Output Validation | 04_validate_output.py |
core |
warning + report |
| 7 LLM Scientific Review | 06_llm_review.py --reviews-only |
llm |
skipped if Ollama absent |
| 8 LLM Translations | 06_llm_review.py --translations-only |
llm |
skipped if Ollama absent |
| 9 Copy Outputs | 05_copy_outputs.py |
core |
soft fail |
| 10 Executable Bundle | 08_executable_bundle.py |
bundle |
soft fail |
| 11 Archival Publication | 09_archive_publication.py |
archival |
soft fail |
The table above lists pipeline-position indices (0-based, as the executor sees them); the table below maps script filename prefixes to their high-level purpose:
| Script | Purpose |
|---|---|
00_setup_environment.py |
Environment setup & validation |
01_run_tests.py |
Run test suite (infrastructure + project) |
02_run_analysis.py |
Discover & run projects/{name}/scripts/ |
03_render_pdf.py |
PDF rendering orchestration |
04_validate_output.py |
Output validation & reporting |
05_copy_outputs.py |
Copy final deliverables to output/ |
06_llm_review.py |
LLM manuscript review & translations (optional, requires Ollama) |
07_generate_executive_report.py |
Executive summaries & dashboards (multi-project only) |
--core-only runs the executor stages through copy outputs and does not run 06 or 07; those are optional or multi-project entry points.
| Entry Point | Pipeline Stages | LLM Support | Use Case |
|---|---|---|---|
./run.sh |
Main entry point | Optional | Interactive menu or manuscript pipeline with LLM |
./run.sh --pipeline |
Full DAG (10 stages in default pipeline.yaml) |
Optional | Manuscript pipeline with LLM stages present in the graph |
./run.sh --secure-run |
Same as ./secure_run.sh via argv shaping |
Optional | Secure subcommand from the main thin shell |
./secure_run.sh |
Full/core DAG + steganography | Optional | Dedicated secure entry; always uv sync --group steganography |
uv run python scripts/execute_pipeline.py --project {name} --core-only |
Core DAG (8 stages; LLM stages omitted) | None | Core pipeline, CI/CD automation |
uv run python scripts/run_matrix.py |
Exactly the (project, stage) pairs declared in run.config |
Per stage | Reproducible subset runs across several projects |
The deterministic, version-controllable alternative to the interactive menu.
A top-level run.config (YAML) declares a matrix of projects × stages — the
exact subset of the pipeline to run, for exactly which projects. Stages always
execute in canonical pipeline order (analysis before render, etc.) regardless of
how they are listed, so a given run.config reproduces the same run every time.
# Uses ./run.config (or run.config.yaml). See run.config.example.yaml.
uv run python scripts/run_matrix.py
uv run python scripts/run_matrix.py --dry-run # print the resolved plan, run nothing
uv run python scripts/run_matrix.py --fail-fast # stop at the first failing stage
uv run python scripts/run_matrix.py --config path/to/other.yamlrun.config schema (see run.config.example.yaml):
version: 1
defaults:
stages: [setup, project_tests, analysis, render_pdf, validate, copy]
runs:
- project: templates/template_code_project # qualified, bare, or sidecar path
- project: working/my_paper
stages: [render_pdf, validate] # overrides defaultsA project reference may be a qualified name (templates/template_code_project),
a bare name (resolved to its canonical location), or a sidecar path stem
(working/my_paper); path traversal is rejected. Valid stage keys match
execute_pipeline.py --stage. The user's run.config is git-ignored (it may
reference private working/ projects); only run.config.example.yaml is tracked.
./run.sh # main dispatcher (project menu + pipeline options)# Run manuscript pipeline
./run.sh --pipeline
# Resume manuscript pipeline from checkpoint
./run.sh --pipeline --resume
# Run core pipeline (Python)
uv run python scripts/execute_pipeline.py --project {name} --core-onlyIndividual stages can also be run directly via Python:
uv run python scripts/00_setup_environment.py # Setup environment
uv run python scripts/01_run_tests.py --project {name} # Run tests only
uv run python scripts/01_run_tests.py --project {name} --verbose # Run tests with verbose output
uv run python scripts/02_run_analysis.py --project {name} # Run project scripts
uv run python scripts/03_render_pdf.py --project {name} # Render PDFs only
uv run python scripts/04_validate_output.py --project {name} # Validate outputs only
uv run python scripts/05_copy_outputs.py --project {name} # Copy final deliverables
uv run python scripts/06_llm_review.py --project {name} # LLM manuscript review
uv run python scripts/06_llm_review.py --project {name} --reviews-only # Reviews only
uv run python scripts/06_llm_review.py --project {name} --translations-only # Translations only- 0: Operation succeeded
- 1: Operation failed - review errors and fix issues
- 2: Operation skipped (e.g., Ollama not available for LLM review)
Root entry shells (run.sh, secure_run.sh) do not export PROJECT_ROOT or
PYTHONPATH. Pipeline stages set runtime paths via
set_environment_variables()
and the test runner adds project src/ when needed.
You can override logging or render toggles before running:
export LOG_LEVEL=0 # Enable debug logging
./run.sh --pipeline| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
1 |
0=DEBUG 1=INFO 2=WARN 3=ERROR |
NO_EMOJI |
unset | Set to disable emoji in output |
STRUCTURED_LOGGING |
unset | Set to emit JSON log lines |
LOG_TERMINAL_VERBOSE |
unset | Restore the verbose [ts] [LEVEL] msg prefix on the terminal (the file always has it) — see operational/logging/output-design.md |
Format toggles default to PDF/HTML/Slides on, DOCX/EPUB off. Set
in projects/{name}/manuscript/config.yaml under render.formats, or
override per-run via env (env precedence beats yaml):
| Variable | Type | Default | Effect |
|---|---|---|---|
ENABLE_PDF |
0/1,true/false,yes/no |
1 |
Combined PDF + per-section LaTeX/PDF |
ENABLE_HTML |
same | 1 |
Combined HTML index + per-section HTML |
ENABLE_SLIDES |
same | 1 |
Per-section Beamer PDFs |
ENABLE_DOCX |
same | 0 |
Combined Word document (output/<project>/docx/) |
ENABLE_EPUB |
same | 0 |
Combined EPUB (output/<project>/epub/) |
See usage/output-formats.md for the full
configuration matrix.
| Variable | Default | Description |
|---|---|---|
LLM_MAX_INPUT_LENGTH |
500000 |
Max chars to send to LLM. Set to 0 for unlimited. |
LLM_REVIEW_TIMEOUT |
300 |
Timeout per review in seconds |
LLM_LONG_MAX_TOKENS |
16384 |
Maximum tokens per review response |
The scripts use strict error handling:
- Stops immediately on first failure
- Provides clear error messages
- Shows which stage/operation failed
- Returns to menu after each operation (interactive mode)
Example error output:
✗ Infrastructure tests failed
Operation completed in 45s
Press Enter to return to menu...
Make the script executable:
chmod +x run.shVerify each project has projects/<name>/tests/conftest.py with path bootstrap for that project's src/ (and template root when needed). Do not rely on a repository-root conftest.py for project imports.
Check pyproject.toml [tool.coverage.report] for coverage thresholds. Increase test coverage in tests/ and projects/{name}/tests/.
Ensure pandoc and xelatex are installed:
# macOS
brew install pandoc
brew install --cask mactex
# Ubuntu/Debian
sudo apt-get install -y pandoc texlive-xetex texlive-fonts-recommendedFor manuscripts that use pandoc-crossref syntax (@sec:…, @tbl:…, @fig:…), install the filter so it appears on PATH (the PDF combined renderer passes --filter when found). Example on macOS: brew install pandoc-crossref. If the binary is missing, the build still succeeds; cross-reference tokens are not expanded until the filter is installed.
Ensure Ollama is running:
# Start Ollama server
ollama serve
# Install a model (if needed)
ollama pull llama3-gradientscripts/README.md— Stage orchestratorsscripts/AGENTS.md—scripts/technical guideAGENTS.md— Documentation hub (docs/)../AGENTS.md— Repository system referenceCLOUD_DEPLOY.md— Headless / cloud server deploymentcore/workflow.md— Development workflow
For a fresh headless server (Ubuntu/Debian), all dependencies including uv are installed
automatically when you invoke any non-interactive pipeline flag:
# 1. Install system deps (LaTeX + git + curl)
sudo apt-get update && sudo apt-get install -y \
curl git python3 pandoc \
texlive-xetex texlive-latex-extra texlive-fonts-recommended
# 2. Clone the repository
git clone https://github.com/docxology/template.git && cd template
# 3. Run — uv is installed automatically, .venv is synced
./run.sh --pipelineThe MPLBACKEND=Agg environment variable is required on headless servers (no display):
export MPLBACKEND=Agg
./run.sh --pipelineFull guide: see
CLOUD_DEPLOY.mdfor system prerequisites, optional dependency groups, Docker alternative, Ollama setup, and troubleshooting.