Hacktoberfest DEV Challenge Submission - StockRadar
Project: StockRadar - Open-weight stockout early warning for tiny neighbourhood shops
Repository: https://github.com/BhushanVidhate-27/side-hustle
Challenge: DEV Challenge - Week 2 (Side Hustle)
Tags: #devchallenge #hf26challenge
Deadline: Sunday 18 October 2026, 11:59 PM PDT
What We Built
StockRadar predicts which SKUs will run out at tiny kirana shops before customers notice. It reads a shop's sales ledger, forecasts stockouts, and outputs ready-to-send reorder messages in the language the shopkeeper actually uses with their distributor.
Core Value: Tells a shop owner what to reorder (and what NOT to reorder) before the shelf goes empty - with complete transparency about which engine/AI produced each number.
Key Features
- Zero-config by default: Runs entirely offline with arithmetic baseline (no API keys required)
- Live TabPFN integration: Uses Prior Labs TabPFN-3.5 tabular foundation model when configured
- Open-weight Gemma: Local LLM (via Ollama) or Google AI Studio for natural language reorder advice in Hinglish/English
- Khata photo ingestion: Upload a photo of a handwritten ledger - vision model extracts structured rows
- Smart urgency logic: Bins by days-of-cover relative to delivery cycle (not just probability) to avoid alert fatigue
- Shelf-life aware reordering: Caps quantities to prevent spoilage (critical for eggs/milk)
- Durable workflows: Temporal-compatible with local fallback that checkpoints after every step and resumes on failure
- Complete degradation: Every optional component has a working fallback; the output always names what actually ran
-
Honest self-reporting:
/api/healthand CLI output explicitly state which models are configured vs actually running
Technical Implementation
Stack: Python 3.11+, FastAPI, TabPFN, Gemma (Ollama/Google), Temporal (optional), Sentry (optional)
Architecture highlights:
- Protocol-based design (
ForecastEngine,Advisor) for swappable components - Defensive parsing: TabPFN outputs are reconciled, hallucinated SKUs are dropped, all numbers copied from forecasts (never from LLM)
- Tolerant CSV ingestion with 9 date formats, BOM handling, missing column resilience
- Recency-weighted demand (65% last 28 days, 35% long-run) to catch Diwali/festival ramps
- Atomic checkpointing with per-activity retries and exponential backoff
Test Coverage: 158 passed, 1 skipped, 2 warnings (no network, fully deterministic)
Evidence of Real Usage
Working Demo (Zero Config)
python data/generate_sample_shop.py
python -m stockradar.cli run --limit 6
Output shows: engine name, days of cover, probabilities, rupee amounts at risk, and WhatsApp-ready messages like:
"Namaste bhaiya, 123 trays Farm Eggs (dozen) bhej dijiye, aaj hi chahiye. Stock khatam hone wala hai. Dhanyavaad. - Sharma General Store"
Live TabPFN Path
When PRIORLABS_API_KEY is configured, the system runs with engine: tabpfn-3.5 (Prior Labs). The model learns from the shop's own history (fit on (SKU, day) features with forward-looking stockout labels) and provides calibrated probabilities.
Durability Demo
STOCKRADAR_NOTIFY_FLAKY_ATTEMPTS=2 python -m stockradar.cli workflow
Shows injected failures, exponential backoff retries (2s, 4s...), and successful completion of all three steps (forecast → notify → persist). Checkpointing ensures interrupted runs resume without redoing completed work.
Measured Performance (Backtest)
Walk-forward evaluation on synthetic kirana data (3 seeds × 5 cutoffs × 24 SKUs = 360 predictions per scenario):
| Scenario | Metric | ArithmeticBaseline | TabPFN-3.5 | Result |
|---|---|---|---|---|
| Realistic (demo) | Brier | 0.3257 | 0.2171 | TabPFN better (calibrated) |
| False-alarm rate | 0.3641 | 0.2521 | TabPFN better (fewer false alerts) | |
| Stressed (supplier failure) | Brier | 0.1603 | 0.2280 | Baseline better (generalizes) |
| Precision @ top 25% | 0.8222 | 0.4556 | Baseline better (ranking) |
Key takeaway: TabPFN wins the realistic scenario (the one matching normal shop behavior) and loses under abrupt regime shift. This is reported honestly with full caveats (only 3 stockout events in demo scenario - direction, not verdict). Methodology documented in docs/BACKTEST.md.
Open-Source AI Usage
This project makes deliberate, honest use of open-weight models:
Prior Labs TabPFN-3.5 (Featured Partner) - Open tabular foundation model. Trained on millions of tabular datasets; we use it for stockout probability prediction from engineered features. Called via scikit-learn API (TabPFNClassifier) with defensive parsing and graceful fallback.
Gemma 3 (open weights) - Used for:
Natural language advice generation (Ollama local:
gemma3:1b; Google AI Studio:gemma-3-27b-it)Khata photo OCR (Ollama:
gemma3:4bvision-capable) to extract ledger rows from handwritten notebooksSystem prompt explicitly forbids forecasting jargon and copies all numeric facts from forecasts (never trusts LLM with arithmetic)
Fully offline path - Works with zero external calls. The arithmetic baseline (
normal approximationover daily demand) is production-quality for this use case.
Degradation Philosophy
"Every optional component has a working replacement, and the replacement is always named in the output."
- No API key → arithmetic baseline + template advisor (explicitly stated)
- TabPFN errors/timeouts → batch fallback to arithmetic with warnings
- LLM unavailable → deterministic templates (no stack traces to shopkeeper)
- Process dies mid-run → atomic checkpoint resumes from first incomplete step
- Malformed model output → per-SKU fallback, never discards entire batch
- Khata OCR fails → raises with actionable fix (
ollama pull gemma3:4b), never invents rows
Sponsor Integrations
| Partner | Status | Evidence |
|---|---|---|
| Prior Labs (TabPFN) - $200 | Integrated, live | Code in stockradar/forecasting/tabpfn_engine.py, API key configured, backtest run with real model path |
| Google (Gemma) - $200 | Code integrated, ready | Providers in explain/providers.py (Ollama + Google AI Studio), prompts in prompts.md, vision path for khata |
| Render - $200 | Config ready |
render.yaml (free plan), health check at /api/health, designed to not host inference (data stays local) |
| Temporal - $100 | Built & tested | Full workflow with retry policies, checkpoint fallback (LocalDurableScheduler), flakiness demo |
| Sentry - $100 | Built & ready | Tracing in observability/tracing.py with local fallback to in-memory step table at /api/steps
|
| .tech domain - $100 | Available via promo | Can be claimed at hacktoberfest.com/my/promos |
Try It Yourself
git clone https://github.com/BhushanVidhate-27/side-hustle.git
cd side-hustle
python -m venv .venv && .venv/bin/pip install -r requirements.txt
# Zero-config demo (no network, no secrets)
python data/generate_sample_shop.py
python -m stockradar.cli run --limit 8
python -m pytest tests/ # 158 passed
# Dashboard
python -m stockradar.cli serve # http://localhost:8000
Full documentation: README.md | DEV Post Draft | Backtest Methodology | Workflow Design
Top comments (0)