PRD §3 C5. Hummingbot ships hbot doctor; keel has no equivalent.
The motivating case, from a real session
A paper profile was detecting setups and recording zero trades for weeks. Two independent causes, neither surfaced by any single command:
subscription_unattested vetoed 15 of 15 detected setups.
- Even attested, every proposal was ~$4,212 of notional against a $2,500 per-asset cap — 0 of 25 products admissible — because the profile sized against a synthetic $10k account while inheriting the real account's $500/month allowance.
Diagnosing it took parsing the JSONL log, cross-referencing guards.check_failed violations, and computing f_N = risk_pct / s by hand against measured ATR. keel status showed a healthy-looking deployment throughout.
What it should check
- Config vs reality — does sizing at
risk_pct produce notionals admissible under this profile's own caps, at current ATR? Report the fraction of allowlisted products that are admissible. This alone would have caught the case above.
- Attestation freshness — rail 14 subscription, rail 17 withdrawals (7-day TTL), asset/instrument attestations; days remaining, not just valid/invalid.
- Rail state — any armed halt (kill-switch, rail 11 drawdown, rail 16 streak) and what clears it.
- Data health — staleness per product, gaps,
market_closed versus genuinely stale.
- Install integrity —
keel versions skew, build identity not DIRTY/[checkout].
- Recent vetoes — top
guards.check_failed violations over the last N cycles, aggregated. A profile vetoing 100% of entries for one reason should be impossible to miss.
- Allowance headroom — month-to-date spend against the attested allowance, and how many typical orders remain.
Design notes
- Read-only, no broker calls beyond what
status already makes, --json supported.
- Each finding names the command that fixes it. The value is in the next step, not the diagnosis.
- Distinguish broken from deliberately halted — an armed kill-switch is a correct state, not a fault.
PRD §3 C5. Hummingbot ships
hbot doctor; keel has no equivalent.The motivating case, from a real session
A paper profile was detecting setups and recording zero trades for weeks. Two independent causes, neither surfaced by any single command:
subscription_unattestedvetoed 15 of 15 detected setups.Diagnosing it took parsing the JSONL log, cross-referencing
guards.check_failedviolations, and computingf_N = risk_pct / sby hand against measured ATR.keel statusshowed a healthy-looking deployment throughout.What it should check
risk_pctproduce notionals admissible under this profile's own caps, at current ATR? Report the fraction of allowlisted products that are admissible. This alone would have caught the case above.market_closedversus genuinely stale.keel versionsskew, build identity notDIRTY/[checkout].guards.check_failedviolations over the last N cycles, aggregated. A profile vetoing 100% of entries for one reason should be impossible to miss.Design notes
statusalready makes,--jsonsupported.