From dc2ca8be0e4d628e013b27332129254602a68891 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Tue, 28 Jul 2026 20:06:58 -0400 Subject: [PATCH 1/2] docs(readme): how to deploy a release into a deployment RELEASING.md covers cutting a release but stops at the published artifacts; how to get one INTO a deployment lived only in shell history. Documents the four commands, run from the deployment directory, plus the two things that are easy to get wrong: --find-links is what lets the keel_trader wheel resolve its workspace siblings (so download them all), and `keel --version` must report [release] bound to a commit -- a (DIRTY) or [checkout] build corresponds to no commit and must not run against live funds. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 922f7547..8c8f77ee 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,39 @@ for any live (network) commands. `.env` is git-ignored and never committed. Offl Runtime settings (allowlist, target weights, risk caps, market data granularities, etc.) live in `config.yaml` at the repo root — see `keel/config.py` for the schema and validation rules. +## Deploying a new version + +Cutting a release is `docs/RELEASING.md`. Installing one into a deployment (e.g. `~/keel`) is four +commands, run **from the deployment directory** — every path below is relative to it: + +```bash +gh release download v0.3.1 --repo CodeGateSoftware/keel --pattern '*.whl' --dir Release/ +uv pip install --python .venv --find-links Release Release/keel_trader-0.3.1-py3-none-any.whl +.venv/bin/keel --version +.venv/bin/keel status +``` + +Substitute the version being deployed in both of the first two lines. `--find-links Release` is +what lets the single `keel_trader` wheel resolve its `keel-core` / `keel-broker-*` siblings from +that same directory — which is why step 1 downloads them all. Installing **by path** rather than +by bare name is deliberate: `keel` on PyPI is an unrelated project, so `pip install keel` fetches a +stranger's code (see `keel/version.py`). + +Step 3 is the check that matters. It must report the version you just installed, bound to a +commit, from source `[release]`: + +``` +keel 0.3.1+deb8fa7e978d [release] +``` + +A build reporting `(DIRTY)` or `[checkout]` corresponds to no commit and **must not be run against +live funds**. Step 4 is a read-only snapshot — no orders, no writes — confirming the new build +opens the database and reaches the venue. + +If the deployment runs on a schedule (LaunchAgents, cron), a new build takes effect on the next +cycle with nothing to restart — each cycle is a fresh process. A **long-running** process is the +exception: a `keel tui` left open keeps the build it started with until you quit and relaunch it. + ## Before trading live Read `docs/operator-runbook.md`. It lists the compliance obligations **no rail can enforce** — chiefly From c564db723135e3531dcc295f03269434eafa896f Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Tue, 28 Jul 2026 15:41:22 -0400 Subject: [PATCH 2/2] chore: ignore operator wrapper scripts keel-live and keel-paper are deployment artifacts with config and db paths pinned; they get copied to ~/keel rather than tracked here. Co-Authored-By: Claude Opus 5 (1M context) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index a8b039cd..c080ad0d 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,7 @@ com.keel.paperforward.plist config.live-sandbox.yaml keel-live-run.sh com.keel.live.plist + +# operator wrappers (config+db pinned) -- deployment artifacts, copied to ~/keel +keel-live +keel-paper