This project keeps source in the Fossil checkout and runtime state outside it.
Paths
Default runtime root:
/var/lib/ollama-codex
Override it for tests or alternate deployments:
export OLLAMA_CODEX_RUNTIME_ROOT=/path/to/runtime
The application uses these subdirectories:
sessions: reserved for future app-local sessions.transcripts: chat transcript JSON files.tasks: file-backed queue records grouped by status.logs: worker stdout, stderr, prompt, report, event, and Fossil status snapshots.artifacts: reserved for completed task artifacts.
Ownership
For the current single-host deployment, the Fossil server and task worker run as the operator-controlled service user. Create and own the runtime root with that same account:
mkdir -p /var/lib/ollama-codex
chown -R <service-user>:<service-group> /var/lib/ollama-codex
chmod 750 /var/lib/ollama-codex
Do not make the runtime root world-writable. Task logs may contain prompts, command output, and repository paths.
Runtime Binaries
shards build compiles a single binary bin/ollama-codex with bootstrap
capability only. Asset-dependent features (agent docs, stdlib lookup, docs CGI)
require a second step to generate embedded data and rebuild:
bin/ollama-codex build # generate assets then rebuild (publishes artifact)
bin/ollama-codex build --local-only # same, skipping Fossil artifact publish
bin/bootstrap is a compatibility symlink to bin/ollama-codex created by
the build step. On a fresh checkout where the symlink does not yet exist,
use bin/ollama-codex build directly.
The versioned .fossil-settings/ignore-glob keeps the binaries out of normal commits.
See docs/isolated-task-checkouts.md for running a localhost Fossil test server against a task checkout.
API Documentation Artifact
Generate project API documentation with:
bin/ollama-codex build-docs
This runs crystal docs, writes generated HTML under agent-docs/html, and enriches index.json with structured doc fields. The next bin/ollama-codex build embeds the generated files into the unified binary. ext/docs is a symlink to bin/ollama-codex which serves the embedded docs.
In isolated task checkouts, build the docs without publishing repo-wide unversioned artifacts:
bin/ollama-codex build-docs --local-only
The versioned .fossil-settings/ignore-glob keeps agent-docs out of normal commits.
Worker
Run one queued task:
bin/task-worker
Run continuously under a supervisor:
bin/task-worker --loop
The authenticated /ext/chat?tasks=1 agent console can also start and stop a managed worker daemon. That path records its pid file and daemon logs under /var/lib/ollama-codex/worker by default:
/var/lib/ollama-codex/worker/task-worker.json
/var/lib/ollama-codex/worker/task-worker.stdout.log
/var/lib/ollama-codex/worker/task-worker.stderr.log
The UI starts the compiled bin/task-worker --loop compatibility symlink, which dispatches through bin/ollama-codex, with setsid and stops the managed process group. It only treats pid files it created as web-managed state.
Useful worker environment:
CODEX_TASK_WORKER_PROVIDER: worker backend, defaultcodex-cli. Set toollama-directfor direct Ollama planning/report tasks that do not shell through thecodexexecutable. Useollama-toolsfor the Crystal-intercepted local tool loop.CODEX_TASK_WORKER_TIMEOUT_SECONDS: per-task wall-clock timeout, default72000.CODEX_TASK_WORKER_COMMAND: test-only override for fake worker commands.OLLAMA_CODEX_ALLOWED_CWD: colon-separated allowed working roots, default/root/ollama.OLLAMA_TOOL_AGENT_MAX_STEPS: maximum interceptedollama-toolsmodel/tool turns, default96.OLLAMA_TOOL_AGENT_NUM_PREDICT: maximum generated tokens for each interceptedollama-toolsJSON tool response, default2048.OLLAMA_TOOL_AGENT_INVALID_JSON_LIMIT: number of malformed JSON tool responses to turn into model feedback before failing the task, default3.OLLAMA_TOOL_AGENT_MAX_SHELL_COMMAND_BYTES: maximum shell command size accepted by the intercepted tool runner, default4096; larger edits should use splitpatchtool calls.OLLAMA_TASK_MODEL: model forollama-direct, falling back toCODEX_TASK_MODELand thenOLLAMA_MODEL.OLLAMA_TIMEOUT_SECONDS: chat/direct Ollama HTTP timeout, default600.OLLAMA_UNLOAD_AFTER_TASK: set to1to unload an Ollama model after each worker task. Default is off so loaded models can remain resident for lower latency.OLLAMA_CODEX_WORKER_PATH: optional absolute path to the compiled worker executable used by the web-managed daemon, default/root/ollama/bin/task-worker.OLLAMA_CODEX_FOSSIL_BINARY: optional absolute Fossil executable path, default/usr/bin/fossil. Use this project-namespaced variable instead of generic Fossil CGI environment variables.
The ollama-direct provider is intentionally limited: the model receives no shell or edit tools, must not claim command execution, and writes a schema-shaped report plus event log directly into the task log directory. Use it for research, planning, prompt shaping, and model checks. Use codex-cli only when the task requires tool use or file edits.
The ollama-tools provider is an experimental local coding backend. It does not hand the session to the Codex CLI; instead, it asks the local model for JSON tool requests, executes bounded shell and patch tools in Crystal, records each intercepted tool request in events.jsonl, and accepts a final schema report. This path exists so local tool behavior can be inspected and repaired without relying on Codex's internal Ollama tool loop.
Repeated whole-file reads are treated as a memory/help signal instead of a violation. The runner tracks lifetime whole-file reads separately from consecutive stalled reads. Progress commands such as tests, targeted compiles, narrow sed ranges, relevant ls/find/rg, patches, or final reports reset the stalled counter without erasing the lifetime diagnostic count. After a small number of stalled semantic repeats such as cat file, cat -n file, or broad sed -n '1,200p' file, the tool runner returns a successful cached read result with a simple file map, line-numbered content, and suggested next actions. If the model ignores that, the runner returns concrete valid JSON examples for test, narrow-read, patch, or final-report actions. One further ignored repeat is replaced with a targeted safe probe, using crystal eval 'require "./path_without_cr_extension"' for Crystal source files. If the model returns to the same whole-file read after that recap, the runner reports a more specific post-probe no-progress loop.
Fossil subprocesses must not inherit CGI variables such as GATEWAY_INTERFACE; Fossil changes command-line behavior in that environment and treats commands like status and open as CGI inputs. The CGI, worker, isolated checkout helper, and intercepted tool runner scrub those variables before invoking Fossil or task tools.
Do not run the worker with crystal run in production. The compiled bin/ollama-codex artifact, reached through bin/task-worker, avoids Crystal compile startup on queued tasks and keeps worker timeouts focused on model/tool execution.
Native Agent Tool
Use the compiled bin/agent-tool helper for model-facing repository operations that should be narrower than raw shell:
bin/agent-tool repo-map src spec
bin/agent-tool read-range src/thread_store.cr 38 48
bin/agent-tool require-check src/thread_store.cr
bin/agent-tool diagnose-crystal-error /tmp/stderr.txt
bin/agent-tool apply-patch /tmp/patch.json
bin/agent-tool verify src/thread_store.cr spec/thread_store_spec.cr
Every subcommand emits JSON. The first monitor integration target is to replace repeated broad file reads with repo-map, read-range, and require-check output, then drive edits through validated old/new patches.
Ollama Residency Check
Use the compiled /api/ps helper to inspect loaded models and their reported CPU/GPU memory split:
bin/agent-tool ollama-status
bin/agent-tool --text ollama-status
The helper reports totals from Ollama's size and size_vram fields. size_vram is GPU-resident memory as reported by Ollama; the CPU/system value is size - size_vram. A loaded model with size_vram equal to 0 is not reported as resident on GPU by Ollama.
Hosted Provider Secrets
Hosted provider credentials must stay outside the checkout. Store them in the root-owned provider environment file:
Use the Providers page in the web UI (/ext/chat?providers=1) to set provider secrets directly into Fossil. For command-line access use the agent-tool set-fossil-secret pathway or the web UI form.
The CGI reads /var/lib/ollama-codex/provider.env directly, because Fossil may not preserve arbitrary environment variables when invoking an extension CGI. The UI reports only whether OPENAI_API_KEY is set; it never renders the key value. start-fossil.sh also sources this file before launching Fossil, but the CGI does not depend on Fossil preserving those variables.
Keys consumed, set as needed:
ANTHROPIC_API_KEY— theanthropicProvider and theclaudeAgentRunner.OPENAI_API_KEY— theopenaiProvider and OpenAI-compatible providers.CONSULT_API_KEY/CONSULT_MODEL— theconsultProvider (the pro model a runner asks at controlled entry points). Consult is an AgentRunner strategy that points at this generic Provider; it is no longer a bespoke config.
Set them through the Providers form (/ext/chat?providers=1) or agent-tool set-fossil-secret; they are stored in the Fossil config table / provider.env, never in versioned source.
Task workers that are started separately from start-fossil.sh need the same environment file sourced by their service wrapper:
. /var/lib/ollama-codex/provider.env
bin/task-worker --loop
The provider environment file is not versioned and should remain readable only by the service account.
Cleanup
Back up /var/lib/ollama-codex if transcripts or task logs are operationally important. Otherwise, old logs/, codex-tasks/, and transcripts/ files may be rotated after their related Fossil commits or task reports have been reviewed. Do not remove JSON files for active pending or running tasks.
Suggested retention policy:
- Keep active
tasks/, tasklogs/, and standalonecodex-tasks/until the related task has a reviewedreport.jsonorpost-analysis.json. - Keep logs for task runs that produced commits at least as long as the related Fossil check-ins are under review.
- Archive older reviewed runtime logs outside the checkout before deleting them if they may be useful for audit or model tuning.
- Prefer a future explicit rotation script over manual cleanup so active task records are not orphaned.