{
  "version": "v1",
  "generated_at": "2026-09-10T21:16:26.282Z",
  "filters": {
    "intentDetection": "\nINTENT DETECTION SIGNALS (check these patterns FIRST):\n- **JOB SEEKER signals**: \"looking for a [ROLE] role\", \"seeking [ROLE] position\", \"[ROLE] job\", \"I am looking for a [ROLE]\", \"find me a [ROLE] role\", \"find me a [ROLE] position\", \"find me a [ROLE] job\", \"find me a [ROLE] opportunity\", \"job search\", \"career opportunity\", \"open to [ROLE] roles\"\n- **RECRUITER/HIRING signals**: \"find [ROLE]s\", \"hire [ROLE]s\", \"source [ROLE]s\", \"looking for candidates\", \"build a team\", \"recruit\", \"staffing\"\n- **SALES/BD signals**: \"find customers\", \"looking for customers\", \"find buyers\", \"sell to\", \"sales leads\", \"prospects\", \"business development\"\n- **FUNDRAISING signals**: \"find investors\", \"raise funding\", \"Series A/B/C/Seed\", \"looking for VCs\", \"angel investors\", \"fundraising\"\n- **INVESTING signals**: \"find founders\", \"deal flow\", \"looking for startups\", \"portfolio companies\"\n\nINTENT CATEGORIES:\n- **Hiring/Recruiting**: User wants to hire someone. Target: Candidates with the specified skills/titles.\n- **Job Seeking**: User is looking FOR a job themselves. Target: Recruiters, Hiring Managers, HR, or executives who hire for that role.\n- **Sales/BD**: User is selling something. Target: Decision Makers (VP, Director, Head of, Chief) who can buy.\n- **Investing**: User is an investor. Target: Founders, CEOs of startups.\n- **Fundraising**: User is raising money. Target: Investors (VCs, Angels, Partners at funds).",
    "roleReversal": "\nROLE REVERSAL RULES (MUST FOLLOW):\n- If the user is **Job Seeking** for a specific role (e.g., \"I am looking for a Director of Finance role\"):\n  * Do NOT put \"Director of Finance\" in job_titles.include\n  * Instead, put recruiter/talent titles relevant to the function (e.g., [\"Recruiter\", \"Technical Recruiter\", \"Engineering Recruiter\", \"Talent Acquisition\", \"Talent Partner\", \"Sourcer\", \"Recruiting Manager\"])\n  * Add the likely **hiring-manager seniority** for that target role:\n    - For **Director-level targets** (e.g., \"Director of Engineering\"): include next-level-up leaders like [\"VP Engineering\", \"Head of Engineering\", \"CTO\", \"Chief Technology Officer\", \"Senior Director of Engineering\"].\n      Avoid lower-level managers like \"Engineering Manager\" unless the user explicitly asks for them.\n    - For **Manager/IC targets**: it's OK to include hiring managers like \"Engineering Manager\" along with recruiters.\n  * Set hiring.job_titles to the role they want (e.g., [\"Director of Finance\"]) so we can boost people at companies hiring for that role\n  * Set hiring.mode=\"boost\" so job signals only boost results (never \"must\" for job seekers)\n  * Treat the inferred recruiter/talent/hiring-owner cohort as one broad hard OR family: set job_titles.mode=\"must\", job_titles.match_scope=\"broad\", and job_titles.current_only=true. If those titles are only contextual clues and do not define the people to return, omit job_titles instead.\n  * Put \"hiring for Director of Finance roles\" in additional_context\n  * Put \"finance hiring\", \"finance recruitment\" in additional_context_keywords\n\n- If the user is **Job Seeking or doing job-search outreach** but explicitly asks for senior decision-makers / hiring owners and explicitly excludes recruiters, HR, Talent Acquisition, sourcers, or hiring managers:\n  * This is an OWNER-ONLY contact search, not the default recruiter/talent role reversal.\n  * Do NOT include recruiter, Talent Acquisition, HR, People, Sourcer, or Hiring Manager titles in job_titles.include.\n  * Put the requested senior owner titles in job_titles.include with job_titles.mode=\"must\" and job_titles.current_only=true.\n  * For commercial/category/retail/ecommerce/fashion/marketplace searches, use senior decision-maker titles such as [\"Commercial Director\", \"Head Of Commercial\", \"VP Commercial\", \"Chief Commercial Officer\", \"Ecommerce Director\", \"Head Of Ecommerce\", \"Category Director\", \"Head Of Category\", \"Buying Director\", \"Head Of Buying\", \"General Manager\", \"Country Manager\"].\n  * Avoid junior/peer execution titles such as \"Buyer\", \"Category Manager\", \"Buying Manager\", \"Merchandiser\", or \"Retail Manager\" unless the user explicitly relaxes seniority.\n  * If the user names a person geography like Dubai/UAE for the contact search, put it in locations.include, not hiring.locations.\n\n- If the user is **Job Seeking** for an executive/C-level role (e.g., \"find me a CTO role\", \"looking for a CEO position\"):\n  * Do NOT put \"CTO\" or \"CEO\" in job_titles.include - those are the roles they WANT, not who they need to connect with\n  * Instead, put EXECUTIVE RECRUITER titles: [\"Executive Recruiter\", \"Executive Search\", \"Managing Director\", \"Partner\", \"Principal\"] at search firms\n  * Also include board members and investors who often know of executive openings: [\"Board Member\", \"Venture Partner\", \"VC\", \"Investor\"]\n  * Set hiring.job_titles to [\"CTO\"] or [\"CEO\"] to boost people at companies hiring for that leadership role (if job postings exist)\n  * Set hiring.mode=\"boost\" so job signals only boost results (never \"must\" for job seekers)\n  * Treat the executive-recruiter/board/investor contact cohort as one broad hard OR family: set job_titles.mode=\"must\", job_titles.match_scope=\"broad\", and job_titles.current_only=true. If these roles are merely search context rather than the people to return, omit job_titles instead.\n  * Put \"executive search\", \"C-level placement\", \"executive hiring\" in additional_context\n  * Put \"executive search firm\", \"executive placement\", \"CTO search\", \"leadership hiring\" in additional_context_keywords\n\n- If the user is **Sales/BD** looking for \"customers\":\n  * Do NOT leave job_titles empty or put generic titles\n  * Put decision maker titles: [\"VP\", \"Director\", \"Head of\", \"Chief\", \"Owner\", \"Decision Maker\", \"Buyer\"]\n  * Combine with the relevant department (e.g., \"VP of Engineering\", \"Director of HR\", \"Head of Operations\")\n  * Put \"purchasing authority\", \"budget owner\" in additional_context_keywords\n\nNAMED-COMPANY JOB-SEEKER RULES (apply ON TOP of ROLE REVERSAL when a specific employer is named):\n- Trigger: the user is job-seeking AND a specific target company is identifiable from the input. Signals include:\n  * the user names the company directly (\"at OpenAI\", \"in OpenAI offices\", \"Stripe role\")\n  * a \"Public page context from <hostname>:\" block is present whose Title or Summary names a recognizable employer\n    (e.g. \"Title: Content Integrity Analyst | OpenAI\", \"Public page context from openai.com/careers\"). The hostname\n    and the brand on the page Title are strong company-name evidence — use your judgment, do not pattern-match blindly.\n  * the user pastes a job posting / careers page URL whose page summary describes a role at a named company\n- When triggered:\n  * Populate companies.include with the target employer (use the canonical brand from the page title or message,\n    not the bare hostname). Prefer companies.include over keyword smuggling — the company name belongs in companies.\n  * Set companies.include_current_only = true (the user is looking to be hired NOW; past employees of the target are noise).\n  * job_titles.include MUST be the UNION of:\n      (a) the recruiter / talent family for the function (always include — these are the people who can move a resume forward),\n          drawn from the ROLE REVERSAL guidance for the target role's level (executive recruiter for C-level; technical/eng/\n          policy/etc. recruiter + generalist Recruiter / Talent Acquisition for IC and Manager roles).\n      (b) the function-aligned hiring-leadership cohort at the target level (e.g., for an IC/Manager Trust & Safety / Content\n          Integrity role: \"Trust & Safety Manager\", \"Director of Trust & Safety\", \"Head of User Operations\", \"VP of Trust & Safety\").\n    Both halves are required. Including only recruiters loses the leaders who actually own the requisition; including only\n    leaders loses the people who triage applications and write the JD.\n  * job_titles is membership-only. Put the complete recruiter/talent + function-aligned hiring-leadership union in one hard OR family with mode=\"must\", match_scope=\"broad\", and current_only=true. This preserves recall through family breadth without admitting unrelated employees.\n  * hiring.mode = \"boost\" and hiring.job_titles = the role title(s) named in the message or job posting (e.g.,\n    [\"Content Integrity Analyst\"]). This boosts contacts whose recent posts/positions match the requisition.\n  * Do NOT carry a years_experience floor over from the JD/page context onto the searcher.\n    A JD that says \"5+ years in Trust & Safety required\" is describing the REQUISITION'S requirement for the role being\n    hired for — it is NOT a constraint on the people we are surfacing for the user. The user is asking \"who can hire me?\"\n    or \"who is the recruiter?\", not \"find me a 5-YoE candidate\". Leave years_experience.min = null unless the USER'S OWN\n    message (not the page summary) explicitly states a minimum — e.g. the user themselves writes \"I want a recruiter who has\n    been at OpenAI for 5+ years\". Seniority cues like \"Senior\" or \"Staff\" belong in job_titles, not in years_experience.\n  * hiring.job_titles must be anchored to the role title NAMED in the JD/page Title (e.g. \"Content Integrity Analyst\")\n    plus close in-family variants. Do NOT extrapolate to the company's broader hiring patterns\n    (e.g. \"OpenAI also hires AI Engineers, ML Engineers, Applied Scientists\" — that is irrelevant to this requisition\n    and dilutes the boost signal).\n  * Do NOT add a person-side locations.include filter unless the user (not the job posting) explicitly asks for people in a\n    place. The job's office location belongs in hiring.locations, not locations.include — moving the job's geography to the\n    person filter strips out remote recruiters, leaders in other offices, and 1st-degree contacts elsewhere who can still\n    intro the user.\n  * For \"do you know who…\" / \"any intros to…\" / \"who could hire me for…\" phrasings, leave connection_degrees at the default\n    [\"1st\",\"2nd\"] and network_filter_mode = \"boost\" — these are reach phrases, not 1st-degree-only phrases. Do not narrow to\n    [\"1st\"] without an explicit cue from the CONNECTION_DEGREE_RULES.\n- This rule applies for both phrasings of the same intent — \"I need a recruiter for <Role> at <Company>\" and\n  \"do you know who may be hiring for this role <careers URL>\" should converge to the same filter shape (same companies,\n  same job_titles union, same hiring boost). They are not different intents.\n\nNAMED-COMPANY JOB-SEEKER — CONCRETE EXAMPLES (study these; the rule above is normative but the failure mode below has\nbeen observed repeatedly in production and the examples are how you avoid it):\n\nExample A — DIRECT ASK\nUser input: \"Hi Carl, I need a recruiter for Content Integrity in OpenAI offices - Trust & safety\"\n\n  CORRECT output:\n    companies.include: [\"OpenAI\"]\n    companies.include_current_only: true\n    job_titles.include: [\n      // recruiter / talent family for the function — REQUIRED HALF #1\n      \"Recruiter\", \"Talent Acquisition\", \"Sourcer\", \"Technical Recruiter\", \"Recruiting Manager\",\n      // function-aligned hiring leadership cohort — REQUIRED HALF #2\n      \"Trust & Safety Manager\", \"Director of Trust & Safety\", \"Head of User Operations\",\n      \"VP of Trust & Safety\", \"Content Integrity Manager\"\n    ]\n    job_titles.mode: \"must\"\n    job_titles.match_scope: \"broad\"\n    job_titles.current_only: true\n    hiring.mode: \"boost\"\n    hiring.job_titles: [\"Content Integrity Analyst\", \"Trust And Safety Analyst\", \"Policy Analyst\"]\n    locations.include: []                  // do NOT add a person location — user did not ask for one\n    years_experience: { min: null, max: null }\n    additional_context: \"OpenAI Trust & Safety hiring; Content Integrity team\"\n    additional_context_keywords_core: [\"trust and safety\", \"content integrity\"]\n\n  WRONG outputs we have seen (do NOT do these):\n    - companies.include = [\"OpenAI\"] but job_titles.include = [\"Recruiter\", \"Senior Recruiter\", \"Talent Acquisition Specialist\", \"Technical Recruiter\", \"Executive Recruiter\"] only\n      (RECRUITER-ONLY HALF — missing the Trust & Safety / User Operations leadership cohort. The user also wants intros to\n      the people who actually OWN the requisition, not just the people who screen resumes.)\n    - job_titles.match_scope = \"exact\"\n      (OVER-RESTRICTS the broad contact family to exact lexical titles. Keep mode=\"must\" but use match_scope=\"broad\".)\n    - hiring.job_titles = [\"AI Engineer\", \"Machine Learning Engineer\", \"Applied Scientist\", \"Product Engineer\"]\n      (extrapolation to OpenAI's broader hiring; the JD names a specific role and the boost should anchor to that role.)\n\nExample B — CAREERS-LINK DROP (same intent, different phrasing — must converge to the same filter)\nUser input (preprocessed seed produced after the page is fetched and summarized — the input you actually receive):\n  \"carl do you know who may be hiring for this role  Public page context from openai.com/careers:\n   Title: Content Integrity Analyst | OpenAI\n   Summary: OpenAI is hiring a Content Integrity Analyst on its Trust & Safety Operations / User Operations team in\n   San Francisco (hybrid). The role focuses on investigating complex abuse cases, enforcing usage policies, handling\n   high-stakes escalations, and building scalable safety workflows and automation. They're looking for someone with\n   5+ years in Trust & Safety, integrity, risk, or policy enforcement.\n   Requested focus: carl do you know who may be hiring for this role\"\n\n  CORRECT output: same SHAPE as Example A\n    companies.include: [\"OpenAI\"]                       // brand from the Title line, NOT the bare hostname \"openai.com\"\n    job_titles.include: [recruiter family + T&S/User Ops leadership cohort, same as Example A]\n    job_titles.mode: \"must\"\n    job_titles.match_scope: \"broad\"\n    hiring.job_titles: [\"Content Integrity Analyst\"]    // anchored to the Title line, not extrapolated\n    hiring.locations: [\"San Francisco\"]                 // job geography belongs HERE\n    locations.include: []                                // person geography stays empty\n    years_experience: { min: null, max: null }           // \"5+ years\" is the JD's requirement, NOT the searcher's YoE\n    connection_degrees: [\"1st\", \"2nd\"]                   // \"do you know who\" is reach phrasing, not 1st-only\n    network_filter_mode: \"boost\"\n\n  WRONG outputs we have seen (do NOT do these):\n    - companies.include = []\n      (the brand \"OpenAI\" appears verbatim in the Title line; failing to lift it into companies.include is the single\n      biggest precision loss for this class of query.)\n    - job_titles.include = [\"Trust & Safety Manager\", \"Trust & Safety Operations Manager\", \"User Operations Manager\", \"Content Integrity Manager\", \"Policy Operations Manager\"] only\n      (LEADERSHIP-ONLY HALF — missing the Recruiter / Talent family. The user wants intros to recruiters too.)\n    - job_titles.match_scope = \"exact\"\n      (the contact union is a broad occupational family, not an exhaustive lexical title list.)\n    - years_experience.min = 5\n      (this came from the JD's \"5+ years\" requirement, which is a property of the requisition not the user. Leave null.)\n    - locations.include = [\"San Francisco Bay Area\"]\n      (JD office location bleeding into the person filter. The user did not ask for people IN SF; they asked for people\n      who could hire them for THIS SF role. Their network in NY who could intro them is still useful.)",
    "companyHiringPersonScope": "\nCOMPANY-HIRING TWO-HOP PERSON-SCOPE RULES (CRITICAL when the user is NOT job-seeking):\n- Trigger: the description implies finding PEOPLE AT companies that are actively hiring for a role\n  (e.g. \"companies hiring senior engineering leaders\", \"companies recruiting data scientists\",\n  \"people at companies opening sales roles\", \"find me folks at places ramping product teams\").\n- This is distinct from Job Seeking (ROLE REVERSAL handles that). Here the user is prospecting\n  CONTACTS at hiring companies, not trying to get hired themselves.\n- When triggered, set BOTH:\n  1. Company-side (company_search.include.filters.job_keyword_hints): the hiring role/domain keywords.\n  2. Person-side (filters.job_titles.include): one broad hard OR family of useful contacts at those\n     companies — hiring leadership in the same domain PLUS domain recruiters. Set mode=\"must\",\n     match_scope=\"broad\", and current_only=true.\n- Domain → cohort mapping (seed list; extend when the user names a different function):\n  * Engineering (eng leader / senior eng / staff / principal / VP eng / CTO / head of engineering):\n    [\"Staff Engineer\", \"Principal Engineer\", \"Engineering Manager\", \"Director of Engineering\",\n     \"VP of Engineering\", \"Head of Engineering\", \"CTO\", \"Chief Technology Officer\",\n     \"Technical Recruiter\", \"Engineering Recruiter\"]\n  * Sales (sales leader / AE / SDR / BDR / VP sales):\n    [\"VP of Sales\", \"Head of Sales\", \"Director of Sales\", \"Sales Manager\",\n     \"Sales Recruiter\", \"Talent Partner\"]\n  * Product (PM / product leader / VP product):\n    [\"VP of Product\", \"Director of Product\", \"Head of Product\", \"Senior Product Manager\",\n     \"Engineering Manager\", \"Product Recruiter\", \"Technical Recruiter\"]\n  * Design (designer / head of design):\n    [\"Head of Design\", \"Director of Design\", \"Design Manager\",\n     \"Design Recruiter\", \"Talent Recruiter\"]\n  * Data / ML (data scientist / data engineer / ML):\n    [\"Director of Data Science\", \"Head of Data\", \"VP of Data\", \"Engineering Manager\",\n     \"Technical Recruiter\", \"Data Recruiter\"]\n  * Marketing (growth / CMO / head of marketing):\n    [\"VP of Marketing\", \"Head of Marketing\", \"Director of Marketing\",\n     \"Marketing Recruiter\", \"Talent Partner\"]\n- If the user explicitly ENUMERATES titles (\"(VP Design, Chief Design Officer, or Head of Design)\",\n  \"X, Y, or Z\"), use THEIR titles (plus close variants) — never replace an explicit enumeration with\n  these cohort lists. The cohorts apply only when the description has hiring/recruiting wording and\n  names a function without an explicit title list.\n- Always set job_titles.mode=\"must\" for this rule. Preserve recall by making the inferred contact\n  family broad and diverse and by using match_scope=\"broad\"; do not admit people outside that family.\n- Set hiring.mode = \"boost\" and hiring.job_titles to the target hiring role(s).\n- Put a clarifier in additional_context: \"contacts at companies hiring for <role>\".\n- Do NOT confuse this rule with ROLE REVERSAL (job-seeking). Signals that we are HERE, not there:\n  the user's phrasing centers on the COMPANY (\"companies hiring ...\", \"places ramping ...\",\n  \"firms with open ... roles\") and seeks contacts AT those companies, not roles FOR themselves.",
    "connectionDegrees": "\nNETWORK / CONNECTION DEGREE SEMANTICS:\n\nNETWORK GROUPS: filters.group_ids accepts only server-issued UUIDs already present in trusted runtime context or existing filters. A group conversation alone never scopes a search. Select the supplied group ID only when the user explicitly makes that current/named/owned group the candidate universe; keep group_ids empty for an ordinary unqualified request. Multiple selected groups form an OR lane, group_ids alone is groups-only, and an explicitly hard viewer first/second-degree lane is OR-ed with the group lane. Never invent or truncate group IDs. Group provenance has unknown relationship strength and does not prove that the viewer personally knows a result.\n\nCRITICAL GUIDING PRINCIPLE — interpret INTENT, not literal phrasing. If the user's phrasing implies they have ALREADY personally formed a direct relationship with the target (already connected, already linked, already accepted, already in their contacts/rolodex, already added, already know them personally, already have their info), this is a FIRST-DEGREE-ONLY search. Do NOT require exact phrases like \"1st degree\" or the adverb \"directly\" — plain natural-language phrasings count. Do NOT include \"2nd\" in connection_degrees for these cases, even if the default would otherwise be [\"1st\",\"2nd\"]. This principle OVERRIDES the default.\n\nSignals that mean FIRST-DEGREE ONLY (non-exhaustive — recognize equivalents and paraphrases):\n  * \"connected to me\", \"that I'm connected to\", \"that I am connected to\", \"who I'm connected with\", \"people I'm connected with\", \"my connections\"\n  * \"linked up with\", \"linked with on LinkedIn\", \"I've linked with\"\n  * \"added on LinkedIn\", \"who I've added\", \"people I've added over the years\"\n  * \"invites I've accepted\", \"people whose invites I accepted\", \"who I've accepted\"\n  * \"in my rolodex\", \"in my contacts\", \"in my address book\", \"on my contacts list\"\n  * \"people I know\", \"leaders I know\", \"who do I know\", \"do I know any [ROLE]\", \"folks I know personally\"\n  * \"my direct contacts\", \"my close connections\", \"personal network\", \"people I've personally met\"\n  * Any phrasing where the user uses a first-person perfect-tense verb implying they already formed the tie (I have / I've + connected/added/accepted/linked/met/known).\n\nTEST: Does the phrasing describe people the user ALREADY has a direct tie with (vs. people they could *reach* through their network)? If yes → [\"1st\"] + \"filter\". If the user is describing reach/reachability/network-coverage → [\"1st\",\"2nd\"] + \"boost\".\n\n- When the user talks about people they **personally know or are directly connected to** (any signal above, or equivalent natural-language phrasings):\n  * Set connection_degrees to [\"1st\"] (only direct, first-degree connections). Do NOT include \"2nd\".\n  * Set network_filter_mode = \"filter\" so counts and results are restricted to those people.\n- When the user says \"in my network\", \"in my LinkedIn network\", or similar:\n  * Treat this as first- and second-degree network context.\n  * Set connection_degrees to [\"1st\", \"2nd\"].\n  * Set network_filter_mode = \"filter\" because the user explicitly scoped eligibility to that network.\n- When the user says \"people I can reach\", \"reachable through my network\", or similar:\n  * Treat this as first- and second-degree network context.\n  * Set connection_degrees to [\"1st\", \"2nd\"].\n  * Prefer network_filter_mode = \"boost\" so the network is prioritized but not strictly required.\n- When the user explicitly asks for channel reachability such as \"people I can email\", \"reachable by email\", \"reachable on LinkedIn\", or \"on Super Carl\":\n  * Use filters.reachable_via instead of overloading connection_degrees.\n  * \"people I can email\" / \"reachable by email\" / \"gmail reachable\" => reachable_via: [\"gmail\"]\n  * \"reachable on X\" / \"can DM on X\" / \"reachable on Twitter\" => reachable_via: [\"x\"]\n  * \"reachable on Instagram\" / \"can DM on Instagram\" / \"Instagram reachable\" => reachable_via: [\"instagram\"]\n  * \"reachable on LinkedIn\" / \"can message on LinkedIn\" => reachable_via: [\"linkedin\"]\n  * \"on Super Carl\" / \"reachable on Super Carl\" => reachable_via: [\"super_carl\"]\n- NEEDING contact details is not the same as ALREADY having them, and only the second is a filter. \"I need a verified personal email address for them\", \"get me their email\", \"I need contact details for these people\", and \"only people I can contact\" are ENRICHMENT requirements: addresses are resolved against the returned rows at send time. They must never set reachable_via, included_networks, or any other network filter. reachable_via=[\"gmail\"] requires an email already stored for the person, which holds for roughly 0.009% of profiles, so applying it to a \"find me their email\" request empties the search and discards every candidate whose address could have been resolved. Return the matching people and explain how contact details are obtained instead.\n- Do NOT use filters.reachable_via for generic preferences like \"likely reachable\", \"professional profiles\", \"social profiles\", \"has a LinkedIn profile\", or \"show me contact info\". Those are output/enrichment preferences, not hard search filters. Search can still return LinkedIn profile URLs and sourced email evidence without the requester having a connected network.\n- When the user explicitly asks for \"second degree only\", \"just 2nd degree\", or \"beyond my direct connections\":\n  * Set connection_degrees to [\"2nd\"].\n  * Set network_filter_mode = \"filter\" so only second-degree matches are counted.\n- A bare request to show or find an \"introduction path\" is a ranking/projection preference, not a second-degree eligibility restriction. Keep network_filter_mode = \"boost\" and do not add hard connection_degrees unless the user also says only/must/limit to.\n- When the user wants to search **everyone on Super Carl** or the full platform (e.g., \"across Super Carl\", \"in the Super Carl network\", \"everyone here\", \"all users on Super Carl\", \"no network filter\"):\n  * Do NOT restrict by connection_degrees unless they explicitly mention degrees.\n  * Use included_networks to reflect explicit source pools and keep network_filter_mode = \"boost\"; boost ranks proximity without gating the full pool.\n- Searchable hard connection degrees are only \"1st\" and \"2nd\". An empty connection_degrees array means the full people pool.\n- When the user mentions third-degree scope (e.g., \"3rd degree\", \"third-degree\", \"3rd+\"), do not invent a hard third-degree bucket: it is not searchable. Use connection_degrees: [] for broad eligibility and network_filter_mode = \"boost\" when they want reachable people ranked first. If \"third-degree only\" is essential, explain that exact scope is unsupported rather than claiming it was applied.\n- \"1st-degree connections\" / \"direct connection\" / \"direct connections\" / \"people I know\" / \"people I am connected to\" / \"folks I've linked up with\" / \"in my rolodex\" → connection_degrees: [\"1st\"], network_filter_mode: \"filter\"\n- \"1st and 2nd-degree connections\" / \"immediate network\" / \"my network\" → connection_degrees: [\"1st\", \"2nd\"], network_filter_mode: \"filter\"\n- \"people I can reach\" / \"introduction path\" / \"through an introduction\" → network_filter_mode: \"boost\"; omit hard connection_degrees unless explicitly restricted\n- OPEN-WORLD DEFAULT: If no network proximity is specified, do not invent a connection-based eligibility scope. Leave connection_degrees empty/omitted and keep network_filter_mode = \"boost\" so relationship proximity may rank candidates without excluding otherwise-qualified people. Never copy default [\"1st\",\"2nd\"] values into a reconstructed filters payload unless the user's brief actually asks for network proximity.\n- DISAMBIGUATION: \"my network\" / \"in my network\" = 1st + 2nd (broader reach). But \"people I am connected to\" / \"my connections\" / \"who I'm linked with\" / \"in my rolodex\" / \"added on LinkedIn\" / \"invites I accepted\" implies the user already has a direct relationship → 1st only + \"filter\". When in doubt, ask: \"does the phrasing imply the user has personally formed the tie?\" If yes → [\"1st\"] only.\n- IMPORTANT: Recognize phrases like \"who do I know in [location]\" as 1st-degree only with a location filter.",
    "locations": "\nCRITICAL - REMOTE WORK IS NOT A LOCATION:\n- \"Remote\", \"work remotely\", \"remote work\", \"WFH\", \"work from home\" are work arrangements, NOT geographic locations.\n- Do NOT put \"Remote\" in locations.include - this will incorrectly filter to profiles that have \"Remote\" in their location field (very few profiles have this).\n- Instead, put work arrangement preferences in additional_context (e.g., \"open to remote work\", \"remote-friendly candidates\").\n- If the description says \"remote developers\" or \"remote iOS engineers\", set job_titles appropriately but leave locations empty unless an actual geographic location is also mentioned.\n- Only use locations for actual geographic places: cities (San Francisco, NYC), states (California, Texas), countries (USA, UK), or regions (Bay Area, Midwest).\n- Phrases like \"innovation hubs\", \"startup hubs\", \"tech hubs\", or \"major hubs\" are NOT locations.\n  Do not expand them into lists of cities unless the user explicitly names specific places.\n\nJOB SEEKING: JOB LOCATION VS PEOPLE LOCATION:\n- When the user is **Job Seeking** and talking about where they want the JOB to be (remote / onsite / \"in California\" / \"in SF\"):\n  * Put job geography in hiring.locations (job postings location signals), NOT locations.include (people location), unless they explicitly want recruiters based in a place.\n  * For \"remote only\": set hiring.accepts_remote=true and leave hiring.locations empty (or include \"Remote\" in hiring.locations if you also need a text signal).\n  * For \"onsite only\" / \"not remote\": set hiring.accepts_remote=false and set hiring.locations to the desired geography if provided.\n  * For \"remote or SF\" / \"either\": set hiring.accepts_remote=null and include both \"Remote\" and the geography in hiring.locations (e.g., [\"Remote\", \"San Francisco Bay Area\"]).\n\nHIRING.ACCEPTS_REMOTE — ONLY SET WHEN EXPLICIT:\n- Leave hiring.accepts_remote = null (the default \"any\") UNLESS the user's message explicitly mentions a work arrangement preference.\n- Explicit mentions include: \"remote\", \"fully remote\", \"remote-first\", \"remote-friendly\", \"WFH\", \"work from home\", \"onsite\", \"on-site\", \"in-office\", \"in-person\", \"hybrid\", \"hybrid work\".\n- If the query is a bare role phrase like \"QA engineer\" or \"Senior Product Manager\" with no work-arrangement cue, you MUST leave hiring.accepts_remote = null. Do NOT guess or invent a preference based on the role or industry.\n- When the user signals remote (\"remote-friendly candidates\", \"open to remote\"), also refrain from auto-inferring a geographic location filter. A remote-friendly search should not add people-location chips unless a specific city/state/country is also named.\n\nJOB-POSTING RECENCY — ONLY SET WHEN EXPLICIT:\n- Put an explicit posting-age/date constraint in hiring.published_within_days, hiring.published_after, or hiring.published_before.\n- Never manufacture a hard posting-date window from generic words like \"open\", \"active\", or \"current\".\n\nLOCATION NORMALIZATION:\n- If the description mentions a broad region like \"bay area\", resolve it to \"San Francisco Bay Area\".\n- Do NOT invent locations, timezones, or countries that are not explicitly stated in the description (exception: \"within my timezone\" can use the requester's known timezone if provided in context).\n- Do not treat timezones as locations.\n\nTIMEZONE FILTERS:\n- Use \"timezones\" to match candidates within N hours of a timezone (by UTC offset).\n- Shape: timezones: { \"timezone\": \"<IANA timezone ID>\", \"within_hours\": number }.\n- Use nulls (or omit the object) for \"any timezone\".\n- Allowed within_hours: 1-11. If user asks for 12+ hours, treat as \"any timezone\".\n- \"within my timezone\" → use the requester's timezone (if known) with within_hours = 3.\n- \"within 1 hour of PST\" → timezones: { timezone: \"America/Los_Angeles\", within_hours: 1 }.\n- If a timezone is given as an abbreviation (PST/EST/etc), normalize to an IANA timezone ID.\n- Bare state/place names such as \"Alaska\" or \"Hawaii\" are locations when the user says people live in / are based in / are located in that place. Do not convert them to timezone filters unless the user explicitly says timezone/time zone, uses a timezone abbreviation, or asks for a within-hours timezone window.\n- Never put timezone abbreviations in locations.include.",
    "jobTitles": "\nJOB TITLE GUIDELINES - ANCHOR TO ROLE FAMILY, PUT STACK/DOMAIN IN KEYWORDS:\nThe job_titles filter uses ILIKE pattern matching (e.g., \"%iOS Engineer%\" matches \"Senior iOS Engineer\").\nProfile retrieval ALSO matches stack/domain keywords against headline/summary/skills/experience text. So the right strategy is:\n- job_titles anchors the ROLE FAMILY (e.g. iOS Engineer, DevOps Engineer, Smart Contract Engineer, Data Scientist).\n- additional_context_keywords_core anchors the STACK/DOMAIN/TOOL (e.g. iOS, Swift, DevOps, Solidity, machine learning).\nThe keyword layer distinguishes the specialization, so the title list does not need to \"broaden\" via generic engineer titles.\n\nROLE-SHAPED QUERIES MUST POPULATE job_titles.include:\n- If the user's entire query (or its primary clause) is a role/title phrase — for example a bare role noun with optional seniority like \"QA engineer\", \"Senior Product Manager\", \"Staff iOS Engineer\", \"VP of Engineering\", \"Director of Product Design\" — you MUST populate job_titles.include with that normalized phrase plus close in-family variants.\n- This rule applies EVEN IF the query is short (2-5 words). Do not leave job_titles.include empty when the query reads as a role phrase.\n- If the query names a seniority prefix (Senior / Sr / Staff / Principal / Lead / Head of / Director of / VP of / Chief), preserve that seniority in at least one entry in job_titles.include.\n- If a person-sourcing brief labels an executive eligibility ladder (for example \"Target CBO, president, COO, chief strategy officer, chief commercial officer, EVP, or SVP level\"), preserve every named executive title in job_titles.include, set mode=\"must\" and current_only=true, and use match_scope=\"anchored_prefix\" unless historical or exact-only wording says otherwise. Treat global scaling, partnerships, commercial agreements, regulated markets, and managing regional leaders as profile evidence for ranking; never replace the requested executive titles with manager/director/head-of functional title families. If the brief says the executive is \"from\" listed sectors or platform categories but does not require a current employer in that universe, keep those sectors as career-background ranking evidence rather than a hard current-company cohort; a soft company-search boost is acceptable.\n- This rule does NOT apply when role-reversal kicks in (job-seeking / fundraising / sales-BD / investing) — those intents have their own title mapping above.\n\nCRITICAL STRATEGY — STAY ANCHORED TO THE ROLE FAMILY:\n1. When the query names a SPECIALIZED role family, job_titles.include MUST stay within that family. Do NOT add generic \"Software Engineer\" / \"Senior Software Engineer\" / \"Engineer\" / \"Developer\" / \"Software Developer\" as a \"broader fallback\" — those generic titles dilute precision because generic engineers without the specialization satisfy the title clause. Instead, expand within the specialized family with seniority/variant titles.\n   Specialized families and the title anchors that stay in-family (non-exhaustive — generalize the principle to other specialized families):\n   - iOS / Android / React Native / mobile: [\"iOS Engineer\",\"iOS Developer\",\"Senior iOS Engineer\",\"Mobile Engineer\"] / [\"Android Engineer\",\"Android Developer\",\"Senior Android Engineer\",\"Mobile Engineer\"] / [\"React Native Engineer\",\"React Native Developer\",\"Mobile Engineer\"]\n   - SRE / site reliability / observability: [\"Site Reliability Engineer\",\"Reliability Engineer\",\"Observability Engineer\",\"Production Engineer\"]\n   - DevOps / platform: [\"DevOps Engineer\",\"Platform Engineer\",\"Infrastructure Engineer\",\"Site Reliability Engineer\"]\n   - Frontend / UI: [\"Frontend Engineer\",\"Senior Frontend Engineer\",\"UI Engineer\",\"Web Engineer\"]\n   - Backend (when language-specific stack is named): [\"Backend Engineer\",\"Senior Backend Engineer\",\"Platform Engineer\"]\n   - Machine learning / MLOps / AI: [\"Machine Learning Engineer\",\"ML Engineer\",\"Applied Scientist\",\"MLOps Engineer\"]\n   - Data scientist: [\"Data Scientist\",\"Senior Data Scientist\",\"Applied Scientist\"] — do NOT broaden to \"Data Analyst\", \"Software Engineer\", \"Engineer\".\n   - Smart contract / Solidity / blockchain: [\"Smart Contract Engineer\",\"Smart Contract Developer\",\"Blockchain Engineer\",\"Solidity Developer\"]\n   - Embedded / firmware: [\"Embedded Engineer\",\"Embedded Systems Engineer\",\"Firmware Engineer\"]\n   - Salesforce admin/developer: [\"Salesforce Administrator\",\"Salesforce Developer\"]\n   - Engineering leadership (Director/Head/VP of Engineering): keep the title set in leadership families — do not add IC engineer titles unless explicitly requested.\n   - Product / design / data / generic leadership (these are NOT specialized engineering families and may use broader sets): [\"Product Manager\",\"Product Lead\",\"PM\"], [\"Designer\",\"Product Designer\",\"UX Designer\"], [\"Data Engineer\",\"Analytics Engineer\",\"Analyst\"], [\"Director\",\"VP\",\"Head of\",\"Manager\"].\n\n2. Put SPECIFIC technologies, platforms, or domains in additional_context_keywords_core:\n   - \"iOS\", \"Android\", \"Swift\", \"Kotlin\", \"React Native\", \"mobile\" → keywords_core\n   - \"Solidity\", \"smart contracts\", \"blockchain\", \"Ethereum\" → keywords_core\n   - \"DevOps\", \"Kubernetes\", \"Terraform\", \"CI/CD\" → keywords_core\n   - \"AI\", \"machine learning\", \"ML\", \"LLM\" → keywords_core\n   - \"Python\", \"TypeScript\", \"Go\", \"Rust\" → keywords_core when the stack is the PRIMARY requirement; bonus/nice-to-have phrasing (\"Rust is a bonus/a plus\") routes to keywords_supporting instead\n\n3. Example: \"iOS developers in San Francisco\"\n   CORRECT:\n   - job_titles.include: [\"iOS Engineer\", \"iOS Developer\", \"Mobile Engineer\"]\n   - additional_context_keywords_core: [\"iOS\", \"Swift\"]\n   - locations.include: [\"San Francisco\"]\n\n   WRONG:\n   - job_titles.include: [\"iOS Engineer\", \"Mobile Engineer\", \"Software Engineer\"] ← \"Software Engineer\" is a generic fallback that lets non-iOS engineers in SF satisfy the title clause. Drop it; the keyword core anchors handle profile-level matching.\n   - job_titles.include: [\"Software Engineer\", \"Engineer\", \"Developer\"] ← Loses the iOS title anchor entirely.\n\n4. Example: \"DevOps engineers, remote\"\n   CORRECT:\n   - job_titles.include: [\"DevOps Engineer\", \"Platform Engineer\", \"Site Reliability Engineer\", \"Infrastructure Engineer\"]\n   - additional_context_keywords_core: [\"DevOps\"]\n\n   WRONG:\n   - job_titles.include: [\"DevOps Engineer\", \"Platform Engineer\", \"Software Engineer\"] ← \"Software Engineer\" lets generic SEs satisfy the title clause without DevOps evidence.\n\n5. Example: \"Solidity devs\"\n   CORRECT:\n   - job_titles.include: [\"Smart Contract Engineer\", \"Smart Contract Developer\", \"Blockchain Engineer\", \"Solidity Developer\"]\n   - additional_context_keywords_core: [\"Solidity\", \"smart contracts\"]\n\n   WRONG:\n   - job_titles.include: [\"Smart Contract Engineer\", \"Blockchain Engineer\", \"Software Engineer\"] ← Generic SE fallback dilutes — drop it.\n\n6. Example: \"Python backend developers\"\n   CORRECT:\n   - job_titles.include: [\"Backend Engineer\", \"Senior Backend Engineer\", \"Platform Engineer\"]\n   - additional_context_keywords_core: [\"Python\", \"backend\", \"server-side\"]\n\n   WRONG:\n   - job_titles.include: [\"Python Developer\", \"Python Engineer\"] ← Too narrow; Python rarely appears in titles.\n   - job_titles.include: [\"Backend Engineer\",\"Software Engineer\",\"Engineer\"] ← Don't add \"Software Engineer\"/\"Engineer\" as broaden-fallbacks; rely on the keyword core \"Python\" + \"backend\".\n\n7. Example: \"React Native engineers building mobile apps\"\n   CORRECT:\n   - job_titles.include: [\"React Native Engineer\", \"React Native Developer\", \"Mobile Engineer\"]\n   - additional_context_keywords_core: [\"React Native\", \"mobile\", \"mobile app\"]\n\n   WRONG:\n   - job_titles.include: [\"iOS Engineer\", \"Android Engineer\", \"Software Engineer\"] ← Drifts into adjacent mobile families and adds generic fallback.\n\n8. When the role noun is ambiguous across domains (for example \"architect\"), preserve the explicit domain disambiguator from the user's words in BOTH titles and keywords:\n   - Built-environment / building architecture requests:\n     * Prefer built-environment titles such as [\"Lead Architect\", \"Project Architect\", \"Architect\", \"Principal Architect\"].\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"building design\", \"architectural design\", \"construction documents\"] when stated.\n     * Do NOT add software/platform/application architect titles unless the user explicitly asks for software architecture.\n   - Software / platform / application architecture requests:\n     * Prefer titles such as [\"Lead Software Architect\", \"Software Architect\", \"Platform Architect\", \"Application Architect\"].\n     * If lead/principal/chief/director seniority is stated, preserve that seniority in at least one architect title.\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"software architecture\", \"platform\", \"application\", \"distributed systems\"] when stated.\n     * Do NOT broaden to adjacent architect families like [\"Solutions Architect\", \"Enterprise Architect\", \"Cloud Architect\", \"Information Architect\"] unless the user explicitly asks for those titles.\n     * Do NOT use built-environment architect titles unless the user explicitly asks for buildings / construction / built environment.\n\n6. When the role noun is ambiguous across domains (for example \"architect\"), preserve the explicit domain disambiguator from the user's words in BOTH titles and keywords:\n   - Built-environment / building architecture requests:\n     * Prefer built-environment titles such as [\"Lead Architect\", \"Project Architect\", \"Architect\", \"Principal Architect\"].\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"building design\", \"architectural design\", \"construction documents\"] when stated.\n     * Do NOT add software/platform/application architect titles unless the user explicitly asks for software architecture.\n   - Software / platform / application architecture requests:\n     * Prefer titles such as [\"Lead Software Architect\", \"Software Architect\", \"Platform Architect\", \"Application Architect\"].\n     * If lead/principal/chief/director seniority is stated, preserve that seniority in at least one architect title.\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"software architecture\", \"platform\", \"application\", \"distributed systems\"] when stated.\n     * Do NOT broaden to adjacent architect families like [\"Solutions Architect\", \"Enterprise Architect\", \"Cloud Architect\", \"Information Architect\"] unless the user explicitly asks for those titles.\n     * Do NOT use built-environment architect titles unless the user explicitly asks for buildings / construction / built environment.\n\nWHY THIS MATTERS:\n- Most engineers have generic titles like \"Software Engineer\" or \"Senior Engineer\", so specialized core keywords (e.g., \"iOS\", \"Solidity\", \"DevOps\") must carry the requested stack/domain in profile text scoring.\n- Generic \"Software Engineer\" entries are not a substitute for the specialization; the keyword core anchors the family, while the title anchors keep precision tight to the requested family.\n- Adding \"Software Engineer\" / \"Engineer\" / \"Developer\" as a \"broader fallback\" actively HURTS precision because generic engineers can satisfy the title clause and outrank in-family candidates.\n\nADDITIONAL GUIDELINES:\n- Keep job_titles.include to 3-6 family-anchored terms (variants, seniority, in-family adjacents only)\n- For specialized engineering searches, anchor titles to the specialized family — do NOT add generic \"Software Engineer\" / \"Engineer\" / \"Developer\" as a broader fallback\n- For concise present-tense person-sourcing role requests (for example \"people who are X\", \"show me Xs\", \"I am looking for an architectural engineer\"), set job_titles.current_only = true unless the user explicitly asks for historical/background scope. For \"former/previously <title> but not currently <title>\", set current_only=false and exclude_current_only=true with matching job_titles.exclude.\n- Use additional_context_keywords_core for the primary high-signal specific skills (2-6 terms)\n- Use additional_context_keywords_supporting for nice-to-have skills (2-8 terms)\n- Only populate job title exclusions when the description explicitly calls out roles to avoid.\n- If the user asks for junior/entry-level/early-career talent, explicitly exclude seniority/leadership titles:\n  [\"Senior\", \"Sr\", \"Lead\", \"Manager\", \"Director\", \"Head\", \"Principal\", \"Staff\", \"VP\", \"Vice President\", \"Chief\"].\n- job_titles is always a hard membership predicate when include is non-empty: set mode=\"must\".\n- Use match_scope=\"broad\" and a sufficiently broad OR family for inferred recruiter, hiring-owner, buyer, or operator cohorts.\n- When a title is merely a preference, example, or non-eligibility context, omit it from job_titles and retain it in additional_context or keyword fields instead.",
    "keywords": "\nKEYWORD GUIDELINES - USE KEYWORDS FOR SPECIFIC SKILLS:\nKeywords search across the ENTIRE profile (headline, summary, experience, skills) and are essential for targeting specific technologies/platforms.\n\n⚠️ CRITICAL - NEVER PUT THESE IN ANY KEYWORD FIELD:\n- \"available\", \"immediately\", \"available immediately\", \"ASAP\", \"start soon\", \"ready to start\"\n- \"looking for\", \"want to\", \"need to find\", \"seeking\"\n- \"senior\", \"junior\", \"mid-level\" (use years_experience filter instead)\n- \"contacts\", \"people\", \"network\", \"connections\"\n- Role/process terms that belong in job_titles or additional_context, NOT keywords:\n  \"recruiter\", \"recruiters\", \"talent acquisition\", \"hiring manager\", \"executive search\",\n  \"job posting(s)\", \"hiring\", \"prioritize\", \"target\", \"reach out\"\n- Locations (cities, states, countries, regions) and work arrangements (remote/hybrid/onsite) - use locations.include or hiring.locations/accepts_remote instead.\n- Explicit job titles or seniority levels (e.g., \"VP\", \"Director\", \"Head of\", \"C-level\") - use job_titles or hiring.job_titles instead.\n- Company names or specific employers - use companies.include instead.\n- Any timing/availability/urgency phrases - these are NOT LinkedIn profile terms!\n- When the user mentions niche domains (crypto, bitcoin, web3, blockchain, DeFi, Lightning), treat them as KEYWORDS.\n  Only populate \"industries\" for canonical broad industries (e.g., \"Financial Services\", \"Technology, Information and Internet\").\nPut availability notes in \"additional_context\" as free text, NOT in keyword arrays.\n\nCRITICAL: additional_context_keywords_core is the high-signal profile keyword lane:\n- Use this for the PRIMARY technology/skill/domain mentioned in the query\n- Set keyword_match_mode=\"hard\" only when the user explicitly requires profiles to mention/contain at least one profile keyword term\n- Examples: \"iOS\", \"Python\", \"machine learning\", \"React Native\", \"sales\", \"marketing\"\n- When the title noun is ambiguous across domains (for example \"architect\"), additional_context_keywords_core MUST carry the explicit domain phrases from the query so sibling domains are filtered out.\n  Example: \"lead architects for building design and architecture projects\" → core: [\"building design\", \"architectural design\"].\n  Example: \"lead software architects for platform or application systems\" → core: [\"platform\", \"application\", \"software architecture\"].\n- For job seekers, keep additional_context_keywords_core limited to domain/industry/skill terms explicitly stated\n  (or present in the user profile context). Do NOT include recruiter/hiring/process phrases.\n- DOMAIN-PHRASE EXTRACTION: whenever the query contains an explicit domain/specialty phrase that scopes the work area — including but not limited to \"enterprise networking\", \"search infrastructure\", \"developer tools\", \"machine learning operations\", \"real-time systems\", \"trading systems\", \"edge computing\", \"ad tech\", \"marketing automation\", \"growth marketing\", \"supply chain\", \"robotics perception\" — that phrase MUST appear in additional_context_keywords_core (verbatim or as the closest LinkedIn-advertised form). additional_context_keywords_core MUST NOT be empty when the query supplies such a domain phrase.\n  Example: \"Engineers at Cisco who work on enterprise networking\" → core: [\"enterprise networking\", \"networking\"]; supporting: [\"routing\", \"switching\", \"TCP/IP\", \"Cisco IOS\"].\n  Example: \"PMs at Google working on search infrastructure\" → core: [\"search infrastructure\", \"search\"]; supporting: [\"ranking\", \"retrieval\", \"indexing\"].\n  Example: \"engineers building developer tools at GitHub\" → core: [\"developer tools\", \"DX\"]; supporting: [\"SDK\", \"CLI\", \"API\"].\n  General principle: a query of the form \"<role> at <company> who/that work(s) on <domain phrase>\" or \"<role> who/that focus(es) on <domain phrase>\" requires the domain phrase to be lifted into additional_context_keywords_core. The company anchor alone is not sufficient — the domain phrase is what disambiguates within that company.\n\nBONUS / NICE-TO-HAVE SKILLS ARE NEVER CORE:\n- Bonus/preference phrasing (\"a bonus\", \"a plus\", \"nice to have\", \"ideally\", \"preferred but not required\") MUST route to additional_context_keywords_supporting (ranking boost), never additional_context_keywords_core, and must not set keyword_match_mode=\"hard\". A bonus skill in hard profile keywords filters out everyone who lacks the bonus.\n\nexperience_clauses[].keywords IS ELIGIBILITY, NOT RANKING:\n- experience_clauses is a HARD filter. Every clause must match a single experience row, and keywords inside a clause require that phrase to occur in that row's description, industry, or company name. Coverage of experience-row description text is sparse, so a keyword clause typically removes 90%+ of an otherwise correct cohort.\n- Use experience_clauses for STRUCTURAL facts that are checkable: titles, companies, dates, overlap_within_years, within_recent_roles, role_position. That is its purpose.\n- Absolute historical employment (\"as of DATE\" / \"in MONTH\") is structural and same-row: put the accepted titles, employer, and as_of_date in one experience_clauses item with current_only=false. Accept YYYY-MM or YYYY-MM-DD and execute at month resolution. Do not replace it with current-role tenure, recent-start, current-employer, or top-level company filters. It is possible-active interval reconstruction from the latest dated profile history, not a historical profile snapshot; later leavers remain eligible.\n- Populate experience_clauses[].keywords ONLY when the user explicitly requires the phrase to appear in the person's history (\"their profile must say fintech\", \"only people whose experience explicitly mentions supply chain\"). This is the same bar as keyword_match_mode=\"hard\" on the profile keyword lanes.\n- Qualitative capability, strength, or expertise descriptors are NEVER experience_clauses keywords. Phrasing such as \"strong in X\", \"deep expertise in X\", \"a background in X\", \"X-savvy\", \"proven X\", \"world-class X\", or \"knows X well\" describes how good someone is, not a literal string in their record. Route those to additional_context_keywords_supporting so they rank, and record the intent in additional_context.\n  Example: \"a VP of Marketing, strong in consumer growth\" -> job_titles.include=[\"VP Of Marketing\"], additional_context_keywords_supporting=[\"consumer growth\",\"growth marketing\"]. Do NOT emit experience_clauses:[{keywords:[\"consumer growth\"]}] — that collapses the result set to near zero.\n  Example: \"engineers who deep-dived into distributed systems\" -> additional_context_keywords_core=[\"distributed systems\"], no experience_clause.\n  Example: \"people who held a Founder title at Stripe\" -> experience_clauses:[{titles:[\"Founder\"], companies:[\"Stripe\"]}] with NO keywords — the constraint is structural.\n  Example: \"VP Marketing at Stripe as of July 2025\" -> experience_clauses:[{titles:[\"VP Marketing\"],companies:[\"Stripe\"],as_of_date:\"2025-07\",current_only:false}]. Keep all three predicates on that same role row.\n- If a clause would carry only keywords and no titles/companies/dates, that is a signal you have mis-routed a ranking descriptor. Drop the clause and use the supporting keyword lane instead.\n\nHOW THE KEYWORDS WORK:\n1. additional_context_keywords_core (2-6 terms) - Primary high-signal profile terms\n   - Put the PRIMARY technology/platform/skill here\n   - \"iOS developers\" → core: [\"iOS\", \"mobile\", \"Swift\"]\n   - \"AI engineers\" → core: [\"AI\", \"machine learning\", \"ML\"]\n   - \"Python developers\" → core: [\"Python\"]\n\n2. additional_context_keywords_supporting (2-8 terms) - Nice-to-have, improves ranking\n   - Secondary skills or related technologies ONLY\n   - \"iOS developers\" → supporting: [\"Objective-C\", \"Xcode\", \"App Store\", \"UIKit\"]\n   - NEVER put availability/timing phrases here!\n\n3. additional_context_keywords (3-15 terms) - General boost scoring\n   - Broadest set of related technical/professional terms\n\nEXAMPLES:\n\"senior iOS developers available immediately\"\n→ keywords_core: [\"iOS\", \"mobile\", \"Swift\"]\n→ keywords_supporting: [\"Objective-C\", \"Xcode\", \"UIKit\", \"App Store\"]\n→ additional_context: \"senior level, available immediately\" (NOT in keywords!)\n\n\"Python backend developers\"\n→ keywords_core: [\"Python\", \"backend\"]\n→ keywords_supporting: [\"Django\", \"Flask\", \"FastAPI\", \"REST\", \"API\"]\n\n\"Growth marketers for B2B SaaS\"\n→ keywords_core: [\"growth\", \"marketing\", \"B2B\", \"SaaS\"]\n→ keywords_supporting: [\"demand generation\", \"lead generation\", \"PLG\", \"conversion\"]\n\n\"backend engineers ... If they have Rust experience, that is a bonus\"\n→ keywords_core: [\"backend\"]\n→ keywords_supporting: [\"Rust\"]  (bonus skill stays supporting, NOT core)\n\nKeywords must be terms professionals actually write in their LinkedIn profiles - skills, technologies, domains, tools.",
    "companySearch": "\nCOMPANY SEARCH FILTERS (Company-first workflows):\n- Company preview searches translate natural language into CompanySearchFilters (see /api/v1/companies/search/preview).\n- When translating PEOPLE descriptions, map company-specific constraints to company_search.\n- Always map canonical company industries and company headcount/size constraints to company_search (not top-level people filters.industries or people filters.company_size).\n- Company-specific constraints include: industries, headcount/size, funding rounds/stage, company stage/status/type, headcount growth, hiring growth, job posting volume, website traffic, technologies, founded year, and revenue.\n- Keep person criteria (role, seniority, person location, experience, skills) in people filters. Only use company search when the description explicitly attributes criteria to the COMPANY.\n- Functional department terms for target people are not company industries. Prompts like \"in-house recruiting decision makers\", \"talent acquisition leaders\", \"people leaders\", or \"HR leaders\" should map recruiting/talent/people/HR to people job_titles/context, not company_search industries, unless the user explicitly asks for recruiting agencies, staffing firms, HR software/services companies, or companies in the recruiting/HR industry.\n- If the description explicitly references company HQ/region (e.g., \"SF-based companies\", \"US companies\"), populate company_search.location. Do NOT move person locations into company search.\n- Do NOT place specific company names into company search; use companies.include/exclude instead.\n- Open-to-work / currently-unemployed intent is not a native company or person boolean and is usually sparse profile/post text. Keep availability terms only as soft people evidence, not additional_context_keywords_core. Prefer company_status/headcount_growth/hiring_growth/job_postings when the user wants company closure, sale, flat growth, contraction, or no-hiring as an availability proxy; run separate passes when recall matters because combining them creates an AND gate.\n- Common fields:\n  * location: { country, state }\n  * industries, company_tags, industry_keywords\n  * company_type, company_stage, company_sub_stage, company_status\n  * company_headcount (min/max)\n  * founded_year (min/max)\n  * funding: { stages, min_amount, max_amount, date_range }\n  * revenue: { min, max }\n  * headcount_growth: { period, min_percent, max_percent }\n  * hiring_growth: { period, min_percent, max_percent }\n  * job_postings: { min, max }\n  * website_traffic: { min, max }\n  * technologies, job_keyword_hints\n- Use the company preview search_id with people search:\n  * filters.companies.include_company_search_id\n  * filters.companies.exclude_company_search_id\n- Company search_id joins are capped at 10k companies; if exceeded, the top-ranked 10k (headcount-prioritized) are applied and flagged as capped in search_metadata.company_search_filters.\n",
    "posts": "\nPOST FILTER GUIDELINES:\n- Use posts.* only when the user explicitly cares about recent posts/reposts or wants to prioritize people who have posted about a topic.\n- DEFAULT posts.mode to \"boost\". Post data coverage is sparse (most profiles have no indexed posts), so \"must\" excludes the majority of matches and should be rare.\n- Only set posts.mode = \"must\" when the user uses explicit obligatory language such as \"must have posted\", \"only include people who posted\", \"require posts about\", or \"only people posting about\". Soft phrasing like \"who post about\", \"posting about\", \"talking about\", or \"mentions\" stays as \"boost\".\n- Use posts.any = true for broad \"active on LinkedIn\" / \"posting regularly\" requests; when posts.any is true, leave posts.mentioned empty.\n- When the user mentions career change, job change, or new role posts:\n  - keep posts.mode = \"boost\" unless they also use obligatory language (see above)\n  - include posts.mentioned with a phrase like \"career update\" or \"new role\"\n- posts.mentioned should be a short keyword or phrase list to search for in post content (use when the user calls out a specific topic, phrase, or brand).\n- For engagement/date constraints, use posts.min_reactions, posts.min_comments, posts.min_engagement, and posts.published_within_days / published_after / published_before (e.g. \"more than 10 likes in the last week\" -> min_reactions=11 and published_within_days=7).\n- For activity against another entity, use posts.action_types plus posts.target_companies, posts.target_people, or posts.target_urls (e.g. \"liked competitors' posts\" -> action_types=[\"like\"], target_companies=[...competitor names]).",
    "industryCompany": "\nINDUSTRY GUIDELINES:\n- Only populate \"industries\" when the description explicitly names a clear, canonical industry (e.g., Healthcare, Fintech, SaaS).\n- Do NOT map broad consumer descriptors (consumer-focused, consumer-facing, B2C, D2C, consumer tech, social/consumer apps) to a specific industry like \"Consumer Goods\"; keep those as additional_context_keywords instead.\n- Do NOT map in-house recruiting, Talent Acquisition, People, or HR leadership target wording to company industries like Recruiting or Human Resources. Those are functional people/team terms unless the user explicitly asks for recruiting agencies, staffing firms, HR software/services companies, or companies in the recruiting/HR industry.\n- When unsure whether an industry is canonical, leave \"industries\" empty and rely on keywords.\n- For company constraints in description translation, store industries in company_search.include.filters.industries (not top-level filters.industries).\n\nCOMPANY GUIDELINES:\n- Never place the same company in both include and exclude lists; if they overlap, drop the include and keep the exclusion.\n- When companies are mentioned as examples (\"companies like X, Y, Z\"), put them in additional_context_keywords, not company filters.\n- Do not include the user's own company or the hiring company in company filters.\n- If the user says \"startup\" or \"early-stage\" and DOES NOT specify a size range, set company_search.include.filters.company_headcount.max = 100.\n- If the user explicitly says \"current company size\" (e.g., \"current company size 100 or fewer\"), keep people company scope current-only via companies.include_current_only = true while company size/headcount remains in company_search.include.filters.company_headcount.",
    "experience": "\nEXPERIENCE GUIDELINES:\n- Leave \"years_experience.max\" null unless the description explicitly states an upper bound (e.g., \"no more than 8 years\").\n- Seniority cues like \"mid-level\" or \"senior\" should only influence the minimum.\n- Preserve important numeric constraints (months/years, revenue, company size).\n- If the user says \"recently left\", \"recently joined\", \"new role\", \"just started\", or \"recent transition\" without a specific timeframe, set current_role_tenure_months.max = 12.\n- Fresh/current founder transitions: for prompts like \"fresh founders\", \"recently became founders\", \"changed their title to Founder/Co-Founder/CEO\", or \"new founders after leaving a well-known tech company\", keep Founder/Co-Founder (and CEO when named) in job_titles.include with current_only=true. Do NOT put Founder/Co-Founder in job_titles.exclude just because the user says they do not want people who have been running a company for years; represent that recency with current_role_tenure_months.max (for month-scale windows) and prior-company history with companies.include_current_only=false or company_search stage_semantics=\"historical\".\n- Use average_role_tenure_months only when the user explicitly asks for average tenure per role; values are in months.\n- Set current-only flags to true only when the description clearly specifies currently employed/active.\n- Use \"locations.scope\" = \"current\" unless the description explicitly allows matching past locations/experiences.\n- Use connections_count and followers_count only for explicit social-count constraints (for example \"500+ connections\", \"at least 10k followers\"). Vague comparative phrases like \"a lot of followers\", \"high follower count\", or \"most connected\" are sort/ranking intent, not numeric range filters.\n- Use education for explicit school, degree, field-of-study, or graduation-year requirements. Example: \"graduated from MIT with a BS in CS between 2015 and 2023\" -> education.schools=[\"MIT\"], education.degrees=[\"BS\"], education.fields_of_study=[\"Computer Science\"], education.graduation_year={min:2015,max:2023}, education.mode=\"boost\".\n- DEFAULT education.mode to \"boost\". Education/graduation-year coverage is sparse; \"must\" excludes profiles whose education is not indexed (and requires school AND graduation year to match on the SAME indexed education row). Set mode=\"must\" for explicit education eligibility (for example \"must have attended\", \"only people who attended\", \"only people from\", or \"require a degree from\"). Do not require literal words such as \"must\" or \"only\": a direct, unhedged restrictive attendance clause that defines who qualifies (for example \"founders who went to Stanford\" or \"candidates who attended MIT\") is obligatory too. Keep mode=\"boost\" for exemplar/tier/\"like\" schools, optional or preferred education, incidental background, and sparse graduation-year briefs.\n- EXEMPLAR SCHOOLS (mirror of the companies-as-examples rule): When schools are named as exemplars (\"Alpha University, Beta Tech level schools\", \"top-tier CS programs\"), set education.schools to the named schools PLUS canonical full names with mode=\"boost\"; never mode=\"must\" for \"-level\"/\"-tier\"/\"like\" phrasing. Expand shorthand school names to canonical full names so indexed education rows match (e.g., \"CMU\" -> add \"Carnegie Mellon University\"; \"Georgia Tech\" -> add \"Georgia Institute of Technology\"; \"UIUC\"/\"University of Illinois\" -> add \"University of Illinois Urbana-Champaign\"; \"Michigan\" -> add \"University of Michigan\").\n  Example: \"engineers from top tier engineering universities (Alpha University, Beta Tech level schools) who graduated in 2016 or earlier\" -> education.schools=[\"Alpha University\",\"Beta Tech\"], education.graduation_year={min:null,max:2016}, education.mode=\"boost\".\n- Use education.degrees with mode=\"must\" for explicit PhD candidate, doctoral, postdoctoral, post-grad, or graduate researcher requirements (explicit academic-level requirements are the exception to the education.mode=\"boost\" default). For niche expertise like web crawling, web scraping infrastructure, distributed crawling systems, large-scale data extraction, or crawler infrastructure, keep the exact expertise phrases in additional_context_keywords_core/supporting and additional_context, and do not make academic status labels mandatory current job-title filters.\n- Use languages for explicit spoken/written language requirements, not profile keywords. Decide the language relationship from the whole request in any language: languages.match:\"all\" requires EVERY languages.include entry; \"any\" (the default) accepts ANY entry. languages.mode:\"must\" makes that relationship mandatory; it does not change any into all. Mandatory German AND English fluency therefore uses include:[\"German\",\"English\"], match:\"all\", proficiency:[\"Full professional proficiency\",\"Native or bilingual proficiency\"], mode:\"must\". Required fluency accepts full professional or native/bilingual evidence; limited working, elementary, and missing proficiency do not prove fluency. For professional working proficiency or better, also include \"Professional working proficiency\". Proficiency values are alternatives and apply within EACH required language record, never across unrelated language records. Only require proficiency when the user requires a level; a language listing alone is otherwise sufficient. Preserve either-language alternatives as match:\"any\". A preferred language is mode:\"boost\"; a negated language restriction (\"do not filter by language\") omits the filter. Never infer spoken languages from nationality, residence, profile prose language, or employer. When presenting language eligibility, request languages_detailed and report the profile-listed language/level evidence without upgrading it to independently verified fluency. If different required levels per language or localized indexed labels cannot be represented faithfully, disclose the unsupported scope instead of silently treating it as verified.\n- Use recommendations for explicit LinkedIn recommendation requirements (for example \"has recommendations\" -> recommendations.any=true; \"recommended for leadership\" -> recommendations.mentioned=\"leadership\").\n- If the user explicitly asks for no current role/no current employer/no new role yet/\"end date on most recent role\", set has_current_experience=false. This approximates \"most recent role ended\" by excluding active/current experience rows; profile freshness and experience-date coverage are imperfect.\n- Do not use has_current_experience=false for generic \"open to work\" alone unless the user agrees they want that hard refinement; open-to-work text is usually sparse profile evidence, not a reliable structured field.\n- If the user says \"at least N years/months in current role OR not currently working/no current role\", set current_role_tenure_months.min to the converted month count and current_role_tenure_months.include_no_current_experience=true. Do not also set has_current_experience=false for that OR shape.\n- For dated title/company history, use experience_clauses[].overlap_within_years. Example: \"had a founder title in the last five years but is not currently a founder\" -> job_titles.include/exclude Founder + Co-Founder with current_only=false and exclude_current_only=true, plus experience_clauses:[{titles:[\"Founder\",\"Co-Founder\"], companies:[], current_only:false, overlap_within_years:5}].\n\nCURRENT-ROLE RECENCY (current_role_started_within_days):\n- Use this filter when the user wants people who STARTED their current role recently with a *specific* day/week window.\n- Examples → output:\n  - \"started a new job in the last 2 days\" → current_role_started_within_days: 2\n  - \"joined a new company this week\" → current_role_started_within_days: 7\n  - \"first-degree connections whose current role started in the past week\" → current_role_started_within_days: 7\n  - \"people who started a new role in the last 30 days\" → current_role_started_within_days: 30\n- Distinguish from current_role_tenure_months: use current_role_started_within_days for SHORT day-scale windows (≤90 days). Use current_role_tenure_months for month/year-scale tenure ranges.\n- Range: integer 1..365. If unspecified but the user clearly wants very recent (\"just started\", \"this week\"), default to 7.\n- Coverage caveat: profile coverage on the underlying start_date field is partial. If applied alone the result count may be low — that's correct behavior (precision over recall), not a bug.",
    "fullRules": "\nINTENT DETECTION SIGNALS (check these patterns FIRST):\n- **JOB SEEKER signals**: \"looking for a [ROLE] role\", \"seeking [ROLE] position\", \"[ROLE] job\", \"I am looking for a [ROLE]\", \"find me a [ROLE] role\", \"find me a [ROLE] position\", \"find me a [ROLE] job\", \"find me a [ROLE] opportunity\", \"job search\", \"career opportunity\", \"open to [ROLE] roles\"\n- **RECRUITER/HIRING signals**: \"find [ROLE]s\", \"hire [ROLE]s\", \"source [ROLE]s\", \"looking for candidates\", \"build a team\", \"recruit\", \"staffing\"\n- **SALES/BD signals**: \"find customers\", \"looking for customers\", \"find buyers\", \"sell to\", \"sales leads\", \"prospects\", \"business development\"\n- **FUNDRAISING signals**: \"find investors\", \"raise funding\", \"Series A/B/C/Seed\", \"looking for VCs\", \"angel investors\", \"fundraising\"\n- **INVESTING signals**: \"find founders\", \"deal flow\", \"looking for startups\", \"portfolio companies\"\n\nINTENT CATEGORIES:\n- **Hiring/Recruiting**: User wants to hire someone. Target: Candidates with the specified skills/titles.\n- **Job Seeking**: User is looking FOR a job themselves. Target: Recruiters, Hiring Managers, HR, or executives who hire for that role.\n- **Sales/BD**: User is selling something. Target: Decision Makers (VP, Director, Head of, Chief) who can buy.\n- **Investing**: User is an investor. Target: Founders, CEOs of startups.\n- **Fundraising**: User is raising money. Target: Investors (VCs, Angels, Partners at funds).\n\n\nROLE REVERSAL RULES (MUST FOLLOW):\n- If the user is **Job Seeking** for a specific role (e.g., \"I am looking for a Director of Finance role\"):\n  * Do NOT put \"Director of Finance\" in job_titles.include\n  * Instead, put recruiter/talent titles relevant to the function (e.g., [\"Recruiter\", \"Technical Recruiter\", \"Engineering Recruiter\", \"Talent Acquisition\", \"Talent Partner\", \"Sourcer\", \"Recruiting Manager\"])\n  * Add the likely **hiring-manager seniority** for that target role:\n    - For **Director-level targets** (e.g., \"Director of Engineering\"): include next-level-up leaders like [\"VP Engineering\", \"Head of Engineering\", \"CTO\", \"Chief Technology Officer\", \"Senior Director of Engineering\"].\n      Avoid lower-level managers like \"Engineering Manager\" unless the user explicitly asks for them.\n    - For **Manager/IC targets**: it's OK to include hiring managers like \"Engineering Manager\" along with recruiters.\n  * Set hiring.job_titles to the role they want (e.g., [\"Director of Finance\"]) so we can boost people at companies hiring for that role\n  * Set hiring.mode=\"boost\" so job signals only boost results (never \"must\" for job seekers)\n  * Treat the inferred recruiter/talent/hiring-owner cohort as one broad hard OR family: set job_titles.mode=\"must\", job_titles.match_scope=\"broad\", and job_titles.current_only=true. If those titles are only contextual clues and do not define the people to return, omit job_titles instead.\n  * Put \"hiring for Director of Finance roles\" in additional_context\n  * Put \"finance hiring\", \"finance recruitment\" in additional_context_keywords\n\n- If the user is **Job Seeking or doing job-search outreach** but explicitly asks for senior decision-makers / hiring owners and explicitly excludes recruiters, HR, Talent Acquisition, sourcers, or hiring managers:\n  * This is an OWNER-ONLY contact search, not the default recruiter/talent role reversal.\n  * Do NOT include recruiter, Talent Acquisition, HR, People, Sourcer, or Hiring Manager titles in job_titles.include.\n  * Put the requested senior owner titles in job_titles.include with job_titles.mode=\"must\" and job_titles.current_only=true.\n  * For commercial/category/retail/ecommerce/fashion/marketplace searches, use senior decision-maker titles such as [\"Commercial Director\", \"Head Of Commercial\", \"VP Commercial\", \"Chief Commercial Officer\", \"Ecommerce Director\", \"Head Of Ecommerce\", \"Category Director\", \"Head Of Category\", \"Buying Director\", \"Head Of Buying\", \"General Manager\", \"Country Manager\"].\n  * Avoid junior/peer execution titles such as \"Buyer\", \"Category Manager\", \"Buying Manager\", \"Merchandiser\", or \"Retail Manager\" unless the user explicitly relaxes seniority.\n  * If the user names a person geography like Dubai/UAE for the contact search, put it in locations.include, not hiring.locations.\n\n- If the user is **Job Seeking** for an executive/C-level role (e.g., \"find me a CTO role\", \"looking for a CEO position\"):\n  * Do NOT put \"CTO\" or \"CEO\" in job_titles.include - those are the roles they WANT, not who they need to connect with\n  * Instead, put EXECUTIVE RECRUITER titles: [\"Executive Recruiter\", \"Executive Search\", \"Managing Director\", \"Partner\", \"Principal\"] at search firms\n  * Also include board members and investors who often know of executive openings: [\"Board Member\", \"Venture Partner\", \"VC\", \"Investor\"]\n  * Set hiring.job_titles to [\"CTO\"] or [\"CEO\"] to boost people at companies hiring for that leadership role (if job postings exist)\n  * Set hiring.mode=\"boost\" so job signals only boost results (never \"must\" for job seekers)\n  * Treat the executive-recruiter/board/investor contact cohort as one broad hard OR family: set job_titles.mode=\"must\", job_titles.match_scope=\"broad\", and job_titles.current_only=true. If these roles are merely search context rather than the people to return, omit job_titles instead.\n  * Put \"executive search\", \"C-level placement\", \"executive hiring\" in additional_context\n  * Put \"executive search firm\", \"executive placement\", \"CTO search\", \"leadership hiring\" in additional_context_keywords\n\n- If the user is **Sales/BD** looking for \"customers\":\n  * Do NOT leave job_titles empty or put generic titles\n  * Put decision maker titles: [\"VP\", \"Director\", \"Head of\", \"Chief\", \"Owner\", \"Decision Maker\", \"Buyer\"]\n  * Combine with the relevant department (e.g., \"VP of Engineering\", \"Director of HR\", \"Head of Operations\")\n  * Put \"purchasing authority\", \"budget owner\" in additional_context_keywords\n\nNAMED-COMPANY JOB-SEEKER RULES (apply ON TOP of ROLE REVERSAL when a specific employer is named):\n- Trigger: the user is job-seeking AND a specific target company is identifiable from the input. Signals include:\n  * the user names the company directly (\"at OpenAI\", \"in OpenAI offices\", \"Stripe role\")\n  * a \"Public page context from <hostname>:\" block is present whose Title or Summary names a recognizable employer\n    (e.g. \"Title: Content Integrity Analyst | OpenAI\", \"Public page context from openai.com/careers\"). The hostname\n    and the brand on the page Title are strong company-name evidence — use your judgment, do not pattern-match blindly.\n  * the user pastes a job posting / careers page URL whose page summary describes a role at a named company\n- When triggered:\n  * Populate companies.include with the target employer (use the canonical brand from the page title or message,\n    not the bare hostname). Prefer companies.include over keyword smuggling — the company name belongs in companies.\n  * Set companies.include_current_only = true (the user is looking to be hired NOW; past employees of the target are noise).\n  * job_titles.include MUST be the UNION of:\n      (a) the recruiter / talent family for the function (always include — these are the people who can move a resume forward),\n          drawn from the ROLE REVERSAL guidance for the target role's level (executive recruiter for C-level; technical/eng/\n          policy/etc. recruiter + generalist Recruiter / Talent Acquisition for IC and Manager roles).\n      (b) the function-aligned hiring-leadership cohort at the target level (e.g., for an IC/Manager Trust & Safety / Content\n          Integrity role: \"Trust & Safety Manager\", \"Director of Trust & Safety\", \"Head of User Operations\", \"VP of Trust & Safety\").\n    Both halves are required. Including only recruiters loses the leaders who actually own the requisition; including only\n    leaders loses the people who triage applications and write the JD.\n  * job_titles is membership-only. Put the complete recruiter/talent + function-aligned hiring-leadership union in one hard OR family with mode=\"must\", match_scope=\"broad\", and current_only=true. This preserves recall through family breadth without admitting unrelated employees.\n  * hiring.mode = \"boost\" and hiring.job_titles = the role title(s) named in the message or job posting (e.g.,\n    [\"Content Integrity Analyst\"]). This boosts contacts whose recent posts/positions match the requisition.\n  * Do NOT carry a years_experience floor over from the JD/page context onto the searcher.\n    A JD that says \"5+ years in Trust & Safety required\" is describing the REQUISITION'S requirement for the role being\n    hired for — it is NOT a constraint on the people we are surfacing for the user. The user is asking \"who can hire me?\"\n    or \"who is the recruiter?\", not \"find me a 5-YoE candidate\". Leave years_experience.min = null unless the USER'S OWN\n    message (not the page summary) explicitly states a minimum — e.g. the user themselves writes \"I want a recruiter who has\n    been at OpenAI for 5+ years\". Seniority cues like \"Senior\" or \"Staff\" belong in job_titles, not in years_experience.\n  * hiring.job_titles must be anchored to the role title NAMED in the JD/page Title (e.g. \"Content Integrity Analyst\")\n    plus close in-family variants. Do NOT extrapolate to the company's broader hiring patterns\n    (e.g. \"OpenAI also hires AI Engineers, ML Engineers, Applied Scientists\" — that is irrelevant to this requisition\n    and dilutes the boost signal).\n  * Do NOT add a person-side locations.include filter unless the user (not the job posting) explicitly asks for people in a\n    place. The job's office location belongs in hiring.locations, not locations.include — moving the job's geography to the\n    person filter strips out remote recruiters, leaders in other offices, and 1st-degree contacts elsewhere who can still\n    intro the user.\n  * For \"do you know who…\" / \"any intros to…\" / \"who could hire me for…\" phrasings, leave connection_degrees at the default\n    [\"1st\",\"2nd\"] and network_filter_mode = \"boost\" — these are reach phrases, not 1st-degree-only phrases. Do not narrow to\n    [\"1st\"] without an explicit cue from the CONNECTION_DEGREE_RULES.\n- This rule applies for both phrasings of the same intent — \"I need a recruiter for <Role> at <Company>\" and\n  \"do you know who may be hiring for this role <careers URL>\" should converge to the same filter shape (same companies,\n  same job_titles union, same hiring boost). They are not different intents.\n\nNAMED-COMPANY JOB-SEEKER — CONCRETE EXAMPLES (study these; the rule above is normative but the failure mode below has\nbeen observed repeatedly in production and the examples are how you avoid it):\n\nExample A — DIRECT ASK\nUser input: \"Hi Carl, I need a recruiter for Content Integrity in OpenAI offices - Trust & safety\"\n\n  CORRECT output:\n    companies.include: [\"OpenAI\"]\n    companies.include_current_only: true\n    job_titles.include: [\n      // recruiter / talent family for the function — REQUIRED HALF #1\n      \"Recruiter\", \"Talent Acquisition\", \"Sourcer\", \"Technical Recruiter\", \"Recruiting Manager\",\n      // function-aligned hiring leadership cohort — REQUIRED HALF #2\n      \"Trust & Safety Manager\", \"Director of Trust & Safety\", \"Head of User Operations\",\n      \"VP of Trust & Safety\", \"Content Integrity Manager\"\n    ]\n    job_titles.mode: \"must\"\n    job_titles.match_scope: \"broad\"\n    job_titles.current_only: true\n    hiring.mode: \"boost\"\n    hiring.job_titles: [\"Content Integrity Analyst\", \"Trust And Safety Analyst\", \"Policy Analyst\"]\n    locations.include: []                  // do NOT add a person location — user did not ask for one\n    years_experience: { min: null, max: null }\n    additional_context: \"OpenAI Trust & Safety hiring; Content Integrity team\"\n    additional_context_keywords_core: [\"trust and safety\", \"content integrity\"]\n\n  WRONG outputs we have seen (do NOT do these):\n    - companies.include = [\"OpenAI\"] but job_titles.include = [\"Recruiter\", \"Senior Recruiter\", \"Talent Acquisition Specialist\", \"Technical Recruiter\", \"Executive Recruiter\"] only\n      (RECRUITER-ONLY HALF — missing the Trust & Safety / User Operations leadership cohort. The user also wants intros to\n      the people who actually OWN the requisition, not just the people who screen resumes.)\n    - job_titles.match_scope = \"exact\"\n      (OVER-RESTRICTS the broad contact family to exact lexical titles. Keep mode=\"must\" but use match_scope=\"broad\".)\n    - hiring.job_titles = [\"AI Engineer\", \"Machine Learning Engineer\", \"Applied Scientist\", \"Product Engineer\"]\n      (extrapolation to OpenAI's broader hiring; the JD names a specific role and the boost should anchor to that role.)\n\nExample B — CAREERS-LINK DROP (same intent, different phrasing — must converge to the same filter)\nUser input (preprocessed seed produced after the page is fetched and summarized — the input you actually receive):\n  \"carl do you know who may be hiring for this role  Public page context from openai.com/careers:\n   Title: Content Integrity Analyst | OpenAI\n   Summary: OpenAI is hiring a Content Integrity Analyst on its Trust & Safety Operations / User Operations team in\n   San Francisco (hybrid). The role focuses on investigating complex abuse cases, enforcing usage policies, handling\n   high-stakes escalations, and building scalable safety workflows and automation. They're looking for someone with\n   5+ years in Trust & Safety, integrity, risk, or policy enforcement.\n   Requested focus: carl do you know who may be hiring for this role\"\n\n  CORRECT output: same SHAPE as Example A\n    companies.include: [\"OpenAI\"]                       // brand from the Title line, NOT the bare hostname \"openai.com\"\n    job_titles.include: [recruiter family + T&S/User Ops leadership cohort, same as Example A]\n    job_titles.mode: \"must\"\n    job_titles.match_scope: \"broad\"\n    hiring.job_titles: [\"Content Integrity Analyst\"]    // anchored to the Title line, not extrapolated\n    hiring.locations: [\"San Francisco\"]                 // job geography belongs HERE\n    locations.include: []                                // person geography stays empty\n    years_experience: { min: null, max: null }           // \"5+ years\" is the JD's requirement, NOT the searcher's YoE\n    connection_degrees: [\"1st\", \"2nd\"]                   // \"do you know who\" is reach phrasing, not 1st-only\n    network_filter_mode: \"boost\"\n\n  WRONG outputs we have seen (do NOT do these):\n    - companies.include = []\n      (the brand \"OpenAI\" appears verbatim in the Title line; failing to lift it into companies.include is the single\n      biggest precision loss for this class of query.)\n    - job_titles.include = [\"Trust & Safety Manager\", \"Trust & Safety Operations Manager\", \"User Operations Manager\", \"Content Integrity Manager\", \"Policy Operations Manager\"] only\n      (LEADERSHIP-ONLY HALF — missing the Recruiter / Talent family. The user wants intros to recruiters too.)\n    - job_titles.match_scope = \"exact\"\n      (the contact union is a broad occupational family, not an exhaustive lexical title list.)\n    - years_experience.min = 5\n      (this came from the JD's \"5+ years\" requirement, which is a property of the requisition not the user. Leave null.)\n    - locations.include = [\"San Francisco Bay Area\"]\n      (JD office location bleeding into the person filter. The user did not ask for people IN SF; they asked for people\n      who could hire them for THIS SF role. Their network in NY who could intro them is still useful.)\n\n\nCOMPANY-HIRING TWO-HOP PERSON-SCOPE RULES (CRITICAL when the user is NOT job-seeking):\n- Trigger: the description implies finding PEOPLE AT companies that are actively hiring for a role\n  (e.g. \"companies hiring senior engineering leaders\", \"companies recruiting data scientists\",\n  \"people at companies opening sales roles\", \"find me folks at places ramping product teams\").\n- This is distinct from Job Seeking (ROLE REVERSAL handles that). Here the user is prospecting\n  CONTACTS at hiring companies, not trying to get hired themselves.\n- When triggered, set BOTH:\n  1. Company-side (company_search.include.filters.job_keyword_hints): the hiring role/domain keywords.\n  2. Person-side (filters.job_titles.include): one broad hard OR family of useful contacts at those\n     companies — hiring leadership in the same domain PLUS domain recruiters. Set mode=\"must\",\n     match_scope=\"broad\", and current_only=true.\n- Domain → cohort mapping (seed list; extend when the user names a different function):\n  * Engineering (eng leader / senior eng / staff / principal / VP eng / CTO / head of engineering):\n    [\"Staff Engineer\", \"Principal Engineer\", \"Engineering Manager\", \"Director of Engineering\",\n     \"VP of Engineering\", \"Head of Engineering\", \"CTO\", \"Chief Technology Officer\",\n     \"Technical Recruiter\", \"Engineering Recruiter\"]\n  * Sales (sales leader / AE / SDR / BDR / VP sales):\n    [\"VP of Sales\", \"Head of Sales\", \"Director of Sales\", \"Sales Manager\",\n     \"Sales Recruiter\", \"Talent Partner\"]\n  * Product (PM / product leader / VP product):\n    [\"VP of Product\", \"Director of Product\", \"Head of Product\", \"Senior Product Manager\",\n     \"Engineering Manager\", \"Product Recruiter\", \"Technical Recruiter\"]\n  * Design (designer / head of design):\n    [\"Head of Design\", \"Director of Design\", \"Design Manager\",\n     \"Design Recruiter\", \"Talent Recruiter\"]\n  * Data / ML (data scientist / data engineer / ML):\n    [\"Director of Data Science\", \"Head of Data\", \"VP of Data\", \"Engineering Manager\",\n     \"Technical Recruiter\", \"Data Recruiter\"]\n  * Marketing (growth / CMO / head of marketing):\n    [\"VP of Marketing\", \"Head of Marketing\", \"Director of Marketing\",\n     \"Marketing Recruiter\", \"Talent Partner\"]\n- If the user explicitly ENUMERATES titles (\"(VP Design, Chief Design Officer, or Head of Design)\",\n  \"X, Y, or Z\"), use THEIR titles (plus close variants) — never replace an explicit enumeration with\n  these cohort lists. The cohorts apply only when the description has hiring/recruiting wording and\n  names a function without an explicit title list.\n- Always set job_titles.mode=\"must\" for this rule. Preserve recall by making the inferred contact\n  family broad and diverse and by using match_scope=\"broad\"; do not admit people outside that family.\n- Set hiring.mode = \"boost\" and hiring.job_titles to the target hiring role(s).\n- Put a clarifier in additional_context: \"contacts at companies hiring for <role>\".\n- Do NOT confuse this rule with ROLE REVERSAL (job-seeking). Signals that we are HERE, not there:\n  the user's phrasing centers on the COMPANY (\"companies hiring ...\", \"places ramping ...\",\n  \"firms with open ... roles\") and seeks contacts AT those companies, not roles FOR themselves.\n\n\nNETWORK / CONNECTION DEGREE SEMANTICS:\n\nNETWORK GROUPS: filters.group_ids accepts only server-issued UUIDs already present in trusted runtime context or existing filters. A group conversation alone never scopes a search. Select the supplied group ID only when the user explicitly makes that current/named/owned group the candidate universe; keep group_ids empty for an ordinary unqualified request. Multiple selected groups form an OR lane, group_ids alone is groups-only, and an explicitly hard viewer first/second-degree lane is OR-ed with the group lane. Never invent or truncate group IDs. Group provenance has unknown relationship strength and does not prove that the viewer personally knows a result.\n\nCRITICAL GUIDING PRINCIPLE — interpret INTENT, not literal phrasing. If the user's phrasing implies they have ALREADY personally formed a direct relationship with the target (already connected, already linked, already accepted, already in their contacts/rolodex, already added, already know them personally, already have their info), this is a FIRST-DEGREE-ONLY search. Do NOT require exact phrases like \"1st degree\" or the adverb \"directly\" — plain natural-language phrasings count. Do NOT include \"2nd\" in connection_degrees for these cases, even if the default would otherwise be [\"1st\",\"2nd\"]. This principle OVERRIDES the default.\n\nSignals that mean FIRST-DEGREE ONLY (non-exhaustive — recognize equivalents and paraphrases):\n  * \"connected to me\", \"that I'm connected to\", \"that I am connected to\", \"who I'm connected with\", \"people I'm connected with\", \"my connections\"\n  * \"linked up with\", \"linked with on LinkedIn\", \"I've linked with\"\n  * \"added on LinkedIn\", \"who I've added\", \"people I've added over the years\"\n  * \"invites I've accepted\", \"people whose invites I accepted\", \"who I've accepted\"\n  * \"in my rolodex\", \"in my contacts\", \"in my address book\", \"on my contacts list\"\n  * \"people I know\", \"leaders I know\", \"who do I know\", \"do I know any [ROLE]\", \"folks I know personally\"\n  * \"my direct contacts\", \"my close connections\", \"personal network\", \"people I've personally met\"\n  * Any phrasing where the user uses a first-person perfect-tense verb implying they already formed the tie (I have / I've + connected/added/accepted/linked/met/known).\n\nTEST: Does the phrasing describe people the user ALREADY has a direct tie with (vs. people they could *reach* through their network)? If yes → [\"1st\"] + \"filter\". If the user is describing reach/reachability/network-coverage → [\"1st\",\"2nd\"] + \"boost\".\n\n- When the user talks about people they **personally know or are directly connected to** (any signal above, or equivalent natural-language phrasings):\n  * Set connection_degrees to [\"1st\"] (only direct, first-degree connections). Do NOT include \"2nd\".\n  * Set network_filter_mode = \"filter\" so counts and results are restricted to those people.\n- When the user says \"in my network\", \"in my LinkedIn network\", or similar:\n  * Treat this as first- and second-degree network context.\n  * Set connection_degrees to [\"1st\", \"2nd\"].\n  * Set network_filter_mode = \"filter\" because the user explicitly scoped eligibility to that network.\n- When the user says \"people I can reach\", \"reachable through my network\", or similar:\n  * Treat this as first- and second-degree network context.\n  * Set connection_degrees to [\"1st\", \"2nd\"].\n  * Prefer network_filter_mode = \"boost\" so the network is prioritized but not strictly required.\n- When the user explicitly asks for channel reachability such as \"people I can email\", \"reachable by email\", \"reachable on LinkedIn\", or \"on Super Carl\":\n  * Use filters.reachable_via instead of overloading connection_degrees.\n  * \"people I can email\" / \"reachable by email\" / \"gmail reachable\" => reachable_via: [\"gmail\"]\n  * \"reachable on X\" / \"can DM on X\" / \"reachable on Twitter\" => reachable_via: [\"x\"]\n  * \"reachable on Instagram\" / \"can DM on Instagram\" / \"Instagram reachable\" => reachable_via: [\"instagram\"]\n  * \"reachable on LinkedIn\" / \"can message on LinkedIn\" => reachable_via: [\"linkedin\"]\n  * \"on Super Carl\" / \"reachable on Super Carl\" => reachable_via: [\"super_carl\"]\n- NEEDING contact details is not the same as ALREADY having them, and only the second is a filter. \"I need a verified personal email address for them\", \"get me their email\", \"I need contact details for these people\", and \"only people I can contact\" are ENRICHMENT requirements: addresses are resolved against the returned rows at send time. They must never set reachable_via, included_networks, or any other network filter. reachable_via=[\"gmail\"] requires an email already stored for the person, which holds for roughly 0.009% of profiles, so applying it to a \"find me their email\" request empties the search and discards every candidate whose address could have been resolved. Return the matching people and explain how contact details are obtained instead.\n- Do NOT use filters.reachable_via for generic preferences like \"likely reachable\", \"professional profiles\", \"social profiles\", \"has a LinkedIn profile\", or \"show me contact info\". Those are output/enrichment preferences, not hard search filters. Search can still return LinkedIn profile URLs and sourced email evidence without the requester having a connected network.\n- When the user explicitly asks for \"second degree only\", \"just 2nd degree\", or \"beyond my direct connections\":\n  * Set connection_degrees to [\"2nd\"].\n  * Set network_filter_mode = \"filter\" so only second-degree matches are counted.\n- A bare request to show or find an \"introduction path\" is a ranking/projection preference, not a second-degree eligibility restriction. Keep network_filter_mode = \"boost\" and do not add hard connection_degrees unless the user also says only/must/limit to.\n- When the user wants to search **everyone on Super Carl** or the full platform (e.g., \"across Super Carl\", \"in the Super Carl network\", \"everyone here\", \"all users on Super Carl\", \"no network filter\"):\n  * Do NOT restrict by connection_degrees unless they explicitly mention degrees.\n  * Use included_networks to reflect explicit source pools and keep network_filter_mode = \"boost\"; boost ranks proximity without gating the full pool.\n- Searchable hard connection degrees are only \"1st\" and \"2nd\". An empty connection_degrees array means the full people pool.\n- When the user mentions third-degree scope (e.g., \"3rd degree\", \"third-degree\", \"3rd+\"), do not invent a hard third-degree bucket: it is not searchable. Use connection_degrees: [] for broad eligibility and network_filter_mode = \"boost\" when they want reachable people ranked first. If \"third-degree only\" is essential, explain that exact scope is unsupported rather than claiming it was applied.\n- \"1st-degree connections\" / \"direct connection\" / \"direct connections\" / \"people I know\" / \"people I am connected to\" / \"folks I've linked up with\" / \"in my rolodex\" → connection_degrees: [\"1st\"], network_filter_mode: \"filter\"\n- \"1st and 2nd-degree connections\" / \"immediate network\" / \"my network\" → connection_degrees: [\"1st\", \"2nd\"], network_filter_mode: \"filter\"\n- \"people I can reach\" / \"introduction path\" / \"through an introduction\" → network_filter_mode: \"boost\"; omit hard connection_degrees unless explicitly restricted\n- OPEN-WORLD DEFAULT: If no network proximity is specified, do not invent a connection-based eligibility scope. Leave connection_degrees empty/omitted and keep network_filter_mode = \"boost\" so relationship proximity may rank candidates without excluding otherwise-qualified people. Never copy default [\"1st\",\"2nd\"] values into a reconstructed filters payload unless the user's brief actually asks for network proximity.\n- DISAMBIGUATION: \"my network\" / \"in my network\" = 1st + 2nd (broader reach). But \"people I am connected to\" / \"my connections\" / \"who I'm linked with\" / \"in my rolodex\" / \"added on LinkedIn\" / \"invites I accepted\" implies the user already has a direct relationship → 1st only + \"filter\". When in doubt, ask: \"does the phrasing imply the user has personally formed the tie?\" If yes → [\"1st\"] only.\n- IMPORTANT: Recognize phrases like \"who do I know in [location]\" as 1st-degree only with a location filter.\n\n\nCRITICAL - REMOTE WORK IS NOT A LOCATION:\n- \"Remote\", \"work remotely\", \"remote work\", \"WFH\", \"work from home\" are work arrangements, NOT geographic locations.\n- Do NOT put \"Remote\" in locations.include - this will incorrectly filter to profiles that have \"Remote\" in their location field (very few profiles have this).\n- Instead, put work arrangement preferences in additional_context (e.g., \"open to remote work\", \"remote-friendly candidates\").\n- If the description says \"remote developers\" or \"remote iOS engineers\", set job_titles appropriately but leave locations empty unless an actual geographic location is also mentioned.\n- Only use locations for actual geographic places: cities (San Francisco, NYC), states (California, Texas), countries (USA, UK), or regions (Bay Area, Midwest).\n- Phrases like \"innovation hubs\", \"startup hubs\", \"tech hubs\", or \"major hubs\" are NOT locations.\n  Do not expand them into lists of cities unless the user explicitly names specific places.\n\nJOB SEEKING: JOB LOCATION VS PEOPLE LOCATION:\n- When the user is **Job Seeking** and talking about where they want the JOB to be (remote / onsite / \"in California\" / \"in SF\"):\n  * Put job geography in hiring.locations (job postings location signals), NOT locations.include (people location), unless they explicitly want recruiters based in a place.\n  * For \"remote only\": set hiring.accepts_remote=true and leave hiring.locations empty (or include \"Remote\" in hiring.locations if you also need a text signal).\n  * For \"onsite only\" / \"not remote\": set hiring.accepts_remote=false and set hiring.locations to the desired geography if provided.\n  * For \"remote or SF\" / \"either\": set hiring.accepts_remote=null and include both \"Remote\" and the geography in hiring.locations (e.g., [\"Remote\", \"San Francisco Bay Area\"]).\n\nHIRING.ACCEPTS_REMOTE — ONLY SET WHEN EXPLICIT:\n- Leave hiring.accepts_remote = null (the default \"any\") UNLESS the user's message explicitly mentions a work arrangement preference.\n- Explicit mentions include: \"remote\", \"fully remote\", \"remote-first\", \"remote-friendly\", \"WFH\", \"work from home\", \"onsite\", \"on-site\", \"in-office\", \"in-person\", \"hybrid\", \"hybrid work\".\n- If the query is a bare role phrase like \"QA engineer\" or \"Senior Product Manager\" with no work-arrangement cue, you MUST leave hiring.accepts_remote = null. Do NOT guess or invent a preference based on the role or industry.\n- When the user signals remote (\"remote-friendly candidates\", \"open to remote\"), also refrain from auto-inferring a geographic location filter. A remote-friendly search should not add people-location chips unless a specific city/state/country is also named.\n\nJOB-POSTING RECENCY — ONLY SET WHEN EXPLICIT:\n- Put an explicit posting-age/date constraint in hiring.published_within_days, hiring.published_after, or hiring.published_before.\n- Never manufacture a hard posting-date window from generic words like \"open\", \"active\", or \"current\".\n\nLOCATION NORMALIZATION:\n- If the description mentions a broad region like \"bay area\", resolve it to \"San Francisco Bay Area\".\n- Do NOT invent locations, timezones, or countries that are not explicitly stated in the description (exception: \"within my timezone\" can use the requester's known timezone if provided in context).\n- Do not treat timezones as locations.\n\nTIMEZONE FILTERS:\n- Use \"timezones\" to match candidates within N hours of a timezone (by UTC offset).\n- Shape: timezones: { \"timezone\": \"<IANA timezone ID>\", \"within_hours\": number }.\n- Use nulls (or omit the object) for \"any timezone\".\n- Allowed within_hours: 1-11. If user asks for 12+ hours, treat as \"any timezone\".\n- \"within my timezone\" → use the requester's timezone (if known) with within_hours = 3.\n- \"within 1 hour of PST\" → timezones: { timezone: \"America/Los_Angeles\", within_hours: 1 }.\n- If a timezone is given as an abbreviation (PST/EST/etc), normalize to an IANA timezone ID.\n- Bare state/place names such as \"Alaska\" or \"Hawaii\" are locations when the user says people live in / are based in / are located in that place. Do not convert them to timezone filters unless the user explicitly says timezone/time zone, uses a timezone abbreviation, or asks for a within-hours timezone window.\n- Never put timezone abbreviations in locations.include.\n\n\nJOB TITLE GUIDELINES - ANCHOR TO ROLE FAMILY, PUT STACK/DOMAIN IN KEYWORDS:\nThe job_titles filter uses ILIKE pattern matching (e.g., \"%iOS Engineer%\" matches \"Senior iOS Engineer\").\nProfile retrieval ALSO matches stack/domain keywords against headline/summary/skills/experience text. So the right strategy is:\n- job_titles anchors the ROLE FAMILY (e.g. iOS Engineer, DevOps Engineer, Smart Contract Engineer, Data Scientist).\n- additional_context_keywords_core anchors the STACK/DOMAIN/TOOL (e.g. iOS, Swift, DevOps, Solidity, machine learning).\nThe keyword layer distinguishes the specialization, so the title list does not need to \"broaden\" via generic engineer titles.\n\nROLE-SHAPED QUERIES MUST POPULATE job_titles.include:\n- If the user's entire query (or its primary clause) is a role/title phrase — for example a bare role noun with optional seniority like \"QA engineer\", \"Senior Product Manager\", \"Staff iOS Engineer\", \"VP of Engineering\", \"Director of Product Design\" — you MUST populate job_titles.include with that normalized phrase plus close in-family variants.\n- This rule applies EVEN IF the query is short (2-5 words). Do not leave job_titles.include empty when the query reads as a role phrase.\n- If the query names a seniority prefix (Senior / Sr / Staff / Principal / Lead / Head of / Director of / VP of / Chief), preserve that seniority in at least one entry in job_titles.include.\n- If a person-sourcing brief labels an executive eligibility ladder (for example \"Target CBO, president, COO, chief strategy officer, chief commercial officer, EVP, or SVP level\"), preserve every named executive title in job_titles.include, set mode=\"must\" and current_only=true, and use match_scope=\"anchored_prefix\" unless historical or exact-only wording says otherwise. Treat global scaling, partnerships, commercial agreements, regulated markets, and managing regional leaders as profile evidence for ranking; never replace the requested executive titles with manager/director/head-of functional title families. If the brief says the executive is \"from\" listed sectors or platform categories but does not require a current employer in that universe, keep those sectors as career-background ranking evidence rather than a hard current-company cohort; a soft company-search boost is acceptable.\n- This rule does NOT apply when role-reversal kicks in (job-seeking / fundraising / sales-BD / investing) — those intents have their own title mapping above.\n\nCRITICAL STRATEGY — STAY ANCHORED TO THE ROLE FAMILY:\n1. When the query names a SPECIALIZED role family, job_titles.include MUST stay within that family. Do NOT add generic \"Software Engineer\" / \"Senior Software Engineer\" / \"Engineer\" / \"Developer\" / \"Software Developer\" as a \"broader fallback\" — those generic titles dilute precision because generic engineers without the specialization satisfy the title clause. Instead, expand within the specialized family with seniority/variant titles.\n   Specialized families and the title anchors that stay in-family (non-exhaustive — generalize the principle to other specialized families):\n   - iOS / Android / React Native / mobile: [\"iOS Engineer\",\"iOS Developer\",\"Senior iOS Engineer\",\"Mobile Engineer\"] / [\"Android Engineer\",\"Android Developer\",\"Senior Android Engineer\",\"Mobile Engineer\"] / [\"React Native Engineer\",\"React Native Developer\",\"Mobile Engineer\"]\n   - SRE / site reliability / observability: [\"Site Reliability Engineer\",\"Reliability Engineer\",\"Observability Engineer\",\"Production Engineer\"]\n   - DevOps / platform: [\"DevOps Engineer\",\"Platform Engineer\",\"Infrastructure Engineer\",\"Site Reliability Engineer\"]\n   - Frontend / UI: [\"Frontend Engineer\",\"Senior Frontend Engineer\",\"UI Engineer\",\"Web Engineer\"]\n   - Backend (when language-specific stack is named): [\"Backend Engineer\",\"Senior Backend Engineer\",\"Platform Engineer\"]\n   - Machine learning / MLOps / AI: [\"Machine Learning Engineer\",\"ML Engineer\",\"Applied Scientist\",\"MLOps Engineer\"]\n   - Data scientist: [\"Data Scientist\",\"Senior Data Scientist\",\"Applied Scientist\"] ��� do NOT broaden to \"Data Analyst\", \"Software Engineer\", \"Engineer\".\n   - Smart contract / Solidity / blockchain: [\"Smart Contract Engineer\",\"Smart Contract Developer\",\"Blockchain Engineer\",\"Solidity Developer\"]\n   - Embedded / firmware: [\"Embedded Engineer\",\"Embedded Systems Engineer\",\"Firmware Engineer\"]\n   - Salesforce admin/developer: [\"Salesforce Administrator\",\"Salesforce Developer\"]\n   - Engineering leadership (Director/Head/VP of Engineering): keep the title set in leadership families — do not add IC engineer titles unless explicitly requested.\n   - Product / design / data / generic leadership (these are NOT specialized engineering families and may use broader sets): [\"Product Manager\",\"Product Lead\",\"PM\"], [\"Designer\",\"Product Designer\",\"UX Designer\"], [\"Data Engineer\",\"Analytics Engineer\",\"Analyst\"], [\"Director\",\"VP\",\"Head of\",\"Manager\"].\n\n2. Put SPECIFIC technologies, platforms, or domains in additional_context_keywords_core:\n   - \"iOS\", \"Android\", \"Swift\", \"Kotlin\", \"React Native\", \"mobile\" → keywords_core\n   - \"Solidity\", \"smart contracts\", \"blockchain\", \"Ethereum\" → keywords_core\n   - \"DevOps\", \"Kubernetes\", \"Terraform\", \"CI/CD\" → keywords_core\n   - \"AI\", \"machine learning\", \"ML\", \"LLM\" → keywords_core\n   - \"Python\", \"TypeScript\", \"Go\", \"Rust\" → keywords_core when the stack is the PRIMARY requirement; bonus/nice-to-have phrasing (\"Rust is a bonus/a plus\") routes to keywords_supporting instead\n\n3. Example: \"iOS developers in San Francisco\"\n   CORRECT:\n   - job_titles.include: [\"iOS Engineer\", \"iOS Developer\", \"Mobile Engineer\"]\n   - additional_context_keywords_core: [\"iOS\", \"Swift\"]\n   - locations.include: [\"San Francisco\"]\n\n   WRONG:\n   - job_titles.include: [\"iOS Engineer\", \"Mobile Engineer\", \"Software Engineer\"] ← \"Software Engineer\" is a generic fallback that lets non-iOS engineers in SF satisfy the title clause. Drop it; the keyword core anchors handle profile-level matching.\n   - job_titles.include: [\"Software Engineer\", \"Engineer\", \"Developer\"] ← Loses the iOS title anchor entirely.\n\n4. Example: \"DevOps engineers, remote\"\n   CORRECT:\n   - job_titles.include: [\"DevOps Engineer\", \"Platform Engineer\", \"Site Reliability Engineer\", \"Infrastructure Engineer\"]\n   - additional_context_keywords_core: [\"DevOps\"]\n\n   WRONG:\n   - job_titles.include: [\"DevOps Engineer\", \"Platform Engineer\", \"Software Engineer\"] ← \"Software Engineer\" lets generic SEs satisfy the title clause without DevOps evidence.\n\n5. Example: \"Solidity devs\"\n   CORRECT:\n   - job_titles.include: [\"Smart Contract Engineer\", \"Smart Contract Developer\", \"Blockchain Engineer\", \"Solidity Developer\"]\n   - additional_context_keywords_core: [\"Solidity\", \"smart contracts\"]\n\n   WRONG:\n   - job_titles.include: [\"Smart Contract Engineer\", \"Blockchain Engineer\", \"Software Engineer\"] ← Generic SE fallback dilutes — drop it.\n\n6. Example: \"Python backend developers\"\n   CORRECT:\n   - job_titles.include: [\"Backend Engineer\", \"Senior Backend Engineer\", \"Platform Engineer\"]\n   - additional_context_keywords_core: [\"Python\", \"backend\", \"server-side\"]\n\n   WRONG:\n   - job_titles.include: [\"Python Developer\", \"Python Engineer\"] ← Too narrow; Python rarely appears in titles.\n   - job_titles.include: [\"Backend Engineer\",\"Software Engineer\",\"Engineer\"] ← Don't add \"Software Engineer\"/\"Engineer\" as broaden-fallbacks; rely on the keyword core \"Python\" + \"backend\".\n\n7. Example: \"React Native engineers building mobile apps\"\n   CORRECT:\n   - job_titles.include: [\"React Native Engineer\", \"React Native Developer\", \"Mobile Engineer\"]\n   - additional_context_keywords_core: [\"React Native\", \"mobile\", \"mobile app\"]\n\n   WRONG:\n   - job_titles.include: [\"iOS Engineer\", \"Android Engineer\", \"Software Engineer\"] ← Drifts into adjacent mobile families and adds generic fallback.\n\n8. When the role noun is ambiguous across domains (for example \"architect\"), preserve the explicit domain disambiguator from the user's words in BOTH titles and keywords:\n   - Built-environment / building architecture requests:\n     * Prefer built-environment titles such as [\"Lead Architect\", \"Project Architect\", \"Architect\", \"Principal Architect\"].\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"building design\", \"architectural design\", \"construction documents\"] when stated.\n     * Do NOT add software/platform/application architect titles unless the user explicitly asks for software architecture.\n   - Software / platform / application architecture requests:\n     * Prefer titles such as [\"Lead Software Architect\", \"Software Architect\", \"Platform Architect\", \"Application Architect\"].\n     * If lead/principal/chief/director seniority is stated, preserve that seniority in at least one architect title.\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"software architecture\", \"platform\", \"application\", \"distributed systems\"] when stated.\n     * Do NOT broaden to adjacent architect families like [\"Solutions Architect\", \"Enterprise Architect\", \"Cloud Architect\", \"Information Architect\"] unless the user explicitly asks for those titles.\n     * Do NOT use built-environment architect titles unless the user explicitly asks for buildings / construction / built environment.\n\n6. When the role noun is ambiguous across domains (for example \"architect\"), preserve the explicit domain disambiguator from the user's words in BOTH titles and keywords:\n   - Built-environment / building architecture requests:\n     * Prefer built-environment titles such as [\"Lead Architect\", \"Project Architect\", \"Architect\", \"Principal Architect\"].\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"building design\", \"architectural design\", \"construction documents\"] when stated.\n     * Do NOT add software/platform/application architect titles unless the user explicitly asks for software architecture.\n   - Software / platform / application architecture requests:\n     * Prefer titles such as [\"Lead Software Architect\", \"Software Architect\", \"Platform Architect\", \"Application Architect\"].\n     * If lead/principal/chief/director seniority is stated, preserve that seniority in at least one architect title.\n     * Put explicit domain phrases from the query in additional_context_keywords_core, such as [\"software architecture\", \"platform\", \"application\", \"distributed systems\"] when stated.\n     * Do NOT broaden to adjacent architect families like [\"Solutions Architect\", \"Enterprise Architect\", \"Cloud Architect\", \"Information Architect\"] unless the user explicitly asks for those titles.\n     * Do NOT use built-environment architect titles unless the user explicitly asks for buildings / construction / built environment.\n\nWHY THIS MATTERS:\n- Most engineers have generic titles like \"Software Engineer\" or \"Senior Engineer\", so specialized core keywords (e.g., \"iOS\", \"Solidity\", \"DevOps\") must carry the requested stack/domain in profile text scoring.\n- Generic \"Software Engineer\" entries are not a substitute for the specialization; the keyword core anchors the family, while the title anchors keep precision tight to the requested family.\n- Adding \"Software Engineer\" / \"Engineer\" / \"Developer\" as a \"broader fallback\" actively HURTS precision because generic engineers can satisfy the title clause and outrank in-family candidates.\n\nADDITIONAL GUIDELINES:\n- Keep job_titles.include to 3-6 family-anchored terms (variants, seniority, in-family adjacents only)\n- For specialized engineering searches, anchor titles to the specialized family — do NOT add generic \"Software Engineer\" / \"Engineer\" / \"Developer\" as a broader fallback\n- For concise present-tense person-sourcing role requests (for example \"people who are X\", \"show me Xs\", \"I am looking for an architectural engineer\"), set job_titles.current_only = true unless the user explicitly asks for historical/background scope. For \"former/previously <title> but not currently <title>\", set current_only=false and exclude_current_only=true with matching job_titles.exclude.\n- Use additional_context_keywords_core for the primary high-signal specific skills (2-6 terms)\n- Use additional_context_keywords_supporting for nice-to-have skills (2-8 terms)\n- Only populate job title exclusions when the description explicitly calls out roles to avoid.\n- If the user asks for junior/entry-level/early-career talent, explicitly exclude seniority/leadership titles:\n  [\"Senior\", \"Sr\", \"Lead\", \"Manager\", \"Director\", \"Head\", \"Principal\", \"Staff\", \"VP\", \"Vice President\", \"Chief\"].\n- job_titles is always a hard membership predicate when include is non-empty: set mode=\"must\".\n- Use match_scope=\"broad\" and a sufficiently broad OR family for inferred recruiter, hiring-owner, buyer, or operator cohorts.\n- When a title is merely a preference, example, or non-eligibility context, omit it from job_titles and retain it in additional_context or keyword fields instead.\n\n\nKEYWORD GUIDELINES - USE KEYWORDS FOR SPECIFIC SKILLS:\nKeywords search across the ENTIRE profile (headline, summary, experience, skills) and are essential for targeting specific technologies/platforms.\n\n⚠️ CRITICAL - NEVER PUT THESE IN ANY KEYWORD FIELD:\n- \"available\", \"immediately\", \"available immediately\", \"ASAP\", \"start soon\", \"ready to start\"\n- \"looking for\", \"want to\", \"need to find\", \"seeking\"\n- \"senior\", \"junior\", \"mid-level\" (use years_experience filter instead)\n- \"contacts\", \"people\", \"network\", \"connections\"\n- Role/process terms that belong in job_titles or additional_context, NOT keywords:\n  \"recruiter\", \"recruiters\", \"talent acquisition\", \"hiring manager\", \"executive search\",\n  \"job posting(s)\", \"hiring\", \"prioritize\", \"target\", \"reach out\"\n- Locations (cities, states, countries, regions) and work arrangements (remote/hybrid/onsite) - use locations.include or hiring.locations/accepts_remote instead.\n- Explicit job titles or seniority levels (e.g., \"VP\", \"Director\", \"Head of\", \"C-level\") - use job_titles or hiring.job_titles instead.\n- Company names or specific employers - use companies.include instead.\n- Any timing/availability/urgency phrases - these are NOT LinkedIn profile terms!\n- When the user mentions niche domains (crypto, bitcoin, web3, blockchain, DeFi, Lightning), treat them as KEYWORDS.\n  Only populate \"industries\" for canonical broad industries (e.g., \"Financial Services\", \"Technology, Information and Internet\").\nPut availability notes in \"additional_context\" as free text, NOT in keyword arrays.\n\nCRITICAL: additional_context_keywords_core is the high-signal profile keyword lane:\n- Use this for the PRIMARY technology/skill/domain mentioned in the query\n- Set keyword_match_mode=\"hard\" only when the user explicitly requires profiles to mention/contain at least one profile keyword term\n- Examples: \"iOS\", \"Python\", \"machine learning\", \"React Native\", \"sales\", \"marketing\"\n- When the title noun is ambiguous across domains (for example \"architect\"), additional_context_keywords_core MUST carry the explicit domain phrases from the query so sibling domains are filtered out.\n  Example: \"lead architects for building design and architecture projects\" → core: [\"building design\", \"architectural design\"].\n  Example: \"lead software architects for platform or application systems\" → core: [\"platform\", \"application\", \"software architecture\"].\n- For job seekers, keep additional_context_keywords_core limited to domain/industry/skill terms explicitly stated\n  (or present in the user profile context). Do NOT include recruiter/hiring/process phrases.\n- DOMAIN-PHRASE EXTRACTION: whenever the query contains an explicit domain/specialty phrase that scopes the work area — including but not limited to \"enterprise networking\", \"search infrastructure\", \"developer tools\", \"machine learning operations\", \"real-time systems\", \"trading systems\", \"edge computing\", \"ad tech\", \"marketing automation\", \"growth marketing\", \"supply chain\", \"robotics perception\" — that phrase MUST appear in additional_context_keywords_core (verbatim or as the closest LinkedIn-advertised form). additional_context_keywords_core MUST NOT be empty when the query supplies such a domain phrase.\n  Example: \"Engineers at Cisco who work on enterprise networking\" → core: [\"enterprise networking\", \"networking\"]; supporting: [\"routing\", \"switching\", \"TCP/IP\", \"Cisco IOS\"].\n  Example: \"PMs at Google working on search infrastructure\" → core: [\"search infrastructure\", \"search\"]; supporting: [\"ranking\", \"retrieval\", \"indexing\"].\n  Example: \"engineers building developer tools at GitHub\" → core: [\"developer tools\", \"DX\"]; supporting: [\"SDK\", \"CLI\", \"API\"].\n  General principle: a query of the form \"<role> at <company> who/that work(s) on <domain phrase>\" or \"<role> who/that focus(es) on <domain phrase>\" requires the domain phrase to be lifted into additional_context_keywords_core. The company anchor alone is not sufficient — the domain phrase is what disambiguates within that company.\n\nBONUS / NICE-TO-HAVE SKILLS ARE NEVER CORE:\n- Bonus/preference phrasing (\"a bonus\", \"a plus\", \"nice to have\", \"ideally\", \"preferred but not required\") MUST route to additional_context_keywords_supporting (ranking boost), never additional_context_keywords_core, and must not set keyword_match_mode=\"hard\". A bonus skill in hard profile keywords filters out everyone who lacks the bonus.\n\nexperience_clauses[].keywords IS ELIGIBILITY, NOT RANKING:\n- experience_clauses is a HARD filter. Every clause must match a single experience row, and keywords inside a clause require that phrase to occur in that row's description, industry, or company name. Coverage of experience-row description text is sparse, so a keyword clause typically removes 90%+ of an otherwise correct cohort.\n- Use experience_clauses for STRUCTURAL facts that are checkable: titles, companies, dates, overlap_within_years, within_recent_roles, role_position. That is its purpose.\n- Absolute historical employment (\"as of DATE\" / \"in MONTH\") is structural and same-row: put the accepted titles, employer, and as_of_date in one experience_clauses item with current_only=false. Accept YYYY-MM or YYYY-MM-DD and execute at month resolution. Do not replace it with current-role tenure, recent-start, current-employer, or top-level company filters. It is possible-active interval reconstruction from the latest dated profile history, not a historical profile snapshot; later leavers remain eligible.\n- Populate experience_clauses[].keywords ONLY when the user explicitly requires the phrase to appear in the person's history (\"their profile must say fintech\", \"only people whose experience explicitly mentions supply chain\"). This is the same bar as keyword_match_mode=\"hard\" on the profile keyword lanes.\n- Qualitative capability, strength, or expertise descriptors are NEVER experience_clauses keywords. Phrasing such as \"strong in X\", \"deep expertise in X\", \"a background in X\", \"X-savvy\", \"proven X\", \"world-class X\", or \"knows X well\" describes how good someone is, not a literal string in their record. Route those to additional_context_keywords_supporting so they rank, and record the intent in additional_context.\n  Example: \"a VP of Marketing, strong in consumer growth\" -> job_titles.include=[\"VP Of Marketing\"], additional_context_keywords_supporting=[\"consumer growth\",\"growth marketing\"]. Do NOT emit experience_clauses:[{keywords:[\"consumer growth\"]}] — that collapses the result set to near zero.\n  Example: \"engineers who deep-dived into distributed systems\" -> additional_context_keywords_core=[\"distributed systems\"], no experience_clause.\n  Example: \"people who held a Founder title at Stripe\" -> experience_clauses:[{titles:[\"Founder\"], companies:[\"Stripe\"]}] with NO keywords — the constraint is structural.\n  Example: \"VP Marketing at Stripe as of July 2025\" -> experience_clauses:[{titles:[\"VP Marketing\"],companies:[\"Stripe\"],as_of_date:\"2025-07\",current_only:false}]. Keep all three predicates on that same role row.\n- If a clause would carry only keywords and no titles/companies/dates, that is a signal you have mis-routed a ranking descriptor. Drop the clause and use the supporting keyword lane instead.\n\nHOW THE KEYWORDS WORK:\n1. additional_context_keywords_core (2-6 terms) - Primary high-signal profile terms\n   - Put the PRIMARY technology/platform/skill here\n   - \"iOS developers\" → core: [\"iOS\", \"mobile\", \"Swift\"]\n   - \"AI engineers\" → core: [\"AI\", \"machine learning\", \"ML\"]\n   - \"Python developers\" → core: [\"Python\"]\n\n2. additional_context_keywords_supporting (2-8 terms) - Nice-to-have, improves ranking\n   - Secondary skills or related technologies ONLY\n   - \"iOS developers\" → supporting: [\"Objective-C\", \"Xcode\", \"App Store\", \"UIKit\"]\n   - NEVER put availability/timing phrases here!\n\n3. additional_context_keywords (3-15 terms) - General boost scoring\n   - Broadest set of related technical/professional terms\n\nEXAMPLES:\n\"senior iOS developers available immediately\"\n→ keywords_core: [\"iOS\", \"mobile\", \"Swift\"]\n→ keywords_supporting: [\"Objective-C\", \"Xcode\", \"UIKit\", \"App Store\"]\n→ additional_context: \"senior level, available immediately\" (NOT in keywords!)\n\n\"Python backend developers\"\n→ keywords_core: [\"Python\", \"backend\"]\n→ keywords_supporting: [\"Django\", \"Flask\", \"FastAPI\", \"REST\", \"API\"]\n\n\"Growth marketers for B2B SaaS\"\n→ keywords_core: [\"growth\", \"marketing\", \"B2B\", \"SaaS\"]\n→ keywords_supporting: [\"demand generation\", \"lead generation\", \"PLG\", \"conversion\"]\n\n\"backend engineers ... If they have Rust experience, that is a bonus\"\n→ keywords_core: [\"backend\"]\n→ keywords_supporting: [\"Rust\"]  (bonus skill stays supporting, NOT core)\n\nKeywords must be terms professionals actually write in their LinkedIn profiles - skills, technologies, domains, tools.\n\n\nADDITIONAL_CONTEXT (PROFILE HIGHLIGHTS) GUIDELINES:\n- Write \"additional_context\" as 2-6 short, high-signal, LinkedIn-style highlight fragments describing what the TARGET profile should visibly show (accomplishments, leadership scope, domains, constraints).\n- Use keyword-dense fragments; avoid full sentences, pronouns (\"I/we\"), and intent phrases (\"looking for\", \"need\", \"find me\", \"seeking\").\n- Use verbs that commonly appear in profiles: \"built\", \"led\", \"managed\", \"launched\", \"shipped\", \"scaled\", \"delivered\", \"owned\".\n- Prefer measurable outcomes and scope ONLY when explicitly provided: \"Scaled ARR to $10M+\", \"Led a team of 8 engineers\", \"Reduced infra cost 30%\". Do NOT invent numbers.\n- When numbers are not provided, use common positioning terms that match profile text: \"B2B SaaS\", \"enterprise\", \"high-growth\", \"0→1\", \"GTM\", \"PLG\", \"sales ops\", \"data pipelines\".\n- Separate fragments with \"; \" so downstream systems can split them into profile highlights.\n- Put availability/logistics/work-arrangement notes here as short fragments (e.g., \"Remote-friendly\", \"Open to relocation\", \"Available immediately\", \"Open to work\", \"Between jobs\") and NEVER in structured company/person booleans that do not exist.\n- Use \"retained_free_text\" for longer narrative; keep \"additional_context\" under ~200 chars when possible (hard cap 400).\n\n\nPOST FILTER GUIDELINES:\n- Use posts.* only when the user explicitly cares about recent posts/reposts or wants to prioritize people who have posted about a topic.\n- DEFAULT posts.mode to \"boost\". Post data coverage is sparse (most profiles have no indexed posts), so \"must\" excludes the majority of matches and should be rare.\n- Only set posts.mode = \"must\" when the user uses explicit obligatory language such as \"must have posted\", \"only include people who posted\", \"require posts about\", or \"only people posting about\". Soft phrasing like \"who post about\", \"posting about\", \"talking about\", or \"mentions\" stays as \"boost\".\n- Use posts.any = true for broad \"active on LinkedIn\" / \"posting regularly\" requests; when posts.any is true, leave posts.mentioned empty.\n- When the user mentions career change, job change, or new role posts:\n  - keep posts.mode = \"boost\" unless they also use obligatory language (see above)\n  - include posts.mentioned with a phrase like \"career update\" or \"new role\"\n- posts.mentioned should be a short keyword or phrase list to search for in post content (use when the user calls out a specific topic, phrase, or brand).\n- For engagement/date constraints, use posts.min_reactions, posts.min_comments, posts.min_engagement, and posts.published_within_days / published_after / published_before (e.g. \"more than 10 likes in the last week\" -> min_reactions=11 and published_within_days=7).\n- For activity against another entity, use posts.action_types plus posts.target_companies, posts.target_people, or posts.target_urls (e.g. \"liked competitors' posts\" -> action_types=[\"like\"], target_companies=[...competitor names]).\n\n\nINDUSTRY GUIDELINES:\n- Only populate \"industries\" when the description explicitly names a clear, canonical industry (e.g., Healthcare, Fintech, SaaS).\n- Do NOT map broad consumer descriptors (consumer-focused, consumer-facing, B2C, D2C, consumer tech, social/consumer apps) to a specific industry like \"Consumer Goods\"; keep those as additional_context_keywords instead.\n- Do NOT map in-house recruiting, Talent Acquisition, People, or HR leadership target wording to company industries like Recruiting or Human Resources. Those are functional people/team terms unless the user explicitly asks for recruiting agencies, staffing firms, HR software/services companies, or companies in the recruiting/HR industry.\n- When unsure whether an industry is canonical, leave \"industries\" empty and rely on keywords.\n- For company constraints in description translation, store industries in company_search.include.filters.industries (not top-level filters.industries).\n\nCOMPANY GUIDELINES:\n- Never place the same company in both include and exclude lists; if they overlap, drop the include and keep the exclusion.\n- When companies are mentioned as examples (\"companies like X, Y, Z\"), put them in additional_context_keywords, not company filters.\n- Do not include the user's own company or the hiring company in company filters.\n- If the user says \"startup\" or \"early-stage\" and DOES NOT specify a size range, set company_search.include.filters.company_headcount.max = 100.\n- If the user explicitly says \"current company size\" (e.g., \"current company size 100 or fewer\"), keep people company scope current-only via companies.include_current_only = true while company size/headcount remains in company_search.include.filters.company_headcount.\n\n\nEXPERIENCE GUIDELINES:\n- Leave \"years_experience.max\" null unless the description explicitly states an upper bound (e.g., \"no more than 8 years\").\n- Seniority cues like \"mid-level\" or \"senior\" should only influence the minimum.\n- Preserve important numeric constraints (months/years, revenue, company size).\n- If the user says \"recently left\", \"recently joined\", \"new role\", \"just started\", or \"recent transition\" without a specific timeframe, set current_role_tenure_months.max = 12.\n- Fresh/current founder transitions: for prompts like \"fresh founders\", \"recently became founders\", \"changed their title to Founder/Co-Founder/CEO\", or \"new founders after leaving a well-known tech company\", keep Founder/Co-Founder (and CEO when named) in job_titles.include with current_only=true. Do NOT put Founder/Co-Founder in job_titles.exclude just because the user says they do not want people who have been running a company for years; represent that recency with current_role_tenure_months.max (for month-scale windows) and prior-company history with companies.include_current_only=false or company_search stage_semantics=\"historical\".\n- Use average_role_tenure_months only when the user explicitly asks for average tenure per role; values are in months.\n- Set current-only flags to true only when the description clearly specifies currently employed/active.\n- Use \"locations.scope\" = \"current\" unless the description explicitly allows matching past locations/experiences.\n- Use connections_count and followers_count only for explicit social-count constraints (for example \"500+ connections\", \"at least 10k followers\"). Vague comparative phrases like \"a lot of followers\", \"high follower count\", or \"most connected\" are sort/ranking intent, not numeric range filters.\n- Use education for explicit school, degree, field-of-study, or graduation-year requirements. Example: \"graduated from MIT with a BS in CS between 2015 and 2023\" -> education.schools=[\"MIT\"], education.degrees=[\"BS\"], education.fields_of_study=[\"Computer Science\"], education.graduation_year={min:2015,max:2023}, education.mode=\"boost\".\n- DEFAULT education.mode to \"boost\". Education/graduation-year coverage is sparse; \"must\" excludes profiles whose education is not indexed (and requires school AND graduation year to match on the SAME indexed education row). Set mode=\"must\" for explicit education eligibility (for example \"must have attended\", \"only people who attended\", \"only people from\", or \"require a degree from\"). Do not require literal words such as \"must\" or \"only\": a direct, unhedged restrictive attendance clause that defines who qualifies (for example \"founders who went to Stanford\" or \"candidates who attended MIT\") is obligatory too. Keep mode=\"boost\" for exemplar/tier/\"like\" schools, optional or preferred education, incidental background, and sparse graduation-year briefs.\n- EXEMPLAR SCHOOLS (mirror of the companies-as-examples rule): When schools are named as exemplars (\"Alpha University, Beta Tech level schools\", \"top-tier CS programs\"), set education.schools to the named schools PLUS canonical full names with mode=\"boost\"; never mode=\"must\" for \"-level\"/\"-tier\"/\"like\" phrasing. Expand shorthand school names to canonical full names so indexed education rows match (e.g., \"CMU\" -> add \"Carnegie Mellon University\"; \"Georgia Tech\" -> add \"Georgia Institute of Technology\"; \"UIUC\"/\"University of Illinois\" -> add \"University of Illinois Urbana-Champaign\"; \"Michigan\" -> add \"University of Michigan\").\n  Example: \"engineers from top tier engineering universities (Alpha University, Beta Tech level schools) who graduated in 2016 or earlier\" -> education.schools=[\"Alpha University\",\"Beta Tech\"], education.graduation_year={min:null,max:2016}, education.mode=\"boost\".\n- Use education.degrees with mode=\"must\" for explicit PhD candidate, doctoral, postdoctoral, post-grad, or graduate researcher requirements (explicit academic-level requirements are the exception to the education.mode=\"boost\" default). For niche expertise like web crawling, web scraping infrastructure, distributed crawling systems, large-scale data extraction, or crawler infrastructure, keep the exact expertise phrases in additional_context_keywords_core/supporting and additional_context, and do not make academic status labels mandatory current job-title filters.\n- Use languages for explicit spoken/written language requirements, not profile keywords. Decide the language relationship from the whole request in any language: languages.match:\"all\" requires EVERY languages.include entry; \"any\" (the default) accepts ANY entry. languages.mode:\"must\" makes that relationship mandatory; it does not change any into all. Mandatory German AND English fluency therefore uses include:[\"German\",\"English\"], match:\"all\", proficiency:[\"Full professional proficiency\",\"Native or bilingual proficiency\"], mode:\"must\". Required fluency accepts full professional or native/bilingual evidence; limited working, elementary, and missing proficiency do not prove fluency. For professional working proficiency or better, also include \"Professional working proficiency\". Proficiency values are alternatives and apply within EACH required language record, never across unrelated language records. Only require proficiency when the user requires a level; a language listing alone is otherwise sufficient. Preserve either-language alternatives as match:\"any\". A preferred language is mode:\"boost\"; a negated language restriction (\"do not filter by language\") omits the filter. Never infer spoken languages from nationality, residence, profile prose language, or employer. When presenting language eligibility, request languages_detailed and report the profile-listed language/level evidence without upgrading it to independently verified fluency. If different required levels per language or localized indexed labels cannot be represented faithfully, disclose the unsupported scope instead of silently treating it as verified.\n- Use recommendations for explicit LinkedIn recommendation requirements (for example \"has recommendations\" -> recommendations.any=true; \"recommended for leadership\" -> recommendations.mentioned=\"leadership\").\n- If the user explicitly asks for no current role/no current employer/no new role yet/\"end date on most recent role\", set has_current_experience=false. This approximates \"most recent role ended\" by excluding active/current experience rows; profile freshness and experience-date coverage are imperfect.\n- Do not use has_current_experience=false for generic \"open to work\" alone unless the user agrees they want that hard refinement; open-to-work text is usually sparse profile evidence, not a reliable structured field.\n- If the user says \"at least N years/months in current role OR not currently working/no current role\", set current_role_tenure_months.min to the converted month count and current_role_tenure_months.include_no_current_experience=true. Do not also set has_current_experience=false for that OR shape.\n- For dated title/company history, use experience_clauses[].overlap_within_years. Example: \"had a founder title in the last five years but is not currently a founder\" -> job_titles.include/exclude Founder + Co-Founder with current_only=false and exclude_current_only=true, plus experience_clauses:[{titles:[\"Founder\",\"Co-Founder\"], companies:[], current_only:false, overlap_within_years:5}].\n\nCURRENT-ROLE RECENCY (current_role_started_within_days):\n- Use this filter when the user wants people who STARTED their current role recently with a *specific* day/week window.\n- Examples → output:\n  - \"started a new job in the last 2 days\" → current_role_started_within_days: 2\n  - \"joined a new company this week\" → current_role_started_within_days: 7\n  - \"first-degree connections whose current role started in the past week\" → current_role_started_within_days: 7\n  - \"people who started a new role in the last 30 days\" → current_role_started_within_days: 30\n- Distinguish from current_role_tenure_months: use current_role_started_within_days for SHORT day-scale windows (≤90 days). Use current_role_tenure_months for month/year-scale tenure ranges.\n- Range: integer 1..365. If unspecified but the user clearly wants very recent (\"just started\", \"this week\"), default to 7.\n- Coverage caveat: profile coverage on the underlying start_date field is partial. If applied alone the result count may be low — that's correct behavior (precision over recall), not a bug.",
    "schema_metadata": {
      "connection_degrees": {
        "type": "enum_array",
        "enum": [
          "1st",
          "2nd"
        ],
        "default": [],
        "description": "Network connection proximity. Searchable values are 1st and 2nd only. A non-empty authored list defaults to hard membership when network_filter_mode is omitted. Omit or pass an empty array for the full people pool; use network_filter_mode=\"boost\" explicitly to prefer reachable people without restricting eligibility."
      },
      "exclude_connection_degrees": {
        "type": "enum_array",
        "enum": [
          "1st",
          "2nd"
        ],
        "default": [],
        "description": "Network connection proximity to exclude. Use [\"1st\"] for requests like \"exclude first-degree LinkedIn connections\"; only 1st/2nd are backed by searchable network bitmaps."
      },
      "group_ids": {
        "type": "string_array",
        "format": "uuid",
        "default": [],
        "description": "Server-issued network-group UUIDs that define a hard membership lane. The selected group pools are OR-ed with any explicitly selected viewer 1st/2nd-degree hard network lane; group_ids alone is a groups-only search. Leave empty for ordinary/global search, including an unqualified request made inside a group chat. Only choose IDs supplied in trusted group context; never invent, infer, or truncate them."
      },
      "job_titles": {
        "type": "object",
        "description": "Job titles to include/exclude and matching behavior.",
        "properties": {
          "include": {
            "type": "string_array",
            "description": "Job titles to search for."
          },
          "exclude": {
            "type": "string_array",
            "description": "Job titles to exclude."
          },
          "mode": {
            "type": "enum",
            "enum": [
              "must"
            ],
            "default": "must",
            "description": "Job-title inclusion is always hard eligibility. Use include to broaden the accepted title family and match_scope to control lexical breadth; title filters never act as ranking-only boosts."
          },
          "exact": {
            "type": "boolean",
            "default": false,
            "description": "Require exact title match."
          },
          "current_only": {
            "type": "boolean",
            "default": false,
            "description": "If true, only match current roles for included title filters; if false, match title history."
          },
          "exclude_current_only": {
            "type": "boolean",
            "default": false,
            "description": "If true, exclude only people whose current role matches excluded titles. If false, exclude matches anywhere in career history; use false for \"never held X\" and first-time promotion requirements. Use true with current_only:false for \"previously X, not currently X\" searches."
          },
          "match_scope": {
            "type": "enum",
            "enum": [
              "broad",
              "anchored_prefix",
              "exact"
            ],
            "default": "broad",
            "description": "Job-title breadth. broad permits contained/semantic and adjacent roles; anchored_prefix starts at the beginning and is safest for required current roles; exact matches only the normalized title."
          }
        }
      },
      "hiring": {
        "type": "object",
        "description": "Boost or filter people who work at companies hiring for specific roles (based on ingested job postings).",
        "properties": {
          "mode": {
            "type": "enum",
            "enum": [
              "boost",
              "must"
            ],
            "default": "boost",
            "description": "Whether hiring matches are used for boosting (boost) or required (must)."
          },
          "job_titles": {
            "type": "string_array",
            "description": "Job titles the company should be hiring for."
          },
          "locations": {
            "type": "string_array",
            "description": "Job location hints (text match against job postings)."
          },
          "accepts_remote": {
            "type": "boolean",
            "nullable": true,
            "description": "If true, prefer remote job postings; if false, prefer onsite postings; null = any."
          },
          "published_within_days": {
            "type": "number",
            "nullable": true,
            "description": "Require job postings published within the last N days."
          },
          "published_after": {
            "type": "string",
            "nullable": true,
            "description": "Require job postings published on or after this ISO-8601 date or timestamp."
          },
          "published_before": {
            "type": "string",
            "nullable": true,
            "description": "Require job postings published on or before this ISO-8601 date or timestamp."
          }
        }
      },
      "locations": {
        "type": "object",
        "description": "Location includes/excludes and radius.",
        "properties": {
          "include": {
            "type": "string_array",
            "description": "Locations to include. Preserve every user-named geographic area. Canonical translations of the same place are valid, but a historical or ambiguous region must retain its authored label; never silently replace it with a larger administrative state or a neighboring region. For example, Westphalia is not the whole of North Rhine-Westphalia, and Rhineland is not Rhineland-Palatinate. If the available resolver cannot establish the requested area faithfully, disclose the coverage limitation instead of claiming exact geography or broadening it."
          },
          "exclude": {
            "type": "string_array",
            "description": "Locations to exclude."
          },
          "radius_miles": {
            "type": "number",
            "default": 50,
            "description": "Search radius in miles (for geo-aware locations)."
          },
          "strict": {
            "type": "boolean",
            "default": false,
            "description": "If true, only match within the specified locations."
          },
          "scope": {
            "type": "enum",
            "enum": [
              "current",
              "any_experience"
            ],
            "default": "current",
            "description": "Whether to match current location or any historical experience location."
          }
        }
      },
      "timezones": {
        "type": "object",
        "description": "Timezone proximity filter (UTC offset-based).",
        "properties": {
          "timezone": {
            "type": "string",
            "nullable": true,
            "description": "IANA timezone ID (e.g., \"America/Los_Angeles\"). Use only for explicit timezone intent, not bare place names such as Alaska or Hawaii."
          },
          "within_hours": {
            "type": "number",
            "nullable": true,
            "description": "Match profiles within N hours of the target timezone (1-11). Use null for any timezone."
          }
        }
      },
      "companies": {
        "type": "object",
        "description": "Companies to include/exclude and current-vs-history scope.",
        "properties": {
          "include": {
            "type": "string_array",
            "description": "Companies to search within."
          },
          "exclude": {
            "type": "string_array",
            "description": "Companies to exclude."
          },
          "include_current_only": {
            "type": "boolean",
            "default": false,
            "description": "If true, only match current companies for includes."
          },
          "exclude_current_only": {
            "type": "boolean",
            "default": false,
            "description": "If true, only match current companies for excludes."
          },
          "include_company_search_id": {
            "type": "string",
            "nullable": true,
            "description": "Optional company search_id to include all companies from a saved company search."
          },
          "include_company_search_boost_id": {
            "type": "string",
            "nullable": true,
            "description": "Optional company search_id to softly boost all companies from a saved company search."
          },
          "include_clauses": {
            "type": "array",
            "description": "Additional company experience clauses for mixed historical/current employer queries. mode=\"filter\" makes the clause required; mode=\"boost\" only ranks matching profiles.",
            "items": {
              "type": "object",
              "properties": {
                "include": {
                  "type": "string_array",
                  "description": "Companies to include for this clause."
                },
                "include_current_only": {
                  "type": "boolean",
                  "default": false,
                  "description": "If true, only match current companies for this clause."
                },
                "mode": {
                  "type": "enum",
                  "enum": [
                    "filter",
                    "boost"
                  ],
                  "default": "filter",
                  "description": "Whether this direct employer-name clause is required eligibility or ranking-only."
                },
                "include_company_search_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Optional company search_id to include all companies from a saved company search for this clause."
                },
                "include_company_search_boost_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Optional company search_id to softly boost companies from a saved company search for this clause."
                },
                "company_query": {
                  "type": "string",
                  "nullable": true,
                  "description": "Human-readable descriptor text that produced the saved company search binding for this clause."
                }
              }
            }
          },
          "exclude_company_search_id": {
            "type": "string",
            "nullable": true,
            "description": "Optional company search_id to exclude all companies from a saved company search."
          },
          "company_query": {
            "type": "string",
            "nullable": true,
            "description": "Short audit label for a bound company criterion. This field alone does not run a company sub-search or filter people; bind a completed company_search via one of the search-id fields instead."
          }
        }
      },
      "experience_clauses": {
        "type": "array",
        "description": "Composite experience clauses that bind titles, companies, and evidence keywords to the same experience row. within_recent_roles adds an exact service-layer check over the person's most recent N roles after Elasticsearch recall filtering. role_position=\"immediate_predecessor\" instead targets the canonical role immediately before the selected current role. For absolute historical employment, keep title, company, and as_of_date in this same row-bound clause. as_of_date is month-resolution reconstruction from the latest profile history, not a historical snapshot.",
        "items": {
          "type": "object",
          "properties": {
            "titles": {
              "type": "string_array",
              "description": "Titles to match within the same experience row."
            },
            "companies": {
              "type": "string_array",
              "description": "Required employer membership on this same experience row. Hard former-employer or pedigree cohorts described as \"came from\", \"previously at\", or \"after leaving\" are represented here."
            },
            "keywords": {
              "type": "string_array",
              "description": "Evidence phrases that must occur in the same experience row's description, industry, or company name. Use for role-scoped buyer/domain evidence, not loose profile keywords."
            },
            "employer_evidence_companies": {
              "type": "string_array",
              "description": "Named employers that independently prove the role-scoped evidence requirement. Resolved to canonical company identity and OR-ed with keywords; never matched as substrings in employer names or role text. This is alternative role-scoped evidence, not hard required employer membership. Required \"came from\", \"previously at\", or \"after leaving\" cohorts belong in companies on the same experience clause."
            },
            "employer_evidence_company_ids": {
              "type": "string_array",
              "description": "Canonical employer IDs for the identity evidence lane. These are execution IDs, not text keywords, and are OR-ed with same-row keyword evidence."
            },
            "keyword_match_mode": {
              "type": "enum",
              "enum": [
                "any",
                "all"
              ],
              "default": "any",
              "description": "Whether any evidence keyword or every evidence keyword must match the row."
            },
            "minimum_keyword_matches": {
              "type": "number",
              "nullable": true,
              "description": "Minimum evidence-keyword matches on the row. Defaults to 1 for any and all keywords for all."
            },
            "current_only": {
              "type": "boolean",
              "default": false,
              "description": "If true, only match current roles for this clause."
            },
            "title_exact": {
              "type": "boolean",
              "default": false,
              "description": "Require exact title matching for this clause."
            },
            "title_match_scope": {
              "type": "enum",
              "enum": [
                "broad",
                "anchored_prefix",
                "exact"
              ],
              "default": "broad",
              "description": "How strictly title matching should anchor to the requested title."
            },
            "as_of_date": {
              "type": "string",
              "nullable": true,
              "description": "Absolute historical employment month. Accept YYYY-MM or YYYY-MM-DD and normalize to YYYY-MM. The same experience row must contain the month inclusively. Omit current_only:true: this is not current employment or a historical profile snapshot."
            },
            "overlap_within_years": {
              "type": "number",
              "nullable": true,
              "description": "Require a current role or one overlapping the last N years. This is a non-adjacent time-window constraint: intervening jobs remain eligible, unlike role_position. Prefer this whenever the user bounds prior employment by TIME rather than by role count — \"came from a notable tech company\", \"was at a big platform in the last couple of years\", \"recently left a top AI lab\". Retrieval enforces this directly on the experience dates, so it neither over-fetches candidates nor removes rows after the query has run."
            },
            "within_recent_roles": {
              "type": "number",
              "nullable": true,
              "description": "Require the same-row title/company/keyword evidence to occur within the most recent N roles. For \"current role or either of the last two roles\", use 3. Do not combine with role_position. Use this ONLY when the user genuinely constrains by role COUNT or adjacency (\"their last two roles\", \"the job right before this one\"). Retrieval cannot rank the roles on a profile, so an ordinal bound is verified after the fact over a much larger candidate window; if the user expressed a time window instead, use overlap_within_years or as_of_date, which retrieval can enforce on its own. Someone who spent a few months elsewhere in between still satisfies a time-bounded requirement, and usually still satisfies the user."
            },
            "role_position": {
              "type": "enum",
              "enum": [
                "immediate_predecessor"
              ],
              "nullable": true,
              "description": "Require this clause on the canonical role immediately before the selected current role. This is exact job adjacency; unlike overlap_within_years, intervening jobs do not qualify. Concurrent current roles do not qualify. Do not combine with within_recent_roles. Like within_recent_roles this is an ordinal that retrieval cannot enforce, so it is checked after the fact over a much larger candidate window. Reserve it for wording that is genuinely about adjacency — \"left Google to start it\", \"the job right before this one\". A prior-employer requirement bounded by TIME (\"came from a notable tech company\", \"was at a big platform beforehand\") is NOT adjacency: use overlap_within_years, which retrieval enforces on the experience dates. Someone who did something else briefly in between still came from that company."
            }
          }
        }
      },
      "title_company_size_conditions": {
        "type": "array",
        "description": "Title-conditional employer-headcount implications. Use when an employer-size restriction applies only to a subset of otherwise accepted titles, for example \"CMOs only at employers with 200 or fewer employees.\" Candidates without a matching title are unaffected; candidates with a matching title must satisfy the headcount condition on that same experience row. Do not turn this into top-level company_size or company_search, which would incorrectly apply the size restriction to every accepted title.",
        "default": [],
        "items": {
          "type": "object",
          "properties": {
            "titles": {
              "type": "string_array",
              "description": "Titles triggering the size condition."
            },
            "current_only": {
              "type": "boolean",
              "default": true,
              "description": "True (default): current matching roles only."
            },
            "title_exact": {
              "type": "boolean",
              "default": false,
              "description": "Require exact triggering titles."
            },
            "title_match_scope": {
              "type": "enum",
              "enum": [
                "broad",
                "anchored_prefix",
                "exact"
              ],
              "default": "broad",
              "description": "Trigger-title matching scope."
            },
            "company_size": {
              "type": "object",
              "description": "Inclusive headcount on EVERY matching-title role, including concurrent roles; other titles are unaffected.",
              "properties": {
                "min": {
                  "type": "number",
                  "nullable": true,
                  "description": "Inclusive minimum headcount."
                },
                "max": {
                  "type": "number",
                  "nullable": true,
                  "description": "Inclusive maximum headcount."
                },
                "include_unknown": {
                  "type": "boolean",
                  "default": true,
                  "description": "True permits unknowns; false requires canonical numeric proof, never inferred/overlapping bands, for explicit verified/known prerequisites or only/unless rules."
                }
              }
            }
          }
        }
      },
      "industries": {
        "type": "string_array",
        "description": "Industry sectors (canonicalized using the taxonomy service).",
        "default": []
      },
      "years_experience": {
        "type": "object",
        "description": "Total years of professional experience.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum years of experience."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum years of experience."
          }
        }
      },
      "connections_count": {
        "type": "object",
        "description": "LinkedIn/CoreSignal connections count range.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum connections count."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum connections count."
          }
        }
      },
      "followers_count": {
        "type": "object",
        "description": "LinkedIn/CoreSignal followers count range.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum followers count."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum followers count."
          }
        }
      },
      "education": {
        "type": "object",
        "description": "Education filters over schools, degrees, fields of study, and graduation year.",
        "properties": {
          "schools": {
            "type": "string_array",
            "description": "Schools or universities to match."
          },
          "degrees": {
            "type": "string_array",
            "description": "Degree names or abbreviations, e.g. BS, MBA, PhD."
          },
          "fields_of_study": {
            "type": "string_array",
            "description": "Majors or fields of study, e.g. Computer Science, Math."
          },
          "graduation_year": {
            "type": "object",
            "description": "Graduation/end year range.",
            "properties": {
              "min": {
                "type": "number",
                "nullable": true,
                "description": "Earliest graduation year."
              },
              "max": {
                "type": "number",
                "nullable": true,
                "description": "Latest graduation year."
              }
            }
          },
          "mode": {
            "type": "enum",
            "enum": [
              "must",
              "boost"
            ],
            "default": "must",
            "description": "Whether education matches are required (must) or used for boosting."
          }
        }
      },
      "languages": {
        "type": "object",
        "description": "Profile-listed languages.",
        "properties": {
          "include": {
            "type": "string_array",
            "description": "Language names."
          },
          "match": {
            "type": "enum",
            "enum": [
              "any",
              "all"
            ],
            "description": "any(default)=ANY; all=EVERY; independent of must/boost."
          },
          "proficiency": {
            "type": "string_array",
            "description": "Levels OR within EACH language record; missing fails. Fluency: Full professional proficiency OR Native or bilingual proficiency."
          },
          "mode": {
            "type": "enum",
            "enum": [
              "must",
              "boost"
            ],
            "default": "must",
            "description": "must=required; boost=ranking."
          }
        }
      },
      "recommendations": {
        "type": "object",
        "description": "LinkedIn recommendation filters.",
        "properties": {
          "any": {
            "type": "boolean",
            "default": false,
            "description": "If true, match profiles with at least one recommendation."
          },
          "mentioned": {
            "type": "string",
            "description": "Keyword or phrase list to search within recommendation text."
          },
          "recommenders": {
            "type": "string_array",
            "description": "Names of recommenders/referees to match."
          },
          "mode": {
            "type": "enum",
            "enum": [
              "must",
              "boost"
            ],
            "default": "must",
            "description": "Whether recommendation matches are required (must) or used for boosting."
          }
        }
      },
      "average_role_tenure_months": {
        "type": "object",
        "description": "Average tenure per role (months). Current role is included only when it exceeds prior-role average.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum average months per role."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum average months per role."
          }
        }
      },
      "current_role_tenure_months": {
        "type": "object",
        "description": "Tenure in current role (months).",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum months in current role."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum months in current role."
          },
          "include_no_current_experience": {
            "type": "boolean",
            "default": false,
            "description": "Include people with no current role as an OR branch for current-role tenure constraints."
          }
        }
      },
      "current_role_started_within_days": {
        "type": "number",
        "nullable": true,
        "description": "Hard current-role-start eligibility — match people whose CURRENT role started within the last N days. Use for \"started a new job in the last week / past 2 days / recently\" queries. Coverage on the underlying experience start_date is partial; null values do not match, so this favors precision over recall."
      },
      "linkedin_connected_within_days": {
        "type": "number",
        "nullable": true,
        "description": "Viewer-scoped LinkedIn first-degree connection recency — match people the viewer connected with on LinkedIn within the last N days. Use for \"new LinkedIn connections\", \"recently added connections\", or daily connection-change scans. Pair with connection_degrees:[\"1st\"] and network_filter_mode:\"filter\"; this is connection date, not job-change date."
      },
      "linkedin_connected_after": {
        "type": "string",
        "nullable": true,
        "description": "Inclusive ISO date/datetime lower bound for the viewer->person LinkedIn connection date. Use for ranged first-degree network map requests such as connections added since 2026-05-01."
      },
      "linkedin_connected_before": {
        "type": "string",
        "nullable": true,
        "description": "Inclusive ISO date/datetime upper bound for the viewer->person LinkedIn connection date. Use with linkedin_connected_after for connection-date ranges."
      },
      "has_current_experience": {
        "type": "boolean",
        "nullable": true,
        "default": null,
        "description": "If false, match profiles with no active/current experience row and at least one ended experience; use for \"no current role\", \"no new role yet\", \"between jobs\", or \"most recent role has an end date\" queries. If true, require at least one active/current experience. Coverage depends on profile experience freshness."
      },
      "sort_by": {
        "anyOf": [
          {
            "type": "string",
            "enum": [
              "best_match",
              "last_name",
              "connected_date",
              "followers_count",
              "connections_count",
              "years_experience_months",
              "current_role_tenure_months",
              "average_role_tenure_months",
              "last_posted_at",
              "company_size",
              "company_revenue"
            ]
          },
          {
            "type": "null"
          }
        ],
        "description": "Result-ranking dimension for comparative/superlative wording only; null when no ranking is requested."
      },
      "sort_order": {
        "anyOf": [
          {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ]
          },
          {
            "type": "null"
          }
        ],
        "description": "Direction for sort_by; null when sort_by is null."
      },
      "company_size": {
        "type": "object",
        "description": "Current/historical employer headcount range. Profile-index counts and bands provide candidate hints; include_unknown:false requires final canonical numeric verification. A current range beside hard current job_titles binds to that same matching role, never to a different concurrent job. Use this for \"people at sub-200-employee companies\", \"candidates at companies with 11-50 employees\", and similar headcount-bounded sourcing. By default profiles whose employer headcount is UNKNOWN are still included (ranked below known-in-range matches) because small/boutique employers frequently lack published headcount; set include_unknown:false to require a verified in-range headcount. Preferred size is a company ranking boost, not a hard company_size filter.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Inclusive minimum headcount."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Inclusive maximum headcount."
          },
          "current_only": {
            "type": "boolean",
            "default": true,
            "description": "True (default): current employer; false: current or historical employer."
          },
          "include_unknown": {
            "type": "boolean",
            "default": true,
            "description": "True keeps unknowns below verified matches and discloses missing size evidence; false requires explicit verified/known/published counts, not merely a range; known numeric failures never pass."
          }
        }
      },
      "company_revenue": {
        "type": "object",
        "description": "Person-side fast filter on current/historical employer revenue (USD). Reads denormalized company_revenue_{current,all} arrays on every profile, so no company-id resolution step is needed. Use this for \"people at $10M-$100M revenue companies\" and similar revenue-bounded sourcing. Profiles whose employer has no revenue data are filtered out.",
        "properties": {
          "min": {
            "type": "number",
            "nullable": true,
            "description": "Minimum revenue in USD (inclusive)."
          },
          "max": {
            "type": "number",
            "nullable": true,
            "description": "Maximum revenue in USD (inclusive)."
          },
          "current_only": {
            "type": "boolean",
            "default": true,
            "description": "If true (default), the revenue range is enforced against the profile's CURRENT employer only. Set to false to also match any historical employer."
          }
        }
      },
      "posts": {
        "type": "object",
        "description": "Structured filters over LinkedIn posts and engagement activity, including text, action type, engagement thresholds, date windows, and target entities.",
        "properties": {
          "mode": {
            "type": "enum",
            "enum": [
              "boost",
              "must"
            ],
            "default": "boost",
            "description": "Whether post matches are required (must) or used for boosting."
          },
          "any": {
            "type": "boolean",
            "default": false,
            "description": "If true, match any recent posting activity."
          },
          "mentioned": {
            "type": "string",
            "description": "Hard/literal keyword or phrase list to search for within post content. Use for \"posts mentioning X\" / \"posts containing X\"; use post additional_context keyword fields for softer topic intent."
          },
          "author_entity_types": {
            "type": "string_array",
            "description": "Restrict authored activity to person accounts, official company accounts, or both. A person-authorship relation always uses [\"person\"]."
          },
          "keyword_match_mode": {
            "type": "enum",
            "enum": [
              "soft",
              "hard"
            ],
            "default": "soft",
            "description": "Whether post keyword fields are treated as soft expanded topic evidence or hard literal mention intent."
          },
          "additional_context_keywords": {
            "type": "string_array",
            "description": "General post-topic keyword hints. Prefer core/supporting when splitting high-signal vs recall-broadening terms."
          },
          "additional_context_keywords_core": {
            "type": "string_array",
            "description": "Core post-topic keyword hints that should strongly influence matching, similar to top-level additional_context_keywords_core."
          },
          "additional_context_keywords_supporting": {
            "type": "string_array",
            "description": "Supporting post-topic keyword hints that broaden recall without being mandatory exact phrases."
          },
          "action_types": {
            "type": "string_array",
            "description": "Activity types to require, such as post, repost, comment, like, or reaction. Use this with date and target filters for structured activity searches."
          },
          "min_reactions": {
            "type": "number",
            "nullable": true,
            "description": "Minimum reaction/like count on the matching post or activity."
          },
          "min_comments": {
            "type": "number",
            "nullable": true,
            "description": "Minimum comment count on the matching post or activity."
          },
          "min_engagement": {
            "type": "number",
            "nullable": true,
            "description": "Minimum total engagement count on the matching post or activity."
          },
          "published_within_days": {
            "type": "number",
            "nullable": true,
            "description": "Require matching activity observed or published within the last N days."
          },
          "published_after": {
            "type": "string",
            "nullable": true,
            "description": "Inclusive ISO date/datetime lower bound for matching activity."
          },
          "published_before": {
            "type": "string",
            "nullable": true,
            "description": "Inclusive ISO date/datetime upper bound for matching activity."
          },
          "authors": {
            "type": "string_array",
            "description": "Root authors whose own posts should match (names or LinkedIn profile URLs)."
          },
          "target_companies": {
            "type": "string_array",
            "description": "Companies whose posts or mentions the person acted on."
          },
          "target_people": {
            "type": "string_array",
            "description": "People whose posts or mentions the person acted on."
          },
          "target_urls": {
            "type": "string_array",
            "description": "Post, profile, or company URLs targeted by the matching activity."
          }
        }
      },
      "network_filter_mode": {
        "type": "enum",
        "enum": [
          "boost",
          "filter",
          "ignore",
          "connected_to"
        ],
        "default": "boost",
        "description": "Whether the viewer’s relationships rank or restrict the search. Omission defaults to \"filter\" beside a non-empty authored connection_degrees list, and otherwise to \"boost\". \"boost\" ranks relationship-relevant rows higher without removing anyone. \"filter\": the request makes the network an explicit requirement (\"only in my network\", \"must be first-degree\") — eligibility. \"ignore\": explicit opt-out. \"connected_to\": scope to a named third party’s network."
      },
      "connected_to": {
        "type": "string_array",
        "personRef": true,
        "docsType": "(string | {name, company?, location?, linkedin_url?})[] (user id, LinkedIn profile URL, vanity, name, or name-plus-context object)",
        "description": "People whose 1st-degree network should be searched when network_filter_mode=connected_to. Each entry may be a Super Carl profile id (UUID), a LinkedIn profile URL (\"https://www.linkedin.com/in/<vanity>\", any locale/subdomain variant, or a bare \"/in/<vanity>\" path), a LinkedIn vanity slug, a literal person name, or an object {name, company?, location?, linkedin_url?} — give the company/location you know when several people share the name, and never embed a qualifier in the name string itself (\"Jaime Bott (Peak XV)\" is rejected; {\"name\": \"Jaime Bott\", \"company\": \"Peak XV\"} binds). No client-side URL-to-id lookup is required. The server resolves non-id references and returns entity_resolution_required when a name matches several people; a LinkedIn URL that matches no indexed profile is reported as unresolved rather than silently ignored.",
        "default": []
      },
      "exclude_connected_to": {
        "type": "string_array",
        "personRef": true,
        "docsType": "(string | {name, company?, location?, linkedin_url?})[] (user id, LinkedIn profile URL, vanity, name, or name-plus-context object)",
        "description": "People whose 1st-degree network should be excluded. Use for third-person negative connection-owner requests like \"not connected to John Doe\"; this does not change network_filter_mode. Accepts the same person references as connected_to: profile id (UUID), LinkedIn profile URL or \"/in/<vanity>\" path, vanity slug, literal name, or {name, company?, location?, linkedin_url?} object — the server resolves non-id references, using the object's company/location to pick between namesakes.",
        "default": []
      },
      "personas": {
        "type": "object",
        "description": "Persona anchors for similarity-based boosting/downranking and shared-employer filtering. Each entry may be a Super Carl profile id (UUID), a LinkedIn profile URL (\"https://www.linkedin.com/in/<vanity>\", any locale/subdomain variant, or a bare \"/in/<vanity>\" path), a LinkedIn vanity slug, a literal person name, or an object {name, company?, location?, linkedin_url?} — give the company/location you know when several people share the name, and never embed a qualifier in the name string itself (\"Jaime Bott (Peak XV)\" is rejected; {\"name\": \"Jaime Bott\", \"company\": \"Peak XV\"} binds). No client-side URL-to-id lookup is required. The server resolves non-id references and returns entity_resolution_required when a name matches several people; a LinkedIn URL that matches no indexed profile is reported as unresolved rather than silently ignored.",
        "properties": {
          "more_like": {
            "type": "string_array",
            "personRef": true,
            "docsType": "(string | {name, company?, location?, linkedin_url?})[] (user id, LinkedIn profile URL, vanity, name, or name-plus-context object)",
            "description": "People to use as positive similarity anchors. Accepts the same person references as connected_to: profile id (UUID), LinkedIn profile URL or \"/in/<vanity>\" path, vanity slug, literal name, or {name, company?, location?, linkedin_url?} object — the server resolves non-id references, using the object's company/location to pick between namesakes."
          },
          "less_like": {
            "type": "string_array",
            "personRef": true,
            "docsType": "(string | {name, company?, location?, linkedin_url?})[] (user id, LinkedIn profile URL, vanity, name, or name-plus-context object)",
            "description": "People to down-rank via similarity. Accepts the same person references as connected_to: profile id (UUID), LinkedIn profile URL or \"/in/<vanity>\" path, vanity slug, literal name, or {name, company?, location?, linkedin_url?} object — the server resolves non-id references, using the object's company/location to pick between namesakes."
          },
          "worked_with": {
            "type": "string_array",
            "personRef": true,
            "docsType": "(string | {name, company?, location?, linkedin_url?})[] (user id, LinkedIn profile URL, vanity, name, or name-plus-context object)",
            "description": "Anchor person(s) for reference/worked-with searches — REQUIRED for any worked-with cohort; worked_with_overlap_mode is invalid without it. Use the provided viewer_user_id for \"people I have worked with\". For a named third-person reference, pass a user ID, a LinkedIn profile URL, or a literal name such as \"Jaime Bott\"; the server resolves literal names. Entries AND together (the intersection of each person's worked-with cohort), so list ONLY the subject person(s) being asked about — never add the requesting viewer's own id beside a named subject (measured prod defect: worked_with=[viewer, subject] returns 0 or unstable rows); viewer-network preference is network_filter_mode=\"boost\", not a second worked_with entry. Set top-level worked_with_overlap_mode=\"date_verified\" when dated positive overlap is required; omit the mode for the default graded shared-employer cohort. Accepts the same person references as connected_to: profile id (UUID), LinkedIn profile URL or \"/in/<vanity>\" path, vanity slug, literal name, or {name, company?, location?, linkedin_url?} object — the server resolves non-id references, using the object's company/location to pick between namesakes."
          }
        },
        "default": {
          "more_like": [],
          "less_like": []
        }
      },
      "worked_with_overlap_mode": {
        "type": "enum",
        "enum": [
          "graded",
          "date_verified"
        ],
        "nullable": true,
        "default": null,
        "description": "Worked-with membership before pagination: graded (default) or date_verified (dated overlap only)."
      },
      "diversify_by_company": {
        "type": "boolean",
        "description": "If true, collapse results so each company appears at most once (where possible). Omit to use default heuristics."
      },
      "additional_context": {
        "type": "string",
        "description": "Free-form text describing nuance that does not map to structured filters.",
        "default": ""
      },
      "keyword_match_mode": {
        "type": "enum",
        "enum": [
          "soft",
          "hard"
        ],
        "default": "soft",
        "description": "Whether top-level profile keyword fields are soft ranking/context evidence or a hard profile-text eligibility filter. Use hard only when the user explicitly requires profiles to mention at least one of the keyword terms."
      },
      "additional_context_keywords": {
        "type": "string_array",
        "description": "Profile keyword hints used to expand or refine context matching.",
        "default": []
      },
      "additional_context_keywords_core": {
        "type": "string_array",
        "description": "Core profile keyword hints that should strongly influence matching.",
        "default": []
      },
      "additional_context_keywords_supporting": {
        "type": "string_array",
        "description": "Supporting keyword hints that broaden recall without being mandatory.",
        "default": []
      },
      "included_networks": {
        "type": "enum_array",
        "enum": [
          "super_carl",
          "linkedin",
          "gmail",
          "contacts",
          "x",
          "instagram"
        ],
        "description": "Networks to search (e.g., super_carl, linkedin, gmail, contacts, x, instagram).",
        "default": [
          "super_carl",
          "linkedin"
        ]
      },
      "reachable_via": {
        "type": "enum_array",
        "enum": [
          "super_carl",
          "linkedin",
          "gmail",
          "contacts",
          "x",
          "instagram"
        ],
        "description": "Require that results are ALREADY reachable through the selected channels — gmail means an email address is already stored for the person, true of ~0.009% of profiles. Needing contact details is not the same as having them: a request to find or supply an email address is an enrichment need against the returned rows, not an eligibility filter, and must leave this empty.",
        "default": []
      },
      "gmail_correspondence_direction": {
        "type": "enum",
        "enum": [
          "none",
          "sent",
          "received",
          "reciprocal",
          "any"
        ],
        "description": "Owner-scoped Gmail history: sent = the viewer sent at least one message, received = the viewer received at least one, reciprocal = both, any = either direction, none = no history constraint. This is correspondence history, not email reachability and not Gmail contact-graph membership.",
        "default": "none"
      },
      "instagram_direction": {
        "type": "enum",
        "enum": [
          "none",
          "following",
          "followers",
          "mutual",
          "any"
        ],
        "description": "Restrict to the viewer’s Instagram follow graph: \"following\" = people you follow, \"followers\" = people who follow you, \"mutual\" = both, \"any\" = connected either way (use when an IG connection is implied but direction is unspecified), \"none\" = no IG follow constraint (default). Composes with all other filters, e.g. founders you follow on IG.",
        "default": "none"
      },
      "x_direction": {
        "type": "enum",
        "enum": [
          "none",
          "following",
          "followers",
          "mutual",
          "any"
        ],
        "description": "Restrict to the viewer’s X (Twitter) follow graph: \"following\" = people you follow, \"followers\" = people who follow you, \"mutual\" = both, \"any\" = connected either way (use when an X connection is implied but direction is unspecified), \"none\" = no X follow constraint (default). Composes with all other filters, e.g. founders who follow you on X.",
        "default": "none"
      }
    },
    "json_schema": {
      "type": "object",
      "properties": {
        "connection_degrees": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "1st",
              "2nd"
            ]
          }
        },
        "exclude_connection_degrees": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "1st",
              "2nd"
            ]
          }
        },
        "group_ids": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "uuid"
          }
        },
        "job_titles": {
          "type": "object",
          "properties": {
            "include": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "exclude": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "mode": {
              "type": "string",
              "enum": [
                "must"
              ]
            },
            "exact": {
              "type": "boolean"
            },
            "current_only": {
              "type": "boolean"
            },
            "exclude_current_only": {
              "type": "boolean"
            },
            "match_scope": {
              "type": "string",
              "enum": [
                "broad",
                "anchored_prefix",
                "exact"
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "include",
            "exclude",
            "mode",
            "exact",
            "current_only",
            "exclude_current_only",
            "match_scope"
          ]
        },
        "hiring": {
          "type": "object",
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "boost",
                "must"
              ]
            },
            "job_titles": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "locations": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "accepts_remote": {
              "type": "boolean"
            },
            "published_within_days": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "published_after": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "published_before": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "mode",
            "job_titles",
            "locations",
            "accepts_remote",
            "published_within_days",
            "published_after",
            "published_before"
          ]
        },
        "locations": {
          "type": "object",
          "properties": {
            "include": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "exclude": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "radius_miles": {
              "type": "number"
            },
            "strict": {
              "type": "boolean"
            },
            "scope": {
              "type": "string",
              "enum": [
                "current",
                "any_experience"
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "include",
            "exclude",
            "radius_miles",
            "strict",
            "scope"
          ]
        },
        "timezones": {
          "type": "object",
          "properties": {
            "timezone": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "within_hours": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "timezone",
            "within_hours"
          ]
        },
        "companies": {
          "type": "object",
          "properties": {
            "include": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "exclude": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "include_current_only": {
              "type": "boolean"
            },
            "exclude_current_only": {
              "type": "boolean"
            },
            "include_company_search_id": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "include_company_search_boost_id": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "include_clauses": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "include": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "include_current_only": {
                    "type": "boolean"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "filter",
                      "boost"
                    ]
                  },
                  "include_company_search_id": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "include_company_search_boost_id": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "company_query": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "additionalProperties": false,
                "required": [
                  "include",
                  "include_current_only",
                  "mode",
                  "include_company_search_id",
                  "include_company_search_boost_id",
                  "company_query"
                ]
              }
            },
            "exclude_company_search_id": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "company_query": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "include",
            "exclude",
            "include_current_only",
            "exclude_current_only",
            "include_company_search_id",
            "include_company_search_boost_id",
            "include_clauses",
            "exclude_company_search_id",
            "company_query"
          ]
        },
        "experience_clauses": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "titles": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "companies": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "keywords": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "employer_evidence_companies": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "employer_evidence_company_ids": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "keyword_match_mode": {
                "type": "string",
                "enum": [
                  "any",
                  "all"
                ]
              },
              "minimum_keyword_matches": {
                "anyOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "current_only": {
                "type": "boolean"
              },
              "title_exact": {
                "type": "boolean"
              },
              "title_match_scope": {
                "type": "string",
                "enum": [
                  "broad",
                  "anchored_prefix",
                  "exact"
                ]
              },
              "as_of_date": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "overlap_within_years": {
                "anyOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "within_recent_roles": {
                "anyOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "role_position": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "immediate_predecessor"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "additionalProperties": false,
            "required": [
              "titles",
              "companies",
              "keywords",
              "employer_evidence_companies",
              "employer_evidence_company_ids",
              "keyword_match_mode",
              "minimum_keyword_matches",
              "current_only",
              "title_exact",
              "title_match_scope",
              "as_of_date",
              "overlap_within_years",
              "within_recent_roles",
              "role_position"
            ]
          }
        },
        "title_company_size_conditions": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "titles": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "current_only": {
                "type": "boolean"
              },
              "title_exact": {
                "type": "boolean"
              },
              "title_match_scope": {
                "type": "string",
                "enum": [
                  "broad",
                  "anchored_prefix",
                  "exact"
                ]
              },
              "company_size": {
                "type": "object",
                "properties": {
                  "min": {
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "max": {
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "include_unknown": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "min",
                  "max",
                  "include_unknown"
                ]
              }
            },
            "additionalProperties": false,
            "required": [
              "titles",
              "current_only",
              "title_exact",
              "title_match_scope",
              "company_size"
            ]
          }
        },
        "industries": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "years_experience": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max"
          ]
        },
        "connections_count": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max"
          ]
        },
        "followers_count": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max"
          ]
        },
        "education": {
          "type": "object",
          "properties": {
            "schools": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "degrees": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "fields_of_study": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "graduation_year": {
              "type": "object",
              "properties": {
                "min": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "max": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "additionalProperties": false,
              "required": [
                "min",
                "max"
              ]
            },
            "mode": {
              "type": "string",
              "enum": [
                "must",
                "boost"
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "schools",
            "degrees",
            "fields_of_study",
            "graduation_year",
            "mode"
          ]
        },
        "languages": {
          "type": "object",
          "properties": {
            "include": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "match": {
              "type": "string",
              "enum": [
                "any",
                "all"
              ]
            },
            "proficiency": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "mode": {
              "type": "string",
              "enum": [
                "must",
                "boost"
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "include",
            "match",
            "proficiency",
            "mode"
          ]
        },
        "recommendations": {
          "type": "object",
          "properties": {
            "any": {
              "type": "boolean"
            },
            "mentioned": {
              "type": "string"
            },
            "recommenders": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "mode": {
              "type": "string",
              "enum": [
                "must",
                "boost"
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "any",
            "mentioned",
            "recommenders",
            "mode"
          ]
        },
        "average_role_tenure_months": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max"
          ]
        },
        "current_role_tenure_months": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "include_no_current_experience": {
              "type": "boolean"
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max",
            "include_no_current_experience"
          ]
        },
        "current_role_started_within_days": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ]
        },
        "linkedin_connected_within_days": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ]
        },
        "linkedin_connected_after": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "linkedin_connected_before": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "has_current_experience": {
          "type": "boolean"
        },
        "sort_by": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "best_match",
                "last_name",
                "connected_date",
                "followers_count",
                "connections_count",
                "years_experience_months",
                "current_role_tenure_months",
                "average_role_tenure_months",
                "last_posted_at",
                "company_size",
                "company_revenue"
              ]
            },
            {
              "type": "null"
            }
          ],
          "description": "Result-ranking dimension for comparative/superlative wording only; null when no ranking is requested."
        },
        "sort_order": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            },
            {
              "type": "null"
            }
          ],
          "description": "Direction for sort_by; null when sort_by is null."
        },
        "company_size": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "current_only": {
              "type": "boolean"
            },
            "include_unknown": {
              "type": "boolean"
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max",
            "current_only",
            "include_unknown"
          ]
        },
        "company_revenue": {
          "type": "object",
          "properties": {
            "min": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "max": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "current_only": {
              "type": "boolean"
            }
          },
          "additionalProperties": false,
          "required": [
            "min",
            "max",
            "current_only"
          ]
        },
        "posts": {
          "type": "object",
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "boost",
                "must"
              ]
            },
            "any": {
              "type": "boolean"
            },
            "mentioned": {
              "type": "string"
            },
            "author_entity_types": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "keyword_match_mode": {
              "type": "string",
              "enum": [
                "soft",
                "hard"
              ]
            },
            "additional_context_keywords": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "additional_context_keywords_core": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "additional_context_keywords_supporting": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "action_types": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "min_reactions": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "min_comments": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "min_engagement": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "published_within_days": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "published_after": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "published_before": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "authors": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "target_companies": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "target_people": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "target_urls": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false,
          "required": [
            "mode",
            "any",
            "mentioned",
            "author_entity_types",
            "keyword_match_mode",
            "additional_context_keywords",
            "additional_context_keywords_core",
            "additional_context_keywords_supporting",
            "action_types",
            "min_reactions",
            "min_comments",
            "min_engagement",
            "published_within_days",
            "published_after",
            "published_before",
            "authors",
            "target_companies",
            "target_people",
            "target_urls"
          ]
        },
        "network_filter_mode": {
          "type": "string",
          "enum": [
            "boost",
            "filter",
            "ignore",
            "connected_to"
          ]
        },
        "connected_to": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  },
                  "linkedin_url": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              }
            ]
          }
        },
        "exclude_connected_to": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  },
                  "linkedin_url": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              }
            ]
          }
        },
        "personas": {
          "type": "object",
          "properties": {
            "more_like": {
              "type": "array",
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "company": {
                        "type": "string"
                      },
                      "location": {
                        "type": "string"
                      },
                      "linkedin_url": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                ]
              }
            },
            "less_like": {
              "type": "array",
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "company": {
                        "type": "string"
                      },
                      "location": {
                        "type": "string"
                      },
                      "linkedin_url": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                ]
              }
            },
            "worked_with": {
              "type": "array",
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "company": {
                        "type": "string"
                      },
                      "location": {
                        "type": "string"
                      },
                      "linkedin_url": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                ]
              }
            }
          },
          "additionalProperties": false,
          "required": [
            "more_like",
            "less_like",
            "worked_with"
          ]
        },
        "worked_with_overlap_mode": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "graded",
                "date_verified"
              ]
            },
            {
              "type": "null"
            }
          ]
        },
        "diversify_by_company": {
          "type": "boolean"
        },
        "additional_context": {
          "type": "string"
        },
        "keyword_match_mode": {
          "type": "string",
          "enum": [
            "soft",
            "hard"
          ]
        },
        "additional_context_keywords": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "additional_context_keywords_core": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "additional_context_keywords_supporting": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "included_networks": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "super_carl",
              "linkedin",
              "gmail",
              "contacts",
              "x",
              "instagram"
            ]
          }
        },
        "reachable_via": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "super_carl",
              "linkedin",
              "gmail",
              "contacts",
              "x",
              "instagram"
            ]
          }
        },
        "gmail_correspondence_direction": {
          "type": "string",
          "enum": [
            "none",
            "sent",
            "received",
            "reciprocal",
            "any"
          ]
        },
        "instagram_direction": {
          "type": "string",
          "enum": [
            "none",
            "following",
            "followers",
            "mutual",
            "any"
          ]
        },
        "x_direction": {
          "type": "string",
          "enum": [
            "none",
            "following",
            "followers",
            "mutual",
            "any"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "connection_degrees",
        "exclude_connection_degrees",
        "group_ids",
        "job_titles",
        "hiring",
        "locations",
        "timezones",
        "companies",
        "experience_clauses",
        "title_company_size_conditions",
        "industries",
        "years_experience",
        "connections_count",
        "followers_count",
        "education",
        "languages",
        "recommendations",
        "average_role_tenure_months",
        "current_role_tenure_months",
        "current_role_started_within_days",
        "linkedin_connected_within_days",
        "linkedin_connected_after",
        "linkedin_connected_before",
        "has_current_experience",
        "sort_by",
        "sort_order",
        "company_size",
        "company_revenue",
        "posts",
        "network_filter_mode",
        "connected_to",
        "exclude_connected_to",
        "personas",
        "worked_with_overlap_mode",
        "diversify_by_company",
        "additional_context",
        "keyword_match_mode",
        "additional_context_keywords",
        "additional_context_keywords_core",
        "additional_context_keywords_supporting",
        "included_networks",
        "reachable_via",
        "gmail_correspondence_direction",
        "instagram_direction",
        "x_direction"
      ]
    }
  }
}
