PRD §3 C7. Design decision needed before any implementation.
The asymmetry
Brokers are pluggable: a venue adapter registers under the keel.brokers Python entry point and is a pip install away, with no core change — that is how keel-broker-alpaca and keel-broker-robinhood ship.
Rules are not: RULE_REGISTRY is a hardcoded four-entry dict in keel/agent.py:116-121. A fifth rule requires a core-code change.
All three competitors let users drop in strategies without touching core — Freqtrade loads any Python class from user_data/strategies/, Jesse and Hummingbot the same.
Why this is not simply a good idea
Three tensions, all needing an answer first:
1. The promotion gate assumes rules it can evaluate. An external rule must still clear min_trades=100, expectancy, RR, win-rate floors and the PBO gate (keel/strategy/promotion.py). That is arguably fine — the gate is rule-agnostic — but it means a plugin author cannot ship a "ready to trade" rule, only a candidate. Worth being explicit, since it is the opposite of what plugin authors on other platforms expect.
2. No sandboxing anywhere in the category. Freqtrade's own docs note strategies are arbitrary Python with no safety net; Jesse is the same. keel would inherit that — third-party code running in the same process that holds live exchange credentials. The broker port at least has a narrow typed surface (Protocol with ten methods) and a 21-test conformance suite; a rule plugin's surface is detect() returning a Setup, which is narrow too, but the code around it is unconstrained.
3. It widens the compliance surface. keel's charter is enforced at multiple layers, and a rule cannot currently propose a short or a derivative because Setup.direction is Literal["long"] and rails 18/19 refuse the instrument shapes. That holds for plugins too — worth confirming by test rather than assumption, since it is the property that makes third-party rules acceptable at all.
If it proceeds
- Mirror the broker pattern: a
keel.rules entry point, discovered like keel.brokers.
- A rule conformance suite, mirroring
keel_broker_api/conformance/suite.py — assert detect() is pure, Setup.direction is long, describe() round-trips, and params validate.
- Plugin rules enter as
candidate and climb the same ladder. No exemption.
The question
Is third-party rule code acceptable in-process given the live credentials, or should keel stay a curated four-rule engine and treat this as a deliberate boundary like the others in §2 of the PRD?
PRD §3 C7. Design decision needed before any implementation.
The asymmetry
Brokers are pluggable: a venue adapter registers under the
keel.brokersPython entry point and is apip installaway, with no core change — that is howkeel-broker-alpacaandkeel-broker-robinhoodship.Rules are not:
RULE_REGISTRYis a hardcoded four-entry dict inkeel/agent.py:116-121. A fifth rule requires a core-code change.All three competitors let users drop in strategies without touching core — Freqtrade loads any Python class from
user_data/strategies/, Jesse and Hummingbot the same.Why this is not simply a good idea
Three tensions, all needing an answer first:
1. The promotion gate assumes rules it can evaluate. An external rule must still clear
min_trades=100, expectancy, RR, win-rate floors and the PBO gate (keel/strategy/promotion.py). That is arguably fine — the gate is rule-agnostic — but it means a plugin author cannot ship a "ready to trade" rule, only a candidate. Worth being explicit, since it is the opposite of what plugin authors on other platforms expect.2. No sandboxing anywhere in the category. Freqtrade's own docs note strategies are arbitrary Python with no safety net; Jesse is the same. keel would inherit that — third-party code running in the same process that holds live exchange credentials. The broker port at least has a narrow typed surface (
Protocolwith ten methods) and a 21-test conformance suite; a rule plugin's surface isdetect()returning aSetup, which is narrow too, but the code around it is unconstrained.3. It widens the compliance surface. keel's charter is enforced at multiple layers, and a rule cannot currently propose a short or a derivative because
Setup.directionisLiteral["long"]and rails 18/19 refuse the instrument shapes. That holds for plugins too — worth confirming by test rather than assumption, since it is the property that makes third-party rules acceptable at all.If it proceeds
keel.rulesentry point, discovered likekeel.brokers.keel_broker_api/conformance/suite.py— assertdetect()is pure,Setup.directionis long,describe()round-trips, and params validate.candidateand climb the same ladder. No exemption.The question
Is third-party rule code acceptable in-process given the live credentials, or should keel stay a curated four-rule engine and treat this as a deliberate boundary like the others in §2 of the PRD?