{"id":51843131,"url":"https://github.com/be-mohand/pitch-back-engine","last_synced_at":"2026-07-23T09:01:07.282Z","repository":{"id":371439622,"uuid":"1301029492","full_name":"be-mohand/pitch-back-engine","owner":"be-mohand","description":"Open-source cold email detection engine. Transparent YAML rules, additive scoring, explainable verdicts — no AI, no black box. Powers Pitch Back, the reverse card for cold emails.","archived":false,"fork":false,"pushed_at":"2026-07-15T01:29:06.000Z","size":25,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-15T03:13:54.603Z","etag":null,"topics":["anti-spam","cold-email","detection-rules","email-filtering","open-source","php","yaml"],"latest_commit_sha":null,"homepage":"https://pitch-back.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/be-mohand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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-07-14T23:36:45.000Z","updated_at":"2026-07-15T01:29:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/be-mohand/pitch-back-engine","commit_stats":null,"previous_names":["be-mohand/pitch-back-engine"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/be-mohand/pitch-back-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/be-mohand%2Fpitch-back-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/be-mohand%2Fpitch-back-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/be-mohand%2Fpitch-back-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/be-mohand%2Fpitch-back-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/be-mohand","download_url":"https://codeload.github.com/be-mohand/pitch-back-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/be-mohand%2Fpitch-back-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35796817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","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":["anti-spam","cold-email","detection-rules","email-filtering","open-source","php","yaml"],"created_at":"2026-07-23T09:01:06.191Z","updated_at":"2026-07-23T09:01:07.267Z","avatar_url":"https://github.com/be-mohand.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pitch Back Engine\n\n\u003e Sales teams automated prospecting. This engine automates rejecting it — politely,\n\u003e transparently, and without a single LLM.\n\n**pitch-back-engine** detects commercial cold emails using transparent, community-maintained\nYAML rules. Every verdict is fully explainable: which rules fired, what each one weighs,\nand how the score adds up. No AI, no network calls, no black box.\n\nIt powers [Pitch Back](https://pitch-back.com) — the app that replies to cold emails\nwith *your* pitch and archives the thread — but it is a standalone library you can embed\nin any PHP project.\n\n## How it works\n\nOne rule = one YAML file in [`rules/`](rules/):\n\n```yaml\nid: lemlist\nlabel: Sent through Lemlist\nmatch:\n  header:\n    x-mailer: Lemlist\nscore: 40\n```\n\nFeed the engine a normalized email, get an explainable verdict:\n\n```php\nuse PitchBack\\Engine\\DetectionEngine;\nuse PitchBack\\Engine\\NormalizedEmail;\nuse PitchBack\\Engine\\RuleLoader;\n\n$engine = new DetectionEngine(RuleLoader::fromDirectory('rules'));\n\n$verdict = $engine-\u003eanalyze(NormalizedEmail::fromArray([\n    'messageId' =\u003e 'abc123',\n    'from' =\u003e ['name' =\u003e 'Jake Miller', 'email' =\u003e 'jake@growthmotion.io'],\n    'to' =\u003e ['you@company.com'],\n    'subject' =\u003e 'Quick question about your outbound',\n    'bodyText' =\u003e \"Grab 15 minutes? calendly.com/jake\\n\\nJake — SDR at GrowthMotion\",\n    'headers' =\u003e ['X-Mailer' =\u003e 'Lemlist 5.2'],\n    'context' =\u003e ['isFirstContact' =\u003e true, 'userHasRepliedBefore' =\u003e false],\n]));\n\n$verdict-\u003escore;          // 97 (0–100, clamped)\n$verdict-\u003eclassification; // 'prospecting' | 'unsure' | 'legit'\n$verdict-\u003ereasons;        // [['ruleId' =\u003e 'lemlist', 'label' =\u003e 'Sent through Lemlist', 'weight' =\u003e 40], …]\n```\n\nOr from the command line:\n\n```\n$ bin/analyze email.json\n\n  Score          97%\n  Classification PROSPECTING\n\n  Reasons\n    ✓ Sent through Lemlist                     (lemlist)            +40\n    ✓ First contact ever                       (first-contact)      +20\n    ✓ Calendly link in body                    (calendly)           +15\n    ✓ Asks for a quick call or meeting         (meeting-ask)        +12\n    ✓ SDR-style signature                      (sdr-signature)      +10\n```\n\n## Scoring model\n\n- Rule weights are **summed**, clamped to 0–100. There is no machine learning anywhere.\n- Default thresholds: **≥ 90** → `prospecting`, **≥ 60** → `unsure`, below → `legit`\n  (both configurable via the `DetectionEngine` constructor).\n- Inside a rule's `match` block: multiple keys are **AND**, values listed under a key are **OR**.\n\nAvailable matchers: `header`, `header_present`, `body_contains`, `subject_contains`,\n`body_regex`, `html_regex`, `from_domain`, `from_email_regex`, `context`\n(see [`src/Rule.php`](src/Rule.php) for exact semantics).\n\n## Install\n\n```\ncomposer require be-mohand/pitch-back-engine\n```\n\nRequires PHP ≥ 8.2. Only dependency: `symfony/yaml`.\n\n## Contributing a rule\n\nFound a cold email that slipped through? That's a missing rule — and one PR away\nfrom protecting every user. See [CONTRIBUTING.md](CONTRIBUTING.md); the short version:\n\n1. Add `rules/your-rule.yaml`\n2. Add a triggering fixture to `tests/DetectionEngineTest.php` (a test enforces 1:1 coverage — CI fails without it)\n3. Open a PR\n\nLike EasyList for ad blocking or YARA rules for malware, this ruleset gets stronger\nwith every contribution.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbe-mohand%2Fpitch-back-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbe-mohand%2Fpitch-back-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbe-mohand%2Fpitch-back-engine/lists"}