Skip to content

Application question taxonomy (technical)

Every question shape ATS forms (Workday, Greenhouse, Lever, iCIMS, UKG, and the rest) ask, grouped by category. Each entry maps to the QuestionType enum in ApplicationQuestion.cs, the IntakeProfile field that answers it, and — where relevant — the edge case that makes it tricky to automate. Resolution logic lives in AnswerResolver.cs.

Plain-language version: ../plain/application-question-taxonomy.md

Source of truth: the code. If this page and AnswerResolver.cs disagree, the code wins — fix the page (see the two-track docs rule in contributing.md).

How to read the tables

  • Profile field — the IntakeProfile (or IntakeProfile.Extended, see profile-data-gaps.md) member AnswerResolver reads.
  • Needed from user — the information any user must supply, once, for this question to ever resolve — independent of which specific ATS asks it.
  • Edge case — a behavior that breaks naive automation; see Edge cases below for the shared handling.

1. Identity / contact

Question QuestionType Profile field Needed from user
Legal first/last name LegalFirstName / LegalLastName Contact.LegalFirstName/LastName Name exactly as it appears on a government ID (some ATSes validate this against later background-check steps).
Preferred / goes-by name PreferredName Contact.PreferredName (falls back to legal first name) Optional nickname.
Email Email Contact.Email One address the user actually checks — this becomes the ATS account login.
Phone Phone Contact.Phone Best contact number, with country code if outside the US.
Mailing address Address Contact.Address Full street address — some forms split this into street/city/state/zip fields; WorkWingman stores it as one string and lets the automation engine split on fill.

2. Work authorization + sponsorship

Question QuestionType Profile field Needed from user
"Are you authorized to work in [country] without sponsorship?" AuthorizedToWorkInCountry Eligibility.AuthorizedToWorkUs A true yes/no — this is a knockout question (see below).
"Will you now or in the future require sponsorship?" RequiresSponsorshipNowOrFuture Eligibility.RequiresSponsorship A true yes/no — also a knockout question. Note the two questions are logically linked (rarely both "No, don't need it" + "Yes, will need it") but AnswerResolver treats them independently since ATSes phrase them independently.
Visa status / type held VisaStatus Derived from Eligibility.RequiresSponsorship Specific visa type (H-1B, TN, OPT, etc.) if sponsorship is relevant — not fully structured yet, see gaps doc.

3. Eligibility (age, clearance, non-compete)

Question QuestionType Profile field Needed from user
"Are you at least 18 years old?" IsAtLeast18 Extended.IsAtLeast18 A yes/no, collected once at onboarding rather than re-asked every application — knockout.
"Do you currently hold a security clearance?" SecurityClearanceHeld Derived from Extended.SecurityClearanceLevel / Eligibility.SecurityClearance Whether any clearance is held — knockout for cleared roles.
Clearance level SecurityClearanceLevel Extended.SecurityClearanceLevel Specific level (Public Trust, Secret, Top Secret, TS/SCI, polygraph type) and, ideally, expiration date (Extended.SecurityClearanceExpiresOn) since lapsed clearances often still count differently than active ones.
"Are you bound by a non-compete or non-solicit agreement?" BoundByNonCompete Extended.BoundByNonCompete + NonCompeteDetails Yes/no plus, if yes, which employer and expiration — knockout for close competitors.
"Have you previously been employed by [Company]?" PreviouslyEmployedByCompany Extended.PreviouslyEmployedByCompany Yes/no — affects rehire-eligibility routing, not usually a hard knockout.

4. EEO / demographics (always optional)

Question QuestionType Profile field Needed from user
Gender identity Gender Demographics.Gender Optional self-identification.
Race / ethnicity RaceEthnicity Demographics.RaceEthnicity Optional self-identification.
Veteran status VeteranStatus Demographics.VeteranStatus Optional — US federal contractors are required to ask (VEVRAA) but the candidate is never required to answer.
Disability status DisabilityStatus Demographics.DisabilityStatus Optional — same OFCCP self-ID framing as veteran status.

These are never treated as gaps. AnswerResolver.VoluntaryDemographic reports IsGap = false even when the field is unset, because "prefer not to answer" is the complete, correct answer for an EEO question WorkWingman never fabricates a response to. The value is applied exactly as the user set it, or left at the form's neutral default.

5. Education

Question QuestionType Profile field Needed from user
School / university School Education[latest].School At minimum, the highest/most recent credential.
Degree Degree Education[latest].Degree Degree type (BS, MS, MBA, etc.) — some ATSes want this as free text, others as a constrained dropdown WorkWingman must fuzzy-match.
Field of study FieldOfStudy Education[latest].FieldOfStudy Major/concentration.
Graduation year GraduationYear Education[latest].GraduationYear Year, or expected year if in progress.

AnswerResolver picks the entry with the highest GraduationYear when multiple degrees exist; a future iteration could ask per-question which degree a form wants (e.g. "highest" vs. "most relevant to role").

6. Work experience

Question QuestionType Profile field Needed from user
Employer name EmployerName WorkHistory[latest].Company Every employer for at least the ATS-required lookback window (commonly 7-10 years).
Job title JobTitle WorkHistory[latest].Title Title as held, not an aspirational title.
Start / end date EmploymentStartDate / EmploymentEndDate WorkHistory[latest].StartDate/EndDate Month + year is usually enough.
Reason for leaving ReasonForLeaving (gap — see profile-data-gaps.md) Short, consistent phrasing per employer so it doesn't contradict itself across applications.

AnswerResolver currently takes WorkHistory.FirstOrDefault() as "latest," matching how IntakeProfile.WorkHistory is populated (most-recent-first) elsewhere in the app.

7. Skills / certifications

Question QuestionType Profile field Needed from user
Skills list Skills TopSkills A curated top-skills list (joined with commas for free-text boxes; automation can also target multi-select skill pickers keyword-by-keyword).
Certification name CertificationName Extended.Certifications[latest].Name Certification title (AWS Certified Solutions Architect, PMP, etc.).
License / credential number LicenseNumber Extended.Certifications[latest].CredentialId The credential ID some ATSes verify against the issuer.

8. Screening / knockout questions

Question QuestionType Profile field Needed from user
"How many years of experience do you have with X?" YearsOfExperienceInSkill (gap) Per-skill years — not a single number, needs either a structured skills-with-years list or a per-question judgement call (mirrors WorkdayAutomationEngine's JudgementCall flow).
Custom yes/no screening question ScreeningYesNo (gap, flagged IsKnockout) No generic mapping exists — every job invents its own ("Can you lift 50 lbs?", "Do you have a car?"). Always surfaced as a judgement call.
Custom free-text screening question ScreeningFreeText (gap) Same — routed to Claude drafting or a judgement call, never guessed.

9. Salary, start date, relocation, work model

Question QuestionType Profile field Needed from user
Salary expectation SalaryExpectation Eligibility.SalaryExpectation A number or range the user is comfortable citing — see gaps doc for the "many states forbid asking salary history" nuance.
Salary history SalaryHistory Extended.SalaryHistory Prior compensation, only where legal to ask.
Earliest start date EarliestStartDate Eligibility.EarliestStartDate A date or "immediately" / "2 weeks notice."
Notice period NoticePeriod Extended.NoticePeriod How much notice the current employer is owed.
Willing to relocate WillingToRelocate Extended.WillingToRelocate (falls back to Eligibility.RelocationPreference free text) A clean yes/no/case-by-case, distinct from the free-text relocation preference already on the profile.
Work model preference WorkModelPreference Eligibility.WorkModelPreference Remote/hybrid/on-site preference.
Employment type preference EmploymentTypePreference Extended.EmploymentTypePreference W-2 vs. contract/1099 willingness.

10. Custom per-job questions

Question QuestionType Profile field Needed from user
"How did you hear about us?" HowDidYouHearAboutUs Extended.HowDidYouHearAboutUs A default source (e.g. "LinkedIn") reused unless the specific job warrants something else (e.g. a referral).
"Why do you want to work here?" WhyThisCompany (gap — drafted, not a static field) Per-company motivation is generated by the document/outreach drafters from the story profile, not read off a static field.
Any other custom free text CustomFreeText (gap) Routed to a judgement call or Claude drafting.

11. References

Question QuestionType Profile field Needed from user
Reference name/relationship/company/phone/email, slot N ReferenceName/ReferenceRelationship/ReferenceCompany/ReferencePhone/ReferenceEmail Extended.References[N-1] via ApplicationQuestion.RepeatIndex + ReferenceField 2-3 pre-cleared references (name, how they know the user, employer, phone, email).

See Edge cases → reference slots below.

12. Consents / acknowledgements

Question QuestionType Profile field Needed from user
Background-check consent BackgroundCheckConsent (never auto-filled) Explicit, in-the-moment affirmation.
Drug-test consent DrugTestConsent (never auto-filled) Same.
At-will employment acknowledgement AtWillAcknowledgement (never auto-filled) Same.
E-Verify acknowledgement EVerifyAcknowledgement (never auto-filled) Same.
EEO notice acknowledgement EqualOpportunityAcknowledgement (never auto-filled) Same.
"I certify the above is true and complete" InformationAccuracyCertification (never auto-filled) Same.

AnswerResolver deliberately returns a gap + RequiresUserConfirmation = true for every consent/acknowledgement question rather than auto-affirming a legal statement on the user's behalf — this mirrors AutomationSettings.AlwaysRequireReviewBeforeSubmit, which is locked on.

Edge cases

Yes/No → conditional "N/A" text box

Many forms show a hidden text box that reveals after a yes/no question — e.g. "Have you ever been convicted of a felony?" → "If yes, please explain." When the underlying yes/no answer makes the follow-up not applicable, the box still has to be filled with the literal string "N/A"; leaving it blank commonly fails client-side validation because the field is marked required regardless of the branch taken.

Modeled by ApplicationQuestion.Control = ControlKind.ConditionalTextAfterYesNo (or the IsConditionalOnYesNo flag), ConditionalTriggerValue (which yes/no answer makes the box relevant), and PrecedingYesNoAnswer (what the user/automation actually answered). AnswerResolver.ResolveConditionalText:

  • fills the literal string "N/A" (via AnswerResolver.NotApplicable) when PrecedingYesNoAnswer != ConditionalTriggerValue;
  • looks for real explanatory text (Extended.ConvictionDetails today; extend per use case) when the box is applicable;
  • never guesses when PrecedingYesNoAnswer is null — it returns a gap instead of risking either a wrongly-blank required field or a wrongly-dismissive "N/A" over real content that should have been disclosed.

Reference slots

Reference questions repeat in slots (Reference 1, Reference 2, …), each with several sub-fields. ApplicationQuestion.RepeatIndex (1-based) + ReferenceField locate the right entry in IntakeProfile.Extended.References. AnswerResolver.ResolveReferenceField:

  • fills whichever sub-field (name/relationship/company/phone/email) the slot asks for when a reference exists at that index;
  • handles gracefully — not an exception — when the user has no references on file yet, or when the form asks for more reference slots than the user has supplied. Both return a gap (IsGap = true, empty value, explanatory Reasoning) rather than fabricating a person.

Conditional reveals

Beyond the yes/no → N/A case, answering one question can unlock an entirely new required field (e.g. selecting "Other" in a dropdown reveals a "please specify" box, or answering "Yes" to "Do you have a clearance?" reveals the clearance-level dropdown). These are represented the same way as the N/A case — a follow-up ApplicationQuestion whose relevance depends on a preceding answer — but the content required differs (real text, not "N/A") depending on which branch was taken. The taxonomy handles the specific "yes/no → N/A" case generically in AnswerResolver because it's ubiquitous across ATSes; job-specific reveals (a custom dropdown revealing a custom box) fall through to ScreeningFreeText/CustomFreeText and a judgement call, matching how WorkdayAutomationEngine.TryFillFieldAsync already pauses on low-confidence fields.

Knockout questions

A knockout question is one where a "wrong" answer causes the ATS to auto-reject the application before any human reviews it — most commonly work authorization, sponsorship requirements, minimum age, and clearance/background prerequisites. ApplicationQuestion .IsKnockout (also implicitly true for AuthorizedToWorkInCountry, RequiresSponsorshipNowOrFuture, IsAtLeast18, SecurityClearanceHeld, BoundByNonCompete, DisclosableConviction, and every consent/acknowledgement type) forces ResolvedAnswer.RequiresUserConfirmation = true regardless of confidenceAnswerResolver will confidently fill "Yes"/"No" from the profile, but the caller (automation engine, or the manual-apply UI) must always surface it for an explicit nod before the application submits. This is the same pattern WorkdayAutomationEngine uses for low-confidence fields (JudgementCall), applied unconditionally to anything that can silently end the application.