PeopleOps Console — Lifecycle Control Skill
You answer HR lifecycle questions for the PeopleOps Console by reading a remote
HTTP API and returning a single JSON object that matches the task's
answer_template.json. Every value must be either a fact pulled from the API or
the exact normalized business label allowed by the template enum. Never write
free-text explanations into label fields, and never invent IDs.
1. How to use the remote API
Base URL is given in the environment-access doc. No auth (login text in prompts is
flavor). All responses are JSON. Use HTTP GET; q= is a case-insensitive
substring filter over scalar fields, so q=EMP-118, q=CASE-445, q=REQ-DA-77
are effective lookups; omit q to list a whole collection.
Endpoints you will rely on:
/api/summary, /api/manifest — counts, departments, sanity check.
/api/employees?q= — profile (department, salary_band, leave_balance_days, status).
/api/payroll-ledgers?q= — BOTH leave assignments AND salary assignments AND
accrual/adjustment rows live here, keyed by record_type, status, period.
/api/policies / /api/policies/{id} — the governing precedence rules (read these first; they state the tie-break logic verbatim).
/api/cases?... (summaries) and /api/cases/{id} (FULL: approvals,
attachments, comments, embedded audit_events, folder/notice detail).
/api/documents?q= — folders with files, required_files, tags,
required_tags, ready.
/api/messages?q= — formal notices delivered as messages, with quality and defects.
/api/recruitment?q= — openings with candidates, offer_register,
cost_ledger, notice_packets, payroll_precheck_records.
/api/audit?q=&case_id= and /api/audit/{id} — QA events; their detail
text is frequently the authoritative tie-breaker (see below).
Workflow for any task: (1) read the prompt + answer_template to learn which
fields and which enum labels are in play; (2) pull the focal entity by id across
employees, payroll-ledgers, cases/{id}, documents, messages, recruitment, audit;
(3) read the policy doc(s) named in the case's policy_refs; (4) apply the rules
below; (5) emit JSON matching the template, using only allowed enum values and
correct types (integers as integers, lists as lists, booleans as booleans).
2. Core source-precedence rules
These come from the policy documents and are the heart of most tasks.
Leave source precedence (LEAVE-SRC-001). The latest approved or submitted
leave assignment for the period controls entitlement. Draft, voided, superseded,
and obsolete rows are EXCLUDED even when the employee profile summary disagrees.
leave_source = leave_assignment_history (not employee_profile_summary).
leave_precedence_source = approved_assignment_current_period
(NOT profile_summary_current_period).
- When a case is specifically a profile-vs-assignment dispute:
precedence_source = approved_assignment_over_profile,
profile_policy_ignored = true, and the next action is to update the stale
summary (update_employee_summary).
- List every excluded leave ledger id (draft + superseded/obsolete) in the
excluded-leave field.
Payroll/salary source (PAY-SRC-001). Use the current submitted salary
assignment for base salary and readiness. Draft planning assignments do NOT count
and must be excluded; superseded rows are excluded too.
payroll_status / payroll_source_status = submitted.
draft_exclusion_rule = exclude_draft_assignment; draft_payroll_allowed = false.
- Put the draft (and any superseded) salary id in the excluded-payroll field.
Accrual readiness. A submitted salary assignment is accrual-ready when it
matches the relevant accrual batch (the assignment row carries the
accrual_batch_id, and an audit payroll.ready event confirms it).
accrual_ready = true in that case; take accrual_batch_id from the
submitted assignment row.
control_result for payroll readiness = ready_with_monitoring — NOT
approve_closeout (that label is reserved for onboarding-close with clean records).
3. Folder readiness, missing files, and required tags
From the lifecycle folder checklist (POL-DOCS-2026): a folder is ready ONLY when
every required file AND every required tag is present.
folder_ready = the document's ready flag; verify it by diffing
required_files minus files and required_tags minus tags.
missing_files = required_files not present in files (exact filenames).
required_tag_present = whether the required tag(s) are all in tags.
- If the required tag is already present,
folder_required_tag_action =
no_tag_action; only use add_required_tag when a required tag is missing.
closeout_blockers is driven by the actual gaps: include
missing_required_files only if a file is missing, missing_required_tags
only if a tag is missing, defective_formal_notice only if the notice is
defective. Do not list a blocker that does not apply (e.g. tag present ⇒ no
missing_required_tags).
4. Formal-notice quality and defect codes
Notices are inspected from the notice packet (recruitment notice_packets)
or the message record (/api/messages), which carry quality and defects.
notice_quality = valid or defective straight from the record.
notice_quality_source / notice_evidence_source = notice_packet_inspection
(assess the formal notice packet; this is the right label even when the notice
is delivered through a message channel — do not pick message_notice_inspection
or case_summary_only).
- Defect codes come from the controlled vocabulary and must match the record's
defects exactly: missing_ack_deadline, missing_appeal_instructions,
missing_waitlist_status, missing_correct_policy. Copy the listed defects;
do not infer extra ones.
- Remediation: a defective notice ⇒
reissue_defective_notices /
block_close_and_reissue_notice. A waitlist notice that was wrongly omitted or
mislabeled is reissued as a waitlist notice, not a rejection
(reissue_waitlist_notice_not_rejection); a not-yet-sent waitlist/rejection
notice is a fresh send (send_waitlist_notice / send_rejection_notice).
5. Approval / closeout gate and final control result
Approval alone is not enough to close.
approval_closeout_gate = approval_sufficient_when_records_clean ONLY when
the folder is ready AND the notice is valid (no defects). If any folder file/tag
gap or notice defect exists, it is
approval_not_sufficient_when_folder_or_notice_defective.
final_control_result:
- clean records (no folder/notice defect) ⇒
approve_closeout;
- any folder/notice defect ⇒
hold_for_folder_and_notice_defects;
ready_with_monitoring is the payroll-readiness verdict, not an
onboarding-close verdict.
closeout_action / next_action follows the same logic: clean ⇒
approve_onboarding_close; notice defect ⇒ block_close_and_reissue_notice; a
missing required FILE is a records issue ⇒ open_records_remediation. When both
a file is missing and the notice is defective, the immediate next_action
addresses the notice (block_close_and_reissue_notice) while the
escalation_action opens records remediation for the file
(open_records_remediation) — these two fields can legitimately differ.
evidence_source_order for a closeout review =
approval_history_folder_notice_audit (approvals first, then folder, notice, audit).
records_remediation_owner for a single case's missing folder file = Records
(owner of folder/required evidence). People Ops Compliance owns the
cross-module escalation package, not single-case file remediation.
6. Audit correlation and scope (very point-sensitive)
Each task has ONE audit scope; set audit_scope to match the task:
leave_source_precedence_only, payroll_assignment_readiness, or
document_notice_findings_only.
audit_event_id / supporting_audit_event_ids = the audit event(s) whose
event/detail are IN the current scope (e.g. the leave.profile_mismatch
event for a leave task, the payroll.ready event for an accrual task, the
notice.defect / folder event for a doc/notice task).
excluded_audit_event_ids = same-case audit events that belong to a
DIFFERENT scope and must be kept out of this decision (e.g. on a leave-scope
task, exclude the same case's folder/notice audit event). Rules learned the
hard way:
- Do NOT dump every other case's audit ids into the exclusion list — only
same-case, out-of-scope events belong there.
- If the case has no other-scope audit event,
excluded_audit_event_ids = [].
- Omitting a genuinely adjacent same-case out-of-scope event costs points, so
always check the full
/api/cases/{id}.audit_events list for siblings.
- The audit
detail text is an authoritative tie-breaker. When a leave or
payroll task has several "Approved"/"Submitted" ledger rows, the audit QA detail
often names the controlling assignment id and the resulting balance/policy —
trust that named record rather than guessing the latest or largest row.
- The cross-module escalation package event lists the related event ids and the
control owner; treat it as the routing record, not as in-scope evidence for a
single entity's leave/payroll decision.
7. Recruitment reconciliation
- Candidate outcomes come from committee decision + offer confirmation:
candidate_status_source = interview_feedback_and_offer,
candidate_outcome_control = committee_decision_with_offer_confirmation.
Map committee_decision to selected / waitlisted / rejected arrays
(arrays hold candidate IDs only).
- The selected candidate's offer status comes from
offer_register
(accepted / draft / withdrawn); offer_id and offer_base_salary from
that register row.
recruitment_cost_total = sum of this opening's cost_ledger items only.
Do not add other openings' ledgers. cost_source = recruitment_cost_ledger.
- Notice follow-up: list candidates whose notices are not yet sent / are
defective; choose send vs reissue per §4.
- Waitlisted candidates are excluded from the payroll/offer handoff because they
have
no_accepted_status_or_offer.
- Payroll handoff gate (PAY-SRC-001): a handoff is created only after a selected
candidate has an accepted offer, and the handoff/assignment must be
submitted — a draft precheck never satisfies the gate
(
draft_payroll_allowed = false). When an offer is accepted, a submitted
handoff/assignment is required after acceptance; when no offer is accepted,
there is no handoff. (The exact normalized label among the close gate/status
variants depends on the template's enum wording — read the allowed values and
pick the option that states "submitted, after acceptance"; verify against the
policy text rather than assuming.)
8. Output discipline / common misjudgments that cost points
- Return ONLY the JSON object matching the template — no markdown, no commentary.
- Use the EXACT allowed enum strings; respect types (int vs number vs string,
list vs scalar, boolean not string).
- Dates in dedicated date fields are usually
YYYY-MM-DD (derive from
period/updated_at), not full timestamps.
- Authoritative state spans modules: never answer a leave/payroll question from
the employee profile or a case summary alone — confirm with the ledger, the
policy doc, and the audit detail.
- Mistakes that previously lowered scores, now avoided:
- using
profile_summary precedence instead of approved_assignment;
- calling a payroll-readiness result
approve_closeout instead of ready_with_monitoring;
- listing unrelated cases' audit ids as "excluded", or conversely forgetting to
exclude a same-case out-of-scope audit event;
- choosing
message_notice_inspection instead of notice_packet_inspection;
- assigning single-case file remediation to People Ops Compliance instead of Records;
- summing cost ledgers across openings instead of the one opening in scope;
- flagging
missing_required_tags when the required tag is actually present.
NOTE: There is no judge or scoring API available at test time. Do not attempt to
call any feedback/scoring endpoint when solving real tasks — derive the answer
from the read-only PeopleOps API and the rules above.
1---2name: peopleops-console-lifecycle-control3description: Solve ERP HR "PeopleOps Console" lifecycle/leave/payroll/policy-case/recruitment/document/notice/audit tasks by cross-referencing the remote HTTP API and applying source-precedence, folder-readiness, notice-defect, and audit-scope business rules to emit normalized-label JSON.4---56# PeopleOps Console — Lifecycle Control Skill78You answer HR lifecycle questions for the PeopleOps Console by reading a remote9HTTP API and returning a single JSON object that matches the task's10`answer_template.json`. Every value must be either a fact pulled from the API or11the exact **normalized business label** allowed by the template enum. Never write12free-text explanations into label fields, and never invent IDs.1314## 1. How to use the remote API1516Base URL is given in the environment-access doc. No auth (login text in prompts is17flavor). All responses are JSON. Use HTTP GET; `q=` is a case-insensitive18substring filter over scalar fields, so `q=EMP-118`, `q=CASE-445`, `q=REQ-DA-77`19are effective lookups; omit `q` to list a whole collection.2021Endpoints you will rely on:22- `/api/summary`, `/api/manifest` — counts, departments, sanity check.23- `/api/employees?q=` — profile (department, salary_band, `leave_balance_days`, status).24- `/api/payroll-ledgers?q=` — BOTH leave assignments AND salary assignments AND25 accrual/adjustment rows live here, keyed by `record_type`, `status`, `period`.26- `/api/policies` / `/api/policies/{id}` — the governing precedence rules (read these first; they state the tie-break logic verbatim).27- `/api/cases?...` (summaries) and `/api/cases/{id}` (FULL: approvals,28 attachments, comments, embedded audit_events, folder/notice detail).29- `/api/documents?q=` — folders with `files`, `required_files`, `tags`,30 `required_tags`, `ready`.31- `/api/messages?q=` — formal notices delivered as messages, with `quality` and `defects`.32- `/api/recruitment?q=` — openings with `candidates`, `offer_register`,33 `cost_ledger`, `notice_packets`, `payroll_precheck_records`.34- `/api/audit?q=&case_id=` and `/api/audit/{id}` — QA events; their `detail`35 text is frequently the authoritative tie-breaker (see below).3637**Workflow for any task:** (1) read the prompt + answer_template to learn which38fields and which enum labels are in play; (2) pull the focal entity by id across39employees, payroll-ledgers, cases/{id}, documents, messages, recruitment, audit;40(3) read the policy doc(s) named in the case's `policy_refs`; (4) apply the rules41below; (5) emit JSON matching the template, using only allowed enum values and42correct types (integers as integers, lists as lists, booleans as booleans).4344## 2. Core source-precedence rules4546These come from the policy documents and are the heart of most tasks.4748**Leave source precedence (LEAVE-SRC-001).** The latest **approved or submitted**49leave assignment for the period controls entitlement. Draft, voided, superseded,50and obsolete rows are EXCLUDED even when the employee profile summary disagrees.51- `leave_source` = `leave_assignment_history` (not `employee_profile_summary`).52- `leave_precedence_source` = `approved_assignment_current_period`53 (NOT `profile_summary_current_period`).54- When a case is specifically a profile-vs-assignment dispute:55 `precedence_source` = `approved_assignment_over_profile`,56 `profile_policy_ignored` = `true`, and the next action is to update the stale57 summary (`update_employee_summary`).58- List every excluded leave ledger id (draft + superseded/obsolete) in the59 excluded-leave field.6061**Payroll/salary source (PAY-SRC-001).** Use the **current submitted** salary62assignment for base salary and readiness. Draft planning assignments do NOT count63and must be excluded; superseded rows are excluded too.64- `payroll_status` / `payroll_source_status` = `submitted`.65- `draft_exclusion_rule` = `exclude_draft_assignment`; `draft_payroll_allowed` = `false`.66- Put the draft (and any superseded) salary id in the excluded-payroll field.6768**Accrual readiness.** A submitted salary assignment is accrual-ready when it69matches the relevant accrual batch (the assignment row carries the70`accrual_batch_id`, and an audit `payroll.ready` event confirms it).71- `accrual_ready` = `true` in that case; take `accrual_batch_id` from the72 submitted assignment row.73- `control_result` for payroll readiness = `ready_with_monitoring` — NOT74 `approve_closeout` (that label is reserved for onboarding-close with clean records).7576## 3. Folder readiness, missing files, and required tags7778From the lifecycle folder checklist (POL-DOCS-2026): a folder is ready ONLY when79**every** required file AND **every** required tag is present.80- `folder_ready` = the document's `ready` flag; verify it by diffing81 `required_files` minus `files` and `required_tags` minus `tags`.82- `missing_files` = required_files not present in files (exact filenames).83- `required_tag_present` = whether the required tag(s) are all in `tags`.84- If the required tag is already present, `folder_required_tag_action` =85 `no_tag_action`; only use `add_required_tag` when a required tag is missing.86- `closeout_blockers` is driven by the actual gaps: include87 `missing_required_files` only if a file is missing, `missing_required_tags`88 only if a tag is missing, `defective_formal_notice` only if the notice is89 defective. Do not list a blocker that does not apply (e.g. tag present ⇒ no90 `missing_required_tags`).9192## 4. Formal-notice quality and defect codes9394Notices are inspected from the **notice packet** (recruitment `notice_packets`)95or the message record (`/api/messages`), which carry `quality` and `defects`.96- `notice_quality` = `valid` or `defective` straight from the record.97- `notice_quality_source` / `notice_evidence_source` = `notice_packet_inspection`98 (assess the formal notice packet; this is the right label even when the notice99 is delivered through a message channel — do not pick `message_notice_inspection`100 or `case_summary_only`).101- Defect codes come from the controlled vocabulary and must match the record's102 `defects` exactly: `missing_ack_deadline`, `missing_appeal_instructions`,103 `missing_waitlist_status`, `missing_correct_policy`. Copy the listed defects;104 do not infer extra ones.105- Remediation: a defective notice ⇒ `reissue_defective_notices` /106 `block_close_and_reissue_notice`. A waitlist notice that was wrongly omitted or107 mislabeled is reissued as a waitlist notice, not a rejection108 (`reissue_waitlist_notice_not_rejection`); a not-yet-sent waitlist/rejection109 notice is a fresh send (`send_waitlist_notice` / `send_rejection_notice`).110111## 5. Approval / closeout gate and final control result112113Approval alone is not enough to close.114- `approval_closeout_gate` = `approval_sufficient_when_records_clean` ONLY when115 the folder is ready AND the notice is valid (no defects). If any folder file/tag116 gap or notice defect exists, it is117 `approval_not_sufficient_when_folder_or_notice_defective`.118- `final_control_result`:119 - clean records (no folder/notice defect) ⇒ `approve_closeout`;120 - any folder/notice defect ⇒ `hold_for_folder_and_notice_defects`;121 - `ready_with_monitoring` is the payroll-readiness verdict, not an122 onboarding-close verdict.123- `closeout_action` / `next_action` follows the same logic: clean ⇒124 `approve_onboarding_close`; notice defect ⇒ `block_close_and_reissue_notice`; a125 missing required FILE is a records issue ⇒ `open_records_remediation`. When both126 a file is missing and the notice is defective, the immediate `next_action`127 addresses the notice (`block_close_and_reissue_notice`) while the128 `escalation_action` opens records remediation for the file129 (`open_records_remediation`) — these two fields can legitimately differ.130- `evidence_source_order` for a closeout review =131 `approval_history_folder_notice_audit` (approvals first, then folder, notice, audit).132- `records_remediation_owner` for a single case's missing folder file = `Records`133 (owner of folder/required evidence). `People Ops Compliance` owns the134 cross-module escalation package, not single-case file remediation.135136## 6. Audit correlation and scope (very point-sensitive)137138Each task has ONE audit scope; set `audit_scope` to match the task:139`leave_source_precedence_only`, `payroll_assignment_readiness`, or140`document_notice_findings_only`.141142- `audit_event_id` / `supporting_audit_event_ids` = the audit event(s) whose143 `event`/`detail` are IN the current scope (e.g. the `leave.profile_mismatch`144 event for a leave task, the `payroll.ready` event for an accrual task, the145 `notice.defect` / folder event for a doc/notice task).146- `excluded_audit_event_ids` = **same-case** audit events that belong to a147 DIFFERENT scope and must be kept out of this decision (e.g. on a leave-scope148 task, exclude the same case's folder/notice audit event). Rules learned the149 hard way:150 - Do NOT dump every other case's audit ids into the exclusion list — only151 same-case, out-of-scope events belong there.152 - If the case has no other-scope audit event, `excluded_audit_event_ids` = `[]`.153 - Omitting a genuinely adjacent same-case out-of-scope event costs points, so154 always check the full `/api/cases/{id}.audit_events` list for siblings.155- **The audit `detail` text is an authoritative tie-breaker.** When a leave or156 payroll task has several "Approved"/"Submitted" ledger rows, the audit QA detail157 often names the controlling assignment id and the resulting balance/policy —158 trust that named record rather than guessing the latest or largest row.159- The cross-module escalation package event lists the related event ids and the160 control owner; treat it as the routing record, not as in-scope evidence for a161 single entity's leave/payroll decision.162163## 7. Recruitment reconciliation164165- Candidate outcomes come from committee decision + offer confirmation:166 `candidate_status_source` = `interview_feedback_and_offer`,167 `candidate_outcome_control` = `committee_decision_with_offer_confirmation`.168 Map `committee_decision` to selected / waitlisted / rejected arrays169 (arrays hold candidate IDs only).170- The selected candidate's offer status comes from `offer_register`171 (`accepted` / `draft` / `withdrawn`); `offer_id` and `offer_base_salary` from172 that register row.173- `recruitment_cost_total` = **sum of this opening's `cost_ledger` items only**.174 Do not add other openings' ledgers. `cost_source` = `recruitment_cost_ledger`.175- Notice follow-up: list candidates whose notices are not yet sent / are176 defective; choose send vs reissue per §4.177- Waitlisted candidates are excluded from the payroll/offer handoff because they178 have `no_accepted_status_or_offer`.179- Payroll handoff gate (PAY-SRC-001): a handoff is created only after a selected180 candidate has an **accepted** offer, and the handoff/assignment must be181 **submitted** — a draft precheck never satisfies the gate182 (`draft_payroll_allowed` = `false`). When an offer is accepted, a submitted183 handoff/assignment is required after acceptance; when no offer is accepted,184 there is no handoff. (The exact normalized label among the close gate/status185 variants depends on the template's enum wording — read the allowed values and186 pick the option that states "submitted, after acceptance"; verify against the187 policy text rather than assuming.)188189## 8. Output discipline / common misjudgments that cost points190191- Return ONLY the JSON object matching the template — no markdown, no commentary.192- Use the EXACT allowed enum strings; respect types (int vs number vs string,193 list vs scalar, boolean not string).194- Dates in dedicated date fields are usually `YYYY-MM-DD` (derive from195 `period`/`updated_at`), not full timestamps.196- Authoritative state spans modules: never answer a leave/payroll question from197 the employee profile or a case summary alone — confirm with the ledger, the198 policy doc, and the audit detail.199- Mistakes that previously lowered scores, now avoided:200 - using `profile_summary` precedence instead of `approved_assignment`;201 - calling a payroll-readiness result `approve_closeout` instead of `ready_with_monitoring`;202 - listing unrelated cases' audit ids as "excluded", or conversely forgetting to203 exclude a same-case out-of-scope audit event;204 - choosing `message_notice_inspection` instead of `notice_packet_inspection`;205 - assigning single-case file remediation to People Ops Compliance instead of Records;206 - summing cost ledgers across openings instead of the one opening in scope;207 - flagging `missing_required_tags` when the required tag is actually present.208209NOTE: There is no judge or scoring API available at test time. Do not attempt to210call any feedback/scoring endpoint when solving real tasks — derive the answer211from the read-only PeopleOps API and the rules above.