{"id":51546109,"url":"https://github.com/amareshhebbar/hiresignal","last_synced_at":"2026-07-09T18:30:44.347Z","repository":{"id":367285137,"uuid":"1280072354","full_name":"amareshhebbar/hiresignal","owner":"amareshhebbar","description":"Ranks 100K candidates against a Senior AI Engineer JD in ~35s on CPU — multi-signal scoring, honeypot detection, semantic embeddings. INDIA RUNS Hackathon Track 1.","archived":false,"fork":false,"pushed_at":"2026-06-25T09:36:12.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-25T11:14:27.731Z","etag":null,"topics":["candidate-ranking","embeddings","faiss","hackathon","india-runs","india-runs-2026","information-retrieval","machine-learning","nlp","python","redrob","sentence-transformers"],"latest_commit_sha":null,"homepage":"https://huggingface.co/spaces/AmareshHebbar/hiresignal","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amareshhebbar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-25T08:41:50.000Z","updated_at":"2026-06-25T09:40:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/amareshhebbar/hiresignal","commit_stats":null,"previous_names":["amareshhebbar/hiresignal"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/amareshhebbar/hiresignal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amareshhebbar%2Fhiresignal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amareshhebbar%2Fhiresignal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amareshhebbar%2Fhiresignal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amareshhebbar%2Fhiresignal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amareshhebbar","download_url":"https://codeload.github.com/amareshhebbar/hiresignal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amareshhebbar%2Fhiresignal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35309827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["candidate-ranking","embeddings","faiss","hackathon","india-runs","india-runs-2026","information-retrieval","machine-learning","nlp","python","redrob","sentence-transformers"],"created_at":"2026-07-09T18:30:41.645Z","updated_at":"2026-07-09T18:30:44.341Z","avatar_url":"https://github.com/amareshhebbar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n```\n██╗  ██╗██╗██████╗ ███████╗███████╗██╗ ██████╗ ███╗   ██╗ █████╗ ██╗      \n██║  ██║██║██╔══██╗██╔════╝██╔════╝██║██╔════╝ ████╗  ██║██╔══██╗██║      \n███████║██║██████╔╝█████╗  ███████╗██║██║  ███╗██╔██╗ ██║███████║██║      \n██╔══██║██║██╔══██╗██╔══╝  ╚════██║██║██║   ██║██║╚██╗██║██╔══██║██║      \n██║  ██║██║██║  ██║███████╗███████║██║╚██████╔╝██║ ╚████║██║  ██║███████╗ \n╚═╝  ╚═╝╚═╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝╚══════╝ \n```\n\n**Intelligent Candidate Discovery \u0026 Ranking**\n\n*INDIA RUNS Hackathon — Track 1 (Data \u0026 AI Challenge) — Redrob AI × Hack2Skill*\n\n[![Python](https://img.shields.io/badge/Python-3.11+-3776AB?style=flat-square\u0026logo=python\u0026logoColor=white)](https://python.org)\n[![Tests](https://img.shields.io/badge/Tests-10%20passed-22c55e?style=flat-square)](tests/)\n[![Runtime](https://img.shields.io/badge/Runtime-~35s%20CPU-6366f1?style=flat-square)](#compute)\n[![Candidates](https://img.shields.io/badge/Dataset-100K%20candidates-f59e0b?style=flat-square)](#)\n[![Demo](https://img.shields.io/badge/Live%20Demo-HuggingFace%20Spaces-ff6b35?style=flat-square\u0026logo=huggingface)](https://huggingface.co/spaces/AmareshHebbar/hiresignal)\n\n\u003c/div\u003e\n\n---\n\n## What it does\n\nRanks 100,000 candidate profiles against a Senior AI Engineer job description in **~35 seconds on CPU** — no GPU, no API calls, no network during ranking.\n\nGoes well beyond keyword matching. Scores each candidate across four dimensions, detects ~85 honeypot/fraudulent profiles, and generates a specific natural-language explanation for every ranking decision.\n\n```\n$ make rank\n[1/6] loading dataset/candidates.jsonl\n      100,000 candidates loaded  (7.1s)\n[2/6] honeypot detection\n      85 flagged  (0.4s)\n[3/6] scoring all candidates\n      done  (10.6s)\n[4/6] semantic refinement on top 500\n      done  (11.0s)\n[5/6] selecting top 100\n[6/6] writing submission.csv\n      done  (0.0s)\n\ndone  total=29.0s\n  [  1] CAND_0041669  Recommendation Systems Engineer  8.0yrs\n  [  2] CAND_0011687  Senior NLP Engineer  7.8yrs\n  [  3] CAND_0064326  Search Engineer  7.6yrs\n  [  4] CAND_0052682  NLP Engineer  6.6yrs\n  [  5] CAND_0017960  Recommendation Systems Engineer  7.7yrs\n\n$ make validate\nSubmission is valid.\n```\n\n---\n\n## Demo\n\n\u003e **[Live sandbox on HuggingFace Spaces →](https://huggingface.co/spaces/AmareshHebbar/hiresignal)**\n\n![HireSignal live demo](screenshots/hiresignal_4.png)\n\n## Output\n\n![Top 10 ranked candidates](screenshots/hiresignal_5.png)\n\n## Pipeline\n\n![Pipeline run](screenshots/hiresignal_1.png)\n\n![Submission validated](screenshots/hiresignal_2.png)\n\n![Tests passing](screenshots/hiresignal_3.png)\n\n\n---\n\n## Architecture\n\n```\n                        candidates.jsonl  (100,000 profiles)\n                               │\n                               ▼\n              ┌────────────────────────────────┐\n              │      HONEYPOT DETECTION        │\n              │                                │\n              │  expert skill + 0 months use   │\n              │  career months \u003e 1.6× YoE      │\n              │  9+ expert skills listed       │\n              │  start_date before 2005        │\n              │  is_current=True + end_date    │\n              │                                │\n              │  → 85 flagged, score = 0.001   │\n              └────────────────┬───────────────┘\n                               │ 99,915 clean candidates\n                               ▼\n        ┌──────────────────────────────────────────────┐\n        │              MULTI-SIGNAL SCORING            │\n        │                                              │\n        │  ┌─────────────────┐  ┌──────────────────┐  │\n        │  │  SKILL MATCH    │  │ CAREER TRAJECTORY │  │\n        │  │    40% weight   │  │    35% weight     │  │\n        │  │                 │  │                   │  │\n        │  │ proficiency ×   │  │ title quality     │  │\n        │  │ duration ×      │  │ company type      │  │\n        │  │ endorsements ×  │  │ YoE band (6-8yr)  │  │\n        │  │ assessments     │  │ prod AI evidence  │  │\n        │  └─────────────────┘  │ location          │  │\n        │                       └──────────────────┘  │\n        │  ┌──────────────────────────────────────┐    │\n        │  │      BEHAVIORAL SIGNALS  25% weight  │    │\n        │  │                                      │    │\n        │  │  last_active_date    response_rate   │    │\n        │  │  notice_period       github_activity │    │\n        │  │  profile_completeness  verifications │    │\n        │  └──────────────────────────────────────┘    │\n        └─────────────────────┬────────────────────────┘\n                              │ sorted, top 500\n                              ▼\n              ┌────────────────────────────────┐\n              │    SEMANTIC REFINEMENT         │\n              │    paraphrase-MiniLM-L6-v2     │\n              │                                │\n              │  JD text → embedding           │\n              │  candidate profile → embedding │\n              │  cosine similarity → +20% blend│\n              └────────────────┬───────────────┘\n                               │ re-sorted\n                               ▼\n              ┌────────────────────────────────┐\n              │       TOP 100 + REASONING      │\n              │                                │\n              │  per-candidate explanation     │\n              │  references actual facts       │\n              │  honest about gaps             │\n              └────────────────────────────────┘\n                               │\n                        submission.csv\n```\n\n---\n\n## Scoring model\n\n| Component | Weight | What it measures |\n|---|---|---|\n| Skill match | 40% | JD-required skills weighted by proficiency × duration × endorsements × assessment scores |\n| Career trajectory | 35% | Title quality, company type, YoE band, production AI evidence, location |\n| Behavioral signals | 25% | Availability, responsiveness, engagement — treats inactivity as an availability gate |\n| Semantic similarity | +20% blend | Sentence-transformer cosine sim on top-500 only — stays within 5-min budget |\n\n### Why behavioral signals are a gate, not a bonus\n\nThe JD explicitly says:\n\n\u003e *\"A perfect-on-paper candidate who hasn't logged in for 6 months and has a 5% recruiter response rate is, for hiring purposes, not actually available.\"*\n\nSo a candidate with great skills but 200+ days inactive gets significantly down-weighted — not penalized slightly.\n\n### Why pure consulting careers get penalized\n\nThe JD explicitly names TCS, Infosys, Wipro, Accenture, Cognizant, Capgemini as patterns they want to move away from. A candidate whose entire career is at these firms gets a `0.2` company score regardless of their skill list.\n\n---\n\n## Honeypot detection\n\nThe dataset contains ~85 impossible profiles designed to catch naive rankers. We detect them with five logical impossibility checks:\n\n```python\n# 1. Expert proficiency + 0 months of actual use on 2+ skills\nexpert_zero = [s for s in skills\n               if s[\"proficiency\"] == \"expert\" and s.get(\"duration_months\", 1) == 0]\nif len(expert_zero) \u003e= 2:\n    return True\n\n# 2. Sum of career months \u003e 1.6× claimed years_of_experience\nif total_career_months \u003e yoe * 12 * 1.6 and total_career_months \u003e 36:\n    return True\n\n# 3. 9+ skills listed as \"expert\" — keyword stuffer pattern\nif sum(1 for s in skills if s[\"proficiency\"] == \"expert\") \u003e= 9:\n    return True\n\n# 4. Job start_date before 2005 for someone with \u003c 20 YoE\nif yoe \u003c 20 and any(int(job[\"start_date\"][:4]) \u003c 2005 for job in career):\n    return True\n\n# 5. is_current=True but end_date is set — logical contradiction\nif any(j.get(\"is_current\") and j.get(\"end_date\") for j in career):\n    return True\n```\n\nAll honeypots score `0.001` and never appear in top-100. The original code had a sixth rule (`skill.duration_months \u003e yoe * 12`) that was incorrectly flagging 9,231 legitimate candidates — caught and fixed during development.\n\n---\n\n## Project structure\n\n```\nhiresignal/\n│\n├── rank.py                     entry point (7 lines)\n├── Makefile                    make rank / validate / test / setup\n├── requirements.txt\n├── app.py                      Gradio demo for HuggingFace Spaces\n│\n├── src/\n│   ├── pipeline.py             orchestrates all 6 steps\n│   ├── loader.py               reads candidates.jsonl line by line\n│   ├── jd.py                   JD constants — skill lists, title sets, cities\n│   │\n│   ├── filters/\n│   │   └── honeypot.py         5 impossibility checks\n│   │\n│   ├── scoring/\n│   │   ├── skills.py           skill match scorer\n│   │   └── career.py           career trajectory scorer\n│   │\n│   ├── signals/\n│   │   └── behavioral.py       23 Redrob platform signals\n│   │\n│   ├── embed/\n│   │   └── encoder.py          sentence-transformer on top-500\n│   │\n│   └── output/\n│       ├── writer.py           CSV output + validation asserts\n│       └── reasoning.py        per-candidate reasoning strings\n│\n├── scripts/\n│   ├── download_model.py       one-time model download\n│   └── check_output.py         inspect top-10 with full profile details\n│\n├── tests/\n│   ├── test_honeypot.py        5 tests\n│   └── test_scoring.py         5 tests\n│\n└── dataset/\n    ├── sample_candidates.json  first 50 candidates\n    ├── sample_submission.csv   format reference\n    ├── validate_submission.py  official format validator\n    └── candidate_schema.json   JSON schema for candidate objects\n```\n\n---\n\n## Quickstart\n\n```bash\ngit clone https://github.com/amareshhebbar/hiresignal\ncd hiresignal\n\nmake setup                    \nsource .venv/bin/activate\n\nmake model                    \nmake rank                    \nmake validate                \nmake test                    \n```\n\nManual:\n\n```bash\npython rank.py --candidates dataset/candidates.jsonl --out submission.csv\npython dataset/validate_submission.py submission.csv\n```\n\n---\n\n## Compute profile \u003ca name=\"compute\"\u003e\u003c/a\u003e\n\n```\nPlatform   Fedora Linux, 8-core CPU\nMemory     ~2.5 GB peak\nRuntime    ~29s (rule-based only) / ~35s (with cached embeddings)\nNetwork    none during ranking\nGPU        not used\n```\n\nPre-computation (`make model`) downloads the sentence-transformer model (~90MB) once to `.model_cache/`. The ranking step itself has zero network dependency — satisfies the submission spec constraint.\n\n---\n\n## Tests\n\n```bash\nmake test\n\n# ===== test session starts =====\n# tests/test_honeypot.py::test_clean_passes               PASSED\n# tests/test_honeypot.py::test_expert_zero_months         PASSED\n# tests/test_honeypot.py::test_career_months_inflated     PASSED\n# tests/test_honeypot.py::test_too_many_expert_skills     PASSED\n# tests/test_honeypot.py::test_is_current_with_end_date   PASSED\n# tests/test_scoring.py::test_ai_engineer_scores_above_zero         PASSED\n# tests/test_scoring.py::test_more_skills_scores_higher             PASSED\n# tests/test_scoring.py::test_disqualifying_title_gets_very_low     PASSED\n# tests/test_scoring.py::test_ideal_yoe_band_boosts_career          PASSED\n# tests/test_scoring.py::test_india_location_preferred              PASSED\n# ===== 10 passed in 0.07s =====\n```\n\n---\n\n## Submission\n\n| Field | Value |\n|---|---|\n| Track | Track 1 — Data \u0026 AI Challenge |\n| Hackathon | INDIA RUNS — Redrob AI × Hack2Skill |\n| Deadline | July 2, 2026 |\n| Reproduce | `python rank.py --candidates ./dataset/candidates.jsonl --out ./submission.csv` |\n| Sandbox | [huggingface.co/spaces/AmareshHebbar/hiresignal](https://huggingface.co/spaces/AmareshHebbar/hiresignal) |\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nBuilt by [G V Amaresh](https://linkedin.com/in/gvamaresh) \u0026nbsp;·\u0026nbsp; [HuggingFace](https://huggingface.co/AmareshHebbar) \u0026nbsp;·\u0026nbsp; [LinkedIn](https://linkedin.com/in/gvamaresh)\n\n\u003c/div\u003e\n\n\u003c!-- docs pass: 2026-07-03T04:33:19Z --\u003e\n\n\u003c docs pass retry: 2026-07-03T04:44:14Z --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famareshhebbar%2Fhiresignal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famareshhebbar%2Fhiresignal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famareshhebbar%2Fhiresignal/lists"}