PeopleOps Console — Lifecycle Resolution Skill
You answer HR lifecycle questions for a fictional company ("northwind-people"). Each task
names one entity (an employee EMP-###, a policy case CASE-*, or a recruitment opening
REQ-*) and asks you to determine its authoritative state and the correct next action,
then emit JSON that matches a provided answer_template.json. Answers use a fixed
normalized-label vocabulary (enums), not free text.
There is no local data. All facts live behind a remote HTTP API. Read it, apply the
business rules below, and fill every field in the template.
1. How to use the remote API
Base URL is given in environment_access.md (e.g. <remote-env-url>).
No auth. All responses are JSON. The q= filter is a case-insensitive substring match
over scalar fields, so q=EMP-118, q=CASE-RW-221, q=REQ-DA-77 are good lookups; omit
q to get the whole collection.
Endpoints and when to use them:
GET /api/manifest, GET /api/summary — orient: counts, modules, departments. Cheap sanity check.
GET /api/employees?q=EMP-### — profile summary (status, leave_balance_days, band, manager). Often stale — never trust it over an assignment record.
GET /api/payroll-ledgers?q=EMP-### — the single most important endpoint. Holds BOTH
leave-assignment rows (record_type: "Leave assignment" / "HRMS leave ledger" /
"People Ops adjustment") AND salary-assignment rows (record_type: "Salary assignment"),
each with a status of Approved/Submitted/Draft/Superseded. This is the authority for
leave policy, leave days, base salary, and accrual batch.
GET /api/policies and /api/policies/{id} — the written business rules (LEAVE-SRC-001,
PAY-SRC-001, POL-DOCS-2026, HR-POL-014). Read the section bodies; they literally state the
precedence/readiness rules used to grade.
GET /api/cases (summaries) then GET /api/cases/{case_id} for FULL detail — approvals,
attachments (folder checklist), comments, embedded audit_events, notice/notice refs, policy_refs.
GET /api/documents?q=... — folders with files, required_files, required_tags, tags, ready.
GET /api/messages?q=... — formal notices with quality and defects arrays.
GET /api/recruitment — openings with candidates, offer_register, cost_ledger,
notice_packets, payroll_precheck_records.
GET /api/audit?q=...&case_id=... and /api/audit/{id} — QA/control events. Detail strings
echo the exact normalized labels you must emit (e.g. "profile_summary_stale",
"ready_with_monitoring", "block close", "draft_excluded").
GET /api/notifications, GET /api/attachments/{id} — raw notification / notice body text.
Always cross-reference modules. An employee's true state is spread across employees +
payroll-ledgers + policies + cases + documents + messages + audit. Start from the named entity,
then pull every module that the answer template's fields reference.
2. Core business rules (transferable)
2.1 Leave source precedence (LEAVE-SRC-001)
"The latest approved or submitted leave assignment for the period controls. Draft, voided,
and obsolete (Superseded) records are excluded even when profile summaries conflict."
- Pick the controlling leave row from
payroll-ledgers for that employee/period:
prefer Approved, else Submitted. If both exist for the period, take the latest by
updated_at. Never pick a Draft or Superseded row, and never use the employee
profile's leave_balance_days as the source when an approved/submitted assignment exists.
effective_leave_policy = the controlling row's policy_name.
annual_days / balance_days = that row's approved_leave_days (integer-cast as the template demands).
excluded_leave_ids = the other leave rows you rejected (the Draft and Superseded ones).
- The employee profile is the "stale profile summary"; when an approved assignment overrides it,
profile_policy_ignored: true, precedence_source: approved_assignment_over_profile,
leave_precedence_source: approved_assignment_current_period, and the typical
next_action: update_employee_summary with audit_result: profile_summary_stale.
2.2 Payroll / salary source (PAY-SRC-001 §3.4)
"Use the current submitted salary assignment. Draft planning assignments do not affect
payroll readiness or accrual checks."
record_type: "Salary assignment" rows. Choose the Submitted one for base salary.
excluded_assignment_id / excluded_payroll_ids = the Draft (and any Superseded) salary rows.
base_salary = the submitted row's base_salary. payroll_status/payroll_source_status = submitted.
draft_exclusion_rule: exclude_draft_assignment; draft_payroll_allowed: false.
effective_date = the submitted row's date (use its period/updated_at, e.g. period 2026-04 → 2026-04-01).
2.3 Accrual readiness
- The submitted salary row carries an
accrual_batch_id. It is "ready" when an audit event
confirms the submitted assignment matches that accrual batch (event payroll.ready,
detail "ready_with_monitoring ... matches accrual batch ...").
accrual_ready: true, accrual_batch_id from the row, control_result: ready_with_monitoring,
audit_scope: payroll_assignment_readiness.
2.4 Folder readiness (POL-DOCS-2026 §5.1)
"A folder is not ready unless all required files AND all required tags in the checklist are present."
- From
/api/documents: missing_files = required_files − files; missing tags = required_tags − tags.
folder_ready = (no missing files) AND (no missing tags). (Trust the computed set; the API's
ready flag should agree, but compute it yourself.)
required_tag_present = the specific required tag is in tags.
folder_required_tag_action: add_required_tag if a required tag is missing, else no_tag_action.
- A case may also carry a folder-checklist attachment (e.g. "Missing tax-equalization-agreement.pdf.
Tag PolicyException2026 present.") — read it; it names the exact missing file(s)/tag state.
2.5 Formal-notice defect detection
- Notices live in
/api/messages (and recruitment.notice_packets). Each has quality
(valid/defective) and a defects array using the controlled vocabulary:
missing_ack_deadline, missing_appeal_instructions, missing_waitlist_status,
missing_correct_policy.
- For remote-work/exception notices, HR-POL-014 §7.1 requires appeal instructions and an
acknowledgement deadline; absence → those defect codes.
notice_quality = the message's quality; notice_defects = its defects list.
notice_evidence_source / notice_quality_source: use notice_packet_inspection when you
inspected the recruitment notice packet or message body; message_notice_inspection if only the
message module; never case_summary_only when packet/message data exists.
- Remediation for a defective notice:
notice_remediation_action: reissue_defective_notices.
2.6 Closeout / approval gate
"Approval alone is NOT sufficient when the folder or notice is defective."
approval_closeout_gate:
approval_sufficient_when_records_clean — folder ready, no missing tags, notice valid (or no notice/folder in scope). → next_action: approve_onboarding_close, final_control_result: approve_closeout.
approval_not_sufficient_when_folder_or_notice_defective — any folder/tag/notice defect. →
final_control_result: hold_for_folder_and_notice_defects.
closeout_blockers (subset of missing_required_files, missing_required_tags,
defective_formal_notice) = exactly the defects you found.
next_action / escalation_action:
- defective notice present →
block_close_and_reissue_notice;
- missing files/tags but notice OK →
open_records_remediation;
- clean →
approve_onboarding_close / no_action.
records_remediation_owner = the folder owner, usually Records (or People Ops Compliance
for cross-module packages, Payroll QA for payroll). Take it from the case owner /
document owner / audit actor rather than guessing.
evidence_source_order: when an approval exists, approval_history_folder_notice_audit;
otherwise folder_notice_audit.
2.7 Recruitment reconciliation
- From the matching
/api/recruitment opening:
selected_candidate = candidate with committee_decision: "Selected".
waitlisted_candidates = those with "Waitlisted"; rejected_candidates = "Rejected". Arrays hold candidate IDs only.
offer_id / offer_base_salary / selected_offer_status = from offer_register for the
selected candidate (status: accepted). Waitlisted/rejected have no offer.
recruitment_cost_total = sum of every cost_ledger line amount for that opening (only that campaign's ledger).
notice_followup_required = candidates whose required notice is not yet sent. Check
notice_packets[].status ("not_sent"/"draft_reissue_required") and candidate
notice_status ("Notice not sent"). Selected candidate with an approved offer package needs no follow-up.
waitlisted_followup_action: send_waitlist_notice if never sent;
reissue_waitlist_notice_not_rejection if a defective/draft waitlist notice must be re-sent.
rejected_followup_action: send_rejection_notice if not sent, else reissue_rejection_notice/no_action.
- Payroll handoff gate (PAY-SRC-001 §4.2): handoff is created only after the selected
candidate has an accepted offer, AND it must be a submitted assignment — draft prechecks do
NOT satisfy the gate.
- If accepted offer but no submitted assignment yet (
payroll_precheck_records empty or Draft):
onboarding_handoff: create_submitted_assignment_after_acceptance,
payroll_handoff_gate: accepted_offer_and_submitted_assignment,
payroll_assignment_status_required: submitted_after_acceptance,
draft_payroll_allowed: false,
handoff_control_result: submitted_handoff_required_after_acceptance.
- No accepted offer →
no_payroll_handoff / no_handoff_required.
- Sourcing labels:
candidate_status_source: interview_feedback_and_offer,
candidate_outcome_control: committee_decision_with_offer_confirmation,
cost_source: recruitment_cost_ledger.
offer_exclusion_reason_for_waitlisted: no_accepted_status_or_offer (waitlisted candidates are
excluded from offer/handoff because they have no accepted status or offer).
2.8 Audit correlation & scope
- Each task has one scope:
leave_source_precedence_only, payroll_assignment_readiness,
or document_notice_findings_only. Only audit events whose event/detail match that scope are
"supporting"; events about the other domains are "adjacent" and must be excluded.
audit_event_id = the single primary QA event for the decision (e.g. the leave.profile_mismatch,
payroll.ready, or notice.defect/folder.tag_missing event for that case/employee).
supporting_audit_event_ids = the in-scope event(s) (often just the primary one).
excluded_audit_event_ids = same-case/same-employee events from a DIFFERENT domain. Example:
for a leave-scope decision on EMP-118 you include AUD-EMP118-LEAVE-04 (leave) and EXCLUDE
AUD-DOC118-06 (folder/tag) because it is a document finding, not a leave finding.
- A
cross_module.escalation_package event (e.g. AUD-XMODULE-77) lists related events from
multiple entities. It instructs you to "review each related event before assigning entity-level
issues" — for a single-entity task, those other-entity events are out of scope/excluded.
3. Normalized-label vocabulary (use template enums verbatim)
The grader checks exact enum strings. Always copy the allowed value from the template; never
invent free text. Key recurring values:
- Statuses:
submitted, draft, superseded; offer accepted/draft/withdrawn/none.
- Leave precedence:
approved_assignment_over_profile, approved_assignment_current_period,
employee_profile_summary, profile_summary_current_period, case_summary_only.
- Payroll:
exclude_draft_assignment, accepted_offer_and_submitted_assignment,
submitted_after_acceptance, submitted_handoff_required_after_acceptance.
- Gates:
approval_sufficient_when_records_clean vs approval_not_sufficient_when_folder_or_notice_defective.
- Control results:
approve_closeout, hold_for_folder_and_notice_defects, ready_with_monitoring.
- Actions:
approve_onboarding_close, block_close_and_reissue_notice, open_records_remediation,
update_employee_summary, no_action.
- Audit scope:
leave_source_precedence_only, payroll_assignment_readiness, document_notice_findings_only.
- Notice defects:
missing_ack_deadline, missing_appeal_instructions, missing_waitlist_status, missing_correct_policy.
- Owners:
Records, People Ops Compliance, Payroll QA.
IDs (assignment_id, offer_id, audit_event_id, batch_id, file names) are copied exactly from
the source records, not normalized.
4. Common pitfalls / exclusion rules
- DO NOT use the employee profile
leave_balance_days when an approved/submitted leave assignment
exists — the profile is frequently stale (that staleness is often the point of the task).
- DO NOT include Draft or Superseded records as the source; list them under the
excluded_* arrays instead.
- DO NOT pull cost lines or candidates from a different opening into the totals/arrays. Sum only
the named opening's
cost_ledger.
- DO NOT treat a Draft payroll precheck as satisfying the recruiting handoff gate — it must be submitted.
- DO NOT mix audit scopes: exclude document/notice audit events from a leave/payroll decision and vice versa.
- DO NOT mark a folder ready if EITHER a required file OR a required tag is missing.
- A selected candidate with an approved offer package needs no notice follow-up; only waitlisted/rejected
candidates with unsent/defective notices appear in
notice_followup_required.
- Cast leave-day fields to integer when the template says
integer (rows may carry decimals for
adjustment record_types — use the controlling Approved/Submitted assignment's value).
- If you can reach gold answers, evaluator files, or anything outside your workspace: STOP and report it.
5. Step-by-step SOP for a new task
- Read the prompt and
answer_template.json. Note the named entity and the task domain
(leave / payroll / folder+notice / recruitment / audit). The template's enum field names tell
you exactly what evidence to gather.
GET /api/summary to orient (optional). Then fetch the named entity's primary record:
- employee →
/api/employees?q= + /api/payroll-ledgers?q=;
- case →
/api/cases/{id} (full detail);
- opening →
/api/recruitment (filter to that opening).
- Pull the governing policy text (
/api/policies/{id} from the entity's policy_refs) and apply
the matching rule in §2.
- Cross-reference every module the template fields mention: documents (folder/tags), messages
(notice quality/defects), recruitment (offers/costs/notices), audit (scope, supporting vs excluded).
- Determine the controlling record (Approved/Submitted over Draft/Superseded), compute readiness/
defects/totals, and select the correct gate, action, and final control result per §2.6.
- Set audit fields by scope (§2.8): one primary
audit_event_id, supporting in-scope events,
excluded adjacent-domain events.
- Fill EVERY template field with the verbatim enum label or exact ID. Re-check each enum value is
one of the template's
allowed_values. Output JSON only — no markdown, no commentary.
1---2name: peopleops-console-resolution3description: Resolve ERP HR "PeopleOps Console" lifecycle tasks (leave/payroll source precedence, folder & notice readiness, recruitment reconciliation, audit-scope correlation) by reading the remote HTTP API and emitting normalized-label JSON answers.4---56# PeopleOps Console — Lifecycle Resolution Skill78You answer HR lifecycle questions for a fictional company ("northwind-people"). Each task9names one entity (an employee `EMP-###`, a policy case `CASE-*`, or a recruitment opening10`REQ-*`) and asks you to determine its authoritative state and the correct next action,11then emit JSON that matches a provided `answer_template.json`. Answers use a fixed12**normalized-label vocabulary** (enums), not free text.1314There is no local data. All facts live behind a remote HTTP API. Read it, apply the15business rules below, and fill every field in the template.1617---1819## 1. How to use the remote API2021Base URL is given in `environment_access.md` (e.g. `<remote-env-url>`).22No auth. All responses are JSON. The `q=` filter is a case-insensitive substring match23over scalar fields, so `q=EMP-118`, `q=CASE-RW-221`, `q=REQ-DA-77` are good lookups; omit24`q` to get the whole collection.2526Endpoints and when to use them:27- `GET /api/manifest`, `GET /api/summary` — orient: counts, modules, departments. Cheap sanity check.28- `GET /api/employees?q=EMP-###` — profile summary (status, `leave_balance_days`, band, manager). Often **stale** — never trust it over an assignment record.29- `GET /api/payroll-ledgers?q=EMP-###` — the single most important endpoint. Holds BOTH30 leave-assignment rows (`record_type: "Leave assignment"` / `"HRMS leave ledger"` /31 `"People Ops adjustment"`) AND salary-assignment rows (`record_type: "Salary assignment"`),32 each with a `status` of Approved/Submitted/Draft/Superseded. This is the authority for33 leave policy, leave days, base salary, and accrual batch.34- `GET /api/policies` and `/api/policies/{id}` — the written business rules (LEAVE-SRC-001,35 PAY-SRC-001, POL-DOCS-2026, HR-POL-014). Read the section bodies; they literally state the36 precedence/readiness rules used to grade.37- `GET /api/cases` (summaries) then `GET /api/cases/{case_id}` for FULL detail — approvals,38 attachments (folder checklist), comments, embedded audit_events, notice/notice refs, policy_refs.39- `GET /api/documents?q=...` — folders with `files`, `required_files`, `required_tags`, `tags`, `ready`.40- `GET /api/messages?q=...` — formal notices with `quality` and `defects` arrays.41- `GET /api/recruitment` — openings with candidates, offer_register, cost_ledger,42 notice_packets, payroll_precheck_records.43- `GET /api/audit?q=...&case_id=...` and `/api/audit/{id}` — QA/control events. Detail strings44 echo the exact normalized labels you must emit (e.g. "profile_summary_stale",45 "ready_with_monitoring", "block close", "draft_excluded").46- `GET /api/notifications`, `GET /api/attachments/{id}` — raw notification / notice body text.4748**Always cross-reference modules.** An employee's true state is spread across employees +49payroll-ledgers + policies + cases + documents + messages + audit. Start from the named entity,50then pull every module that the answer template's fields reference.5152---5354## 2. Core business rules (transferable)5556### 2.1 Leave source precedence (LEAVE-SRC-001)57"The latest **approved or submitted** leave assignment for the period controls. Draft, voided,58and obsolete (Superseded) records are excluded even when profile summaries conflict."59- Pick the controlling leave row from `payroll-ledgers` for that employee/period:60 prefer **Approved**, else **Submitted**. If both exist for the period, take the latest by61 `updated_at`. **Never** pick a `Draft` or `Superseded` row, and **never** use the employee62 profile's `leave_balance_days` as the source when an approved/submitted assignment exists.63- `effective_leave_policy` = the controlling row's `policy_name`.64- `annual_days` / `balance_days` = that row's `approved_leave_days` (integer-cast as the template demands).65- `excluded_leave_ids` = the other leave rows you rejected (the Draft and Superseded ones).66- The employee profile is the "stale profile summary"; when an approved assignment overrides it,67 `profile_policy_ignored: true`, `precedence_source: approved_assignment_over_profile`,68 `leave_precedence_source: approved_assignment_current_period`, and the typical69 `next_action: update_employee_summary` with `audit_result: profile_summary_stale`.7071### 2.2 Payroll / salary source (PAY-SRC-001 §3.4)72"Use the current **submitted** salary assignment. Draft planning assignments do not affect73payroll readiness or accrual checks."74- `record_type: "Salary assignment"` rows. Choose the **Submitted** one for base salary.75- `excluded_assignment_id` / `excluded_payroll_ids` = the Draft (and any Superseded) salary rows.76- `base_salary` = the submitted row's `base_salary`. `payroll_status`/`payroll_source_status` = `submitted`.77- `draft_exclusion_rule: exclude_draft_assignment`; `draft_payroll_allowed: false`.78- `effective_date` = the submitted row's date (use its `period`/`updated_at`, e.g. period `2026-04` → `2026-04-01`).7980### 2.3 Accrual readiness81- The submitted salary row carries an `accrual_batch_id`. It is "ready" when an audit event82 confirms the submitted assignment **matches** that accrual batch (event `payroll.ready`,83 detail "ready_with_monitoring ... matches accrual batch ...").84- `accrual_ready: true`, `accrual_batch_id` from the row, `control_result: ready_with_monitoring`,85 `audit_scope: payroll_assignment_readiness`.8687### 2.4 Folder readiness (POL-DOCS-2026 §5.1)88"A folder is not ready unless **all required files AND all required tags** in the checklist are present."89- From `/api/documents`: `missing_files = required_files − files`; missing tags = `required_tags − tags`.90- `folder_ready = (no missing files) AND (no missing tags)`. (Trust the computed set; the API's91 `ready` flag should agree, but compute it yourself.)92- `required_tag_present` = the specific required tag is in `tags`.93- `folder_required_tag_action`: `add_required_tag` if a required tag is missing, else `no_tag_action`.94- A case may also carry a folder-checklist **attachment** (e.g. "Missing tax-equalization-agreement.pdf.95 Tag PolicyException2026 present.") — read it; it names the exact missing file(s)/tag state.9697### 2.5 Formal-notice defect detection98- Notices live in `/api/messages` (and `recruitment.notice_packets`). Each has `quality`99 (`valid`/`defective`) and a `defects` array using the controlled vocabulary:100 `missing_ack_deadline`, `missing_appeal_instructions`, `missing_waitlist_status`,101 `missing_correct_policy`.102- For remote-work/exception notices, HR-POL-014 §7.1 requires appeal instructions and an103 acknowledgement deadline; absence → those defect codes.104- `notice_quality` = the message's `quality`; `notice_defects` = its `defects` list.105- `notice_evidence_source` / `notice_quality_source`: use `notice_packet_inspection` when you106 inspected the recruitment notice packet or message body; `message_notice_inspection` if only the107 message module; never `case_summary_only` when packet/message data exists.108- Remediation for a defective notice: `notice_remediation_action: reissue_defective_notices`.109110### 2.6 Closeout / approval gate111"Approval alone is NOT sufficient when the folder or notice is defective."112- `approval_closeout_gate`:113 - `approval_sufficient_when_records_clean` — folder ready, no missing tags, notice valid (or no notice/folder in scope). → `next_action: approve_onboarding_close`, `final_control_result: approve_closeout`.114 - `approval_not_sufficient_when_folder_or_notice_defective` — any folder/tag/notice defect. →115 `final_control_result: hold_for_folder_and_notice_defects`.116- `closeout_blockers` (subset of `missing_required_files`, `missing_required_tags`,117 `defective_formal_notice`) = exactly the defects you found.118- `next_action` / `escalation_action`:119 - defective notice present → `block_close_and_reissue_notice`;120 - missing files/tags but notice OK → `open_records_remediation`;121 - clean → `approve_onboarding_close` / `no_action`.122- `records_remediation_owner` = the folder owner, usually `Records` (or `People Ops Compliance`123 for cross-module packages, `Payroll QA` for payroll). Take it from the case `owner` /124 document owner / audit `actor` rather than guessing.125- `evidence_source_order`: when an approval exists, `approval_history_folder_notice_audit`;126 otherwise `folder_notice_audit`.127128### 2.7 Recruitment reconciliation129- From the matching `/api/recruitment` opening:130 - `selected_candidate` = candidate with `committee_decision: "Selected"`.131 - `waitlisted_candidates` = those with `"Waitlisted"`; `rejected_candidates` = `"Rejected"`. Arrays hold candidate IDs only.132 - `offer_id` / `offer_base_salary` / `selected_offer_status` = from `offer_register` for the133 selected candidate (`status: accepted`). Waitlisted/rejected have no offer.134 - `recruitment_cost_total` = **sum of every `cost_ledger` line `amount`** for that opening (only that campaign's ledger).135 - `notice_followup_required` = candidates whose required notice is not yet sent. Check136 `notice_packets[].status` ("not_sent"/"draft_reissue_required") and candidate137 `notice_status` ("Notice not sent"). Selected candidate with an approved offer package needs no follow-up.138 - `waitlisted_followup_action`: `send_waitlist_notice` if never sent;139 `reissue_waitlist_notice_not_rejection` if a defective/draft waitlist notice must be re-sent.140 - `rejected_followup_action`: `send_rejection_notice` if not sent, else `reissue_rejection_notice`/`no_action`.141- **Payroll handoff gate** (PAY-SRC-001 §4.2): handoff is created **only after the selected142 candidate has an accepted offer, AND it must be a *submitted* assignment** — draft prechecks do143 NOT satisfy the gate.144 - If accepted offer but no submitted assignment yet (`payroll_precheck_records` empty or Draft):145 `onboarding_handoff: create_submitted_assignment_after_acceptance`,146 `payroll_handoff_gate: accepted_offer_and_submitted_assignment`,147 `payroll_assignment_status_required: submitted_after_acceptance`,148 `draft_payroll_allowed: false`,149 `handoff_control_result: submitted_handoff_required_after_acceptance`.150 - No accepted offer → `no_payroll_handoff` / `no_handoff_required`.151- Sourcing labels: `candidate_status_source: interview_feedback_and_offer`,152 `candidate_outcome_control: committee_decision_with_offer_confirmation`,153 `cost_source: recruitment_cost_ledger`.154- `offer_exclusion_reason_for_waitlisted: no_accepted_status_or_offer` (waitlisted candidates are155 excluded from offer/handoff because they have no accepted status or offer).156157### 2.8 Audit correlation & scope158- Each task has one **scope**: `leave_source_precedence_only`, `payroll_assignment_readiness`,159 or `document_notice_findings_only`. Only audit events whose event/detail match that scope are160 "supporting"; events about the other domains are "adjacent" and must be **excluded**.161- `audit_event_id` = the single primary QA event for the decision (e.g. the `leave.profile_mismatch`,162 `payroll.ready`, or `notice.defect`/`folder.tag_missing` event for that case/employee).163- `supporting_audit_event_ids` = the in-scope event(s) (often just the primary one).164- `excluded_audit_event_ids` = same-case/same-employee events from a DIFFERENT domain. Example:165 for a leave-scope decision on EMP-118 you include `AUD-EMP118-LEAVE-04` (leave) and EXCLUDE166 `AUD-DOC118-06` (folder/tag) because it is a document finding, not a leave finding.167- A `cross_module.escalation_package` event (e.g. AUD-XMODULE-77) lists related events from168 multiple entities. It instructs you to "review each related event before assigning entity-level169 issues" — for a single-entity task, those other-entity events are out of scope/excluded.170171---172173## 3. Normalized-label vocabulary (use template enums verbatim)174175The grader checks exact enum strings. Always copy the allowed value from the template; never176invent free text. Key recurring values:177- Statuses: `submitted`, `draft`, `superseded`; offer `accepted`/`draft`/`withdrawn`/`none`.178- Leave precedence: `approved_assignment_over_profile`, `approved_assignment_current_period`,179 `employee_profile_summary`, `profile_summary_current_period`, `case_summary_only`.180- Payroll: `exclude_draft_assignment`, `accepted_offer_and_submitted_assignment`,181 `submitted_after_acceptance`, `submitted_handoff_required_after_acceptance`.182- Gates: `approval_sufficient_when_records_clean` vs `approval_not_sufficient_when_folder_or_notice_defective`.183- Control results: `approve_closeout`, `hold_for_folder_and_notice_defects`, `ready_with_monitoring`.184- Actions: `approve_onboarding_close`, `block_close_and_reissue_notice`, `open_records_remediation`,185 `update_employee_summary`, `no_action`.186- Audit scope: `leave_source_precedence_only`, `payroll_assignment_readiness`, `document_notice_findings_only`.187- Notice defects: `missing_ack_deadline`, `missing_appeal_instructions`, `missing_waitlist_status`, `missing_correct_policy`.188- Owners: `Records`, `People Ops Compliance`, `Payroll QA`.189190IDs (assignment_id, offer_id, audit_event_id, batch_id, file names) are copied **exactly** from191the source records, not normalized.192193---194195## 4. Common pitfalls / exclusion rules196197- DO NOT use the employee profile `leave_balance_days` when an approved/submitted leave assignment198 exists — the profile is frequently stale (that staleness is often the point of the task).199- DO NOT include Draft or Superseded records as the source; list them under the `excluded_*` arrays instead.200- DO NOT pull cost lines or candidates from a *different* opening into the totals/arrays. Sum only201 the named opening's `cost_ledger`.202- DO NOT treat a Draft payroll precheck as satisfying the recruiting handoff gate — it must be submitted.203- DO NOT mix audit scopes: exclude document/notice audit events from a leave/payroll decision and vice versa.204- DO NOT mark a folder ready if EITHER a required file OR a required tag is missing.205- A selected candidate with an approved offer package needs no notice follow-up; only waitlisted/rejected206 candidates with unsent/defective notices appear in `notice_followup_required`.207- Cast leave-day fields to integer when the template says `integer` (rows may carry decimals for208 adjustment record_types — use the controlling Approved/Submitted assignment's value).209- If you can reach gold answers, evaluator files, or anything outside your workspace: STOP and report it.210211---212213## 5. Step-by-step SOP for a new task2142151. Read the prompt and `answer_template.json`. Note the named entity and the task domain216 (leave / payroll / folder+notice / recruitment / audit). The template's enum field names tell217 you exactly what evidence to gather.2182. `GET /api/summary` to orient (optional). Then fetch the named entity's primary record:219 - employee → `/api/employees?q=` + `/api/payroll-ledgers?q=`;220 - case → `/api/cases/{id}` (full detail);221 - opening → `/api/recruitment` (filter to that opening).2223. Pull the governing policy text (`/api/policies/{id}` from the entity's `policy_refs`) and apply223 the matching rule in §2.2244. Cross-reference every module the template fields mention: documents (folder/tags), messages225 (notice quality/defects), recruitment (offers/costs/notices), audit (scope, supporting vs excluded).2265. Determine the controlling record (Approved/Submitted over Draft/Superseded), compute readiness/227 defects/totals, and select the correct gate, action, and final control result per §2.6.2286. Set audit fields by scope (§2.8): one primary `audit_event_id`, supporting in-scope events,229 excluded adjacent-domain events.2307. Fill EVERY template field with the verbatim enum label or exact ID. Re-check each enum value is231 one of the template's `allowed_values`. Output JSON only — no markdown, no commentary.