Introduce a new ensemble ranking stage that z-normalizes and fuses reranker, granite, and composite signals into a weighted final_score, then selects top_n and assigns a 1-based rank. Adds EnsembleSettings (defaults: top_n=100, weights 0.5/0.3/0.2, z_clip=3.0) and YAML config block, implements src/rank/ensemble.py with empty/missing-signal guards, exports ensemble from rank package, integrates it into streamlit_app pipeline, and includes unit tests covering scoring, ranking, missing signals, and empty input.