Skip to content
cavackPublic

About

Decision-first SIGNAL_ONLY terminal for short-side USDT perpetual-futures research, evidence capture, replay, outcomes, and observability. No live order placement.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

WaterfallHunter

A canonical, decision-first terminal for SIGNAL_ONLY USDT perpetual-futures research.

CI Python 3.13 Node.js 26 Product mode: SIGNAL ONLY License: All rights reserved

Live Decision Terminal · Architecture · Decision contract · Developer onboarding · Operations

Important

WaterfallHunter is SIGNAL_ONLY. LIVE_TRADING_ENABLED=false is mandatory, and the supported runtime does not place or cancel exchange orders. Only canonical ENTRY_READY is a proactive signal state. Research rankings, lifecycle labels, replay results, execution observations, historical outcomes, and AI output are non-actionable evidence surfaces.

Caution

This repository is research software, not financial advice. entry_readiness is a versioned evidence score—not a probability, promise, or expected return.

Current operational status — 2026-09-09

This repository is now documented as a finalization handoff, not as a claim that every deferred production concern has been closed.

Surface Finalization snapshot
Production application revision e06d874797d936dd134655b606aab5f22ea221ac
Release state DEPLOYED_UNVERIFIED — post-deploy soak and current-state schema-10 DR certification remain pending (#19)
Database schema 10; quick_check=ok; 0 foreign-key violations
Runtime backend/frontend/watchdog/Prometheus/Grafana healthy; restart count 0; OOMKilled=false in the finalization checks
Backtest Lab HMAC-backed Production bundle and authenticated replay verified operational
Gemini configured model gemini-flash-lite-latest; direct provider probe succeeded; advisory-only
CoinGlass optional derivatives packet UNAVAILABLE under the current provider plan (#20)
Telegram credentials validated; signal delivery intentionally disabled; no cutover configured (#21)
Decision snapshot 173 candidates: 108 LATE, 65 NO_TRADE, 0 ENTRY_READY, 0 FORMING, 0 ACTIVE (#22)
Safety LIVE_TRADING_ENABLED=false; no live order placement

The authoritative return point is Current Status. The latest Git main may contain documentation-only commits newer than the deployed application revision; documentation movement is not a Production deployment.

Contents

At a glance

Contract Current boundary
Product Read-only decision terminal, evidence recorder, replay, outcomes, and operational diagnostics
Market Linear USDT perpetual futures
Direction Short-side cascade research only
Actionable state ENTRY_READY only
Execution No order placement or cancellation; execution evidence is observational
Runtime Docker Compose behind nginx, with bounded systemd recovery
Application FastAPI backend, Next.js frontend, Python watchdog
Persistence Managed SQLite schema with durable decision, outcome, replay, and notification records
Observability Prometheus, Grafana, Alertmanager, structured health/readiness endpoints
Optional integrations Telegram notification delivery, Gemini advisory, and additional public-data providers
Safety posture Fail closed on mandatory missing, stale, contradictory, or invalid evidence

Why WaterfallHunter exists

Crypto monitoring systems often mix discovery, ranking, lifecycle, research scores, and entry timing into one ambiguous list. WaterfallHunter keeps those concerns separate:

  1. Discover eligible contracts and normalize market evidence.
  2. Bind evidence to the correct economic contract and freshness window.
  3. Build one canonical decision packet per symbol.
  4. Evaluate hard invalidators, anti-chase, timing, and weighted evidence.
  5. Emit one public entry decision with explicit reasons and blockers.
  6. Persist transitions, outcomes, replay evidence, and notification state.
  7. Present actionability before research detail.

The result is deliberately conservative: a high research score, an interesting lifecycle stage, or a model advisory can never silently become an entry command.

Canonical decision contract

Every evaluated symbol receives exactly one public entry state:

State Meaning Enter now?
NO_TRADE Evidence does not support a valid setup, or a deterministic veto applies No
FORMING Evidence is developing but the canonical entry contract is incomplete No
ENTRY_READY Timing, direction, execution geometry, freshness, and mandatory checks pass Canonical signal state
ACTIVE A previously emitted entry-ready setup is now in progress No new entry instruction
LATE The move is too extended or the entry window has passed No
INVALIDATED A previously valid setup has failed an explicit invariant No
EXPIRED The decision aged beyond its valid horizon No
UNAVAILABLE Required evidence or runtime state cannot be established honestly No

Lifecycle is a separate context model:

WATCH → FUEL-RICH → PRE-TRIGGER → ARMED → TRIGGERED → EXHAUSTED
                                      ↘ INVALIDATED

Lifecycle TRIGGERED does not mean ENTRY_READY. An immutable entry event cannot silently disappear; later changes are recorded as explicit transitions with timestamps, reason codes, model/evidence version, and provenance.

Protected calibration and pending Anti-Chase correction

The protected entry_policy_v1 bands are ENTRY_READY >= 78 and FORMING >= 55; lower readiness remains NO_TRADE. Anti-Chase uses a 1.2 ATR hard-extension boundary. The canonical Anti-Chase ordering recorded in Model Change Ledger is present in the deployed Production lineage: freshness and deterministic invalidators are evaluated first, and Anti-Chase only converts an otherwise FORMING, ENTRY_READY, or ACTIVE decision to LATE. Anti-Chase does not turn sub-FORMING evidence into LATE, lower either readiness threshold, or manufacture missing evidence. Genuine lifecycle EXHAUSTED remains explicitly terminal LATE, including when other blockers apply. New LATE packets record late_origin provenance while lifecycle_state continues to reflect the current evaluation.

Read the full contracts in Decision Engine, Model, and Dashboard.

System architecture

flowchart LR
    O["Browser / operator"] --> N["nginx public edge"]
    N --> F["Next.js Decision Terminal"]
    F -->|"/dashboard/api/* + SSE"| B["FastAPI backend"]

    subgraph EVIDENCE["Market and evidence inputs"]
        L["LBank canonical catalogue + market data"]
        X["Cross-exchange CCXT evidence"]
        C["CoinGlass optional derivatives evidence"]
        D["DEX / on-chain optional context"]
        G["Gemini optional advisory"]
    end

    L --> B
    X --> B
    C -.-> B
    D -.-> B
    G -.-> B

    B --> S[("Managed SQLite schema 10")]
    S --> H["Canonical decisions / outcomes / replay"]
    H --> R["Backtest Lab — signed, read-only"]
    S --> Q["Durable notification outbox"]
    Q -.-> T["Telegram — disabled until release cutover"]

    B --> P["Prometheus"]
    P --> GR["Grafana"]
    P --> A["Alertmanager"]
    W["Watchdog"] --> B
    W --> A

    SD["systemd bounded recovery"] --> DC["Docker Compose"]
    DC --> F
    DC --> B
    DC --> W
    DC --> P
    DC --> GR
    DC --> A

    B --> SAFE["SIGNAL_ONLY boundary"]
    SAFE --> LT["LIVE_TRADING_ENABLED=false"]
Loading

Runtime topology:

browser → nginx → Next.js frontend → FastAPI backend → managed SQLite volume
                                  ↘ watchdog / Prometheus / Grafana / Alertmanager

The frontend is the public edge. The backend and stateful services remain on internal Compose networks. Container filesystems are read-only where practical, Linux capabilities are dropped, no-new-privileges is enabled, logs are bounded, and persistent state is isolated in named volumes.

Product surfaces

Decision Terminal

The live dashboard is ordered by decision safety rather than raw rank:

  • canonical counts for ENTRY_READY, FORMING, ACTIVE, and blocked/other states;
  • at most three ENTRY_READY cards;
  • at most six nearest FORMING cards;
  • explicit no-signal and dominant-blocker explanations;
  • recent decision transitions;
  • searchable, filterable, paginated all-candidates table;
  • price, OI, funding, taker flow, cascade, spread, cross-exchange, freshness, anti-chase, and execution-plan context where available.

When nothing is ready, the terminal says so. It does not turn a top-ranked observational list into a trading cue.

Research and validation

Secondary panels are collapsed and loaded on demand. They include:

  • production evidence recorder status;
  • feature-equivalent replay;
  • natural and imported historical outcomes;
  • execution-suitability and execution-outcome observations;
  • lifecycle-v2 shadow evidence;
  • signal-funnel diagnostics;
  • bounded Backtest Lab workflows.

These surfaces explain and validate the system; they cannot create, veto, promote, or downgrade a canonical signal.

Notification and advisory boundaries

  • Telegram is notification-only. Canonical events use a durable outbox with leases, retries, rate-limit handling, dead-letter state, and a release-scoped cutover boundary.
  • Gemini is optional advisory context. Missing credentials or provider failure yields UNAVAILABLE; deterministic evaluation continues.
  • No local model runtime is required by the canonical architecture.

Evidence model

WaterfallHunter combines evidence families without pretending that every optional source is always present:

Evidence family Examples Safety treatment
Market identity symbol, venue, contract type, quote/settlement asset Contract mismatch can invalidate the packet
Structure and timing price behavior, breakdown geometry, extension Drives timing and mandatory anti-chase checks
Derivatives open interest, funding, crowding Weighted evidence; freshness and provenance are explicit
Aggressive flow taker imbalance, CVD-like observations Supports or contradicts directional evidence
Liquidation/cascade observed liquidation flow and cascade context Observed and estimated evidence are labelled separately
Liquidity/execution spread, depth, slippage geometry, venue constraints Invalid geometry can block actionability
Cross-exchange agreement for the same economic contract Contradictory fresh identity/evidence can invalidate
Relative context market regime and relative weakness Contextual evidence, never a standalone command

Missing optional evidence lowers coverage. Missing mandatory evidence produces an explicit blocker or UNAVAILABLE; it is never silently replaced with synthetic market data.

Scientific and promotion boundaries

  • entry_readiness is a versioned readiness score, not a calibrated probability.
  • Deterministic fixtures and golden replay corpora are regression evidence, not live profitability evidence.
  • Imported historical datasets and naturally observed production outcomes remain distinct.
  • New thresholds and evidence families require provenance, replay, walk-forward/holdout evaluation, and explicit promotion evidence.
  • Experimental pre-triggers remain observational and cannot place orders or bypass canonical decisions.
  • Execution suitability cannot become a signal gate without its own calibrated promotion contract.

See Strict Scientific Validation, Feature-equivalent Replay, and Operational Historical Outcomes.

Repository map

Path Responsibility
backend/ FastAPI application, discovery, evidence normalization, decision engine, persistence, migrations, replay, outcomes, and APIs
frontend/ Next.js Decision Terminal and lazily mounted research panels
watchdog/ Health watcher, heartbeat, and optional alert/notification bridge
deploy/ nginx, systemd, Prometheus, Grafana, and Alertmanager assets
scripts/ Validation, backup, migration, replay, calibration, certification, and release tooling
docs/ Canonical product, engineering, data, scientific, and operational documentation
research/ Curated research inputs; generated outputs and datasets stay out of Git
skills/waterfallhunter/ Repository-local engineering workflows and verification contracts
.github/workflows/ Exact-SHA CI artifact construction and guarded production deployment

Repository governance

The canonical repository is protected main in cavack/WFH-ORG. Required CI checks are strict, linear history is enforced, force pushes/deletion are blocked, review conversations must be resolved, and Production deployment is an explicit exact-SHA action rather than a side effect of push.

GitHub Actions reaches Production through a dedicated SSH identity stored in the production Environment. The Production host uses authenticated HTTPS/gh for normal repository operations and has a repository-scoped read-only SSH fallback for fetch continuity. Runtime recovery is layered across systemd boot assertion, Docker restart: unless-stopped, and the bounded one-minute health-recovery timer.

See Repository Governance, Security Policy, Contributing, and Support.

Quick start with Docker Compose

Prerequisites

  • Git
  • Docker Engine with Compose v2
  • Enough local resources to build the backend, frontend, and watchdog images
git clone https://github.com/cavack/WFH-ORG.git
cd WFH-ORG
cp .env.example .env

# Validate the resolved configuration before starting anything.
docker compose config --quiet

# Build the backend image, then bootstrap the managed SQLite schema
# in the persistent waterfall_data volume before runtime startup.
docker compose build waterfall-backend
docker compose run --rm \
  -e SOURCE_REVISION="$(git rev-parse HEAD)" \
  waterfall-backend sh -ec '
    python -m waterfallhunter.migrate_database \
      --db-path "$REGISTRY_DB_PATH" \
      --apply \
      --source-revision "$SOURCE_REVISION"
  '

# Build the remaining images and start the local SIGNAL_ONLY stack.
docker compose up --build -d
docker compose ps

Local interfaces bind to loopback by default:

Surface URL
Decision Terminal http://127.0.0.1:3000/dashboard/
Grafana http://127.0.0.1:3001/

Stop containers without deleting persistent state:

docker compose down

Warning

Do not use docker compose down -v against a stack whose SQLite volume matters. The -v option removes named volumes and can destroy the only local database copy.

Native development

Canonical runtimes are recorded in .github/runtime-versions.json: Python 3.13 and Node.js 26. make setup refuses to build a virtualenv from a different Python; pass PYTHON=python3.13 when python3 is not the canonical runtime.

make setup
make validate

Individual developer commands:

make test
make typecheck
make build

A partial direct sequence for backend/frontend tests and build is:

python -m pip install --only-binary=:all: --require-hashes -r backend/requirements.lock
PYTHONPATH=backend/src:. pytest -q backend/tests

npm --prefix frontend ci
npm --prefix frontend run test:contract
npm --prefix frontend run typecheck
npm --prefix frontend run build

The release-candidate validator requires a clean committed SHA. It exports that exact revision, validates Compose, builds the production image family, executes backend tests inside the built backend image, applies migrations to a throwaway SQLite database, and verifies OCI revision labels. It never starts Production or mounts the Production database.

./scripts/validate_clean_install.sh

Configuration contract

Copy .env.example for local development. Never commit the resulting .env.

Variable Default Contract
LIVE_TRADING_ENABLED false Mandatory invariant; the supported runtime is signal-only
REGISTRY_DB_PATH /app/data/waterfall_registry.db Managed SQLite database path inside the backend container
EXPERIMENTAL_PRETRIGGER_ENABLED false Observational discovery only; never order execution
LBANK_EXECUTION_SHADOW_ENABLED false in .env.example Read-only execution observation; Compose may explicitly enable the worker
TELEGRAM_SIGNAL_DELIVERY_ENABLED false Requires credentials and a release-scoped cutover timestamp
GEMINI_API_KEY empty Optional advisory provider; absence does not break deterministic evaluation
COINGLASS_API_KEY empty Optional external evidence provider
DEXSCREENER_ENABLED false Optional contextual discovery path
BACKTEST_ARTIFACT_HMAC_KEY empty Optional signing key for bounded backtest artifacts

Provider credentials, chat identifiers, production environment files, database files, evidence packets, logs, backups, and generated research datasets must never be committed.

API and health surface

Common backend routes:

Route Purpose
GET /livez Process liveness only
GET /readyz Scanner, hunter, database, and runtime-progress readiness
GET /healthz Readiness-compatible health alias
GET /api/health Structured application health snapshot
GET /api/candidates Canonical dashboard snapshot
GET /api/stream Server-Sent Events dashboard stream with replay support
GET /api/recent-signals Durable recent canonical signal history
GET /api/notification-delivery Durable notification/outbox health
GET /api/production-evidence Recorder and production-evidence report
GET /api/feature-replay Feature-equivalent replay report
GET /api/historical-outcomes Historical-outcome datasets and summaries
GET /api/execution-suitability Read-only execution-suitability report
GET /api/execution-outcome-validation Execution-observation validation report
GET /api/lifecycle-v2-shadow Lifecycle-v2 shadow evidence
GET /metrics Prometheus metrics

When accessed through the public Next.js frontend, API paths are exposed under the dashboard base path—for example, /dashboard/api/health. Research endpoints are requested only when their corresponding UI section is opened.

Data, schema, and recovery

  • The application database lives in the waterfall_data volume, not in Git.
  • Schema ownership is migration-based; the current migration chain lives under backend/src/waterfallhunter/migrations/.
  • Runtime startup fails closed on unsupported or inconsistent schema state.
  • A production migration requires a certified backup, preflight, isolated rehearsal, and rollback evidence.
  • Restore is always performed into a new file or volume first. The only good backup is never overwritten.
  • SQLite backup equality is established through integrity and logical-content evidence, not by assuming raw online-backup bytes must match.
  • A bounded recovery set normally retains two certified backups, including a valid pre-migration recovery point until post-cutover certification completes.

Read Data and Database, Backup and Restore, and the Deployment Certification Runbook before any schema, cutover, cleanup, or restore operation.

CI, release, and deployment

The CI workflow runs:

  • locked Python installation and the backend test suite;
  • WaterfallHunter skill and runtime-parity validation;
  • frontend contract tests, typechecking, and production build;
  • Python and npm dependency audits;
  • Compose validation and production image builds;
  • backend tests and migration smoke tests inside the exact backend artifact;
  • OCI revision-label verification;
  • repository hygiene and credential-pattern checks;
  • upload of the exact built, digest-recorded, revision-labelled backend/frontend/watchdog image bundle; the backend artifact is additionally exercised by backend tests and migration smoke.

Production deployment is deliberately separate from an ordinary push:

protected main
  → exact-SHA CI
  → backup / migration / rollback / recovery gates
  → explicit workflow_dispatch with deploy_production=true
  → repeated required checks
  → exact CI-built, digest-recorded artifact bundle
  → guarded host deployment
  → health, schema, safety, and OCI revision certification

Pull requests do not receive production credentials. A push to main runs CI but does not deploy. Rollback is allowed only when schema compatibility is proven; otherwise the runtime is quarantined and recovery evidence is preserved.

See Deployment, Operations, and Automatic Production Deployment.

Observability and incident response

  • /livez answers only whether the process is alive.
  • readiness endpoints include scanner catalogue freshness, hunter progress, database readiness, and read-only execution-shadow progress.
  • Prometheus records candidate states, evidence quality, cycle progress, notification health, and service metrics.
  • Grafana provides dashboards; Alertmanager and the watchdog provide bounded health alerting.
  • Container logs use bounded JSON-file rotation.
  • systemd asserts the canonical Compose stack after boot and uses bounded recovery rather than unlimited restart loops.

Healthy endpoints do not by themselves prove decision correctness, backup validity, schema compatibility, or release readiness. Those are separate evidence gates.

Documentation index

Topic Canonical document
Current production/finalization status Current Status
New developer or AI-session handoff Project Handoff
Runtime topology and data flow Architecture
Market and evidence rules Model
Entry states and readiness Decision Engine
Dashboard information architecture Dashboard
SQLite ownership and schema lineage Data and Database
Local setup Developer Onboarding
Runtime operations Operations
Production release Deployment
Recovery Backup and Restore
Notification boundary Telegram
Advisory boundary AI Advisory
Common failures Troubleshooting
Program sequencing Dependency Graph
Model and decision changes Model Change Ledger
Repository controls and trust paths Repository Governance

Contributing

  1. Start from current main in a short-lived branch or isolated worktree.
  2. Keep changes narrow and add focused regression coverage for behavior changes.
  3. Preserve SIGNAL_ONLY, canonical state semantics, and fail-closed data handling.
  4. Use migration and backup/rehearsal coverage for persistent-schema changes.
  5. Run make validate; run ./scripts/validate_clean_install.sh for a clean release-candidate commit.
  6. Open a reviewed pull request and require exact-head CI before merge.

Read CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md, and SUPPORT.md before submitting changes, requesting support, or reporting a vulnerability.

Non-goals

The supported runtime intentionally does not provide:

  • exchange order placement, cancellation, or account management;
  • automatic threshold promotion from replay or historical results;
  • a claim that readiness is a calibrated probability;
  • synthetic fallback market data when required evidence is missing;
  • AI authority over canonical decisions;
  • unreviewed push-to-production deployment;
  • destructive database cleanup without certified recovery evidence.

License

Copyright © 2026 cavack. All rights reserved.

The source is publicly viewable for inspection and collaboration, but no permission is granted to copy, modify, distribute, sublicense, sell, or use the software or substantial portions of it without prior written permission from the copyright holder. See LICENSE for the controlling terms.

About

Decision-first SIGNAL_ONLY terminal for short-side USDT perpetual-futures research, evidence capture, replay, outcomes, and observability. No live order placement.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages