SKILL — Finance & Control Batch Reconciliation SOP
1. API Endpoints to Inspect
Always call the endpoints exactly as named in the task prompt. Common families across this group:
- AP / Claims
GET /ap/claims/batch/{batch_id}GET /ap/open-balance
- Onboarding / KYC / UBO
GET /onboarding/batch/{batch_id}GET /screening/ubo/{business_id}POST /onboarding/batch/{batch_id}/release-check
- Prepaid / Amortization
GET /finance/prepaid/close-scope?period={YYYY-MM}&entity={entity_name}GET /finance/prepaid/amortization-schedule?invoice_id={invoice_id}
- Vendor Account Changes
GET /vendor/account-changes/batch/{batch_id}GET /vendor/{business_id}/profileGET /vendor/{business_id}/bank-detailsGET /vendor/{business_id}/licenseGET /vendor/{business_id}/tax-id
Use the environment_access.md host/port in the workspace root for the base URL. Do not guess alternative endpoint names.
2. Answer Schema Compliance
Every task ships an answer_template.json. Produce JSON that exactly matches the template keys and value types (arrays, objects, booleans, numbers, strings). Never add extra top-level keys. Observed required top-level structures:
| Task Type | Key Patterns |
|---|---|
| AP Claims | payable_claim_ids, blocked_claim_ids, paid_claim_ids, ap_open_balance_total, crm_required_claim_ids, batch_status, reviewed_claim_count |
| AP Stale Snapshot | eligible_claim_ids, not_ready_claim_ids, ap_balance_by_claim, stale_snapshot_corrections, close_log_required, batch_status |
| Onboarding | per_business, reportable_ubo_counts, hard_stop_flags, follow_up_business_ids, overall_release_ready |
| Prepaid Close | period, entity, selected_invoice_ids, account_rollup, invoice_results, default_missing_term_invoice_ids, exception_invoice_ids |
| Vendor Changes | task_id, batch_id, as_of_date, target_business_ids, decisions, bank_mismatch_ids, invalid_tax_ids, expired_license_ids, review_queue_ids, risk_score_override_flags |
3. Sorting & Ordering Rules
- All ID lists and object keys must be sorted lexicographically (alphabetical) unless the prompt explicitly specifies a processing order.
- Example arrays:
blocked_claim_ids,eligible_claim_ids,target_business_ids,follow_up_business_ids,selected_invoice_ids,default_missing_term_invoice_ids,exception_invoice_ids. - Example objects: keys inside
reportable_ubo_counts,hard_stop_flags,ap_balance_by_claim,stale_snapshot_corrections,decisions.
- Example arrays:
- For
per_businessarrays, sort entries bybusiness_idascending.
4. Rounding & Monetary Conventions
- Round all currency fields to 2 decimal places (e.g.,
1842.36,0.00,-290855.05). - Represent zero as
0.0or0.00consistently with the template example. - Do not truncate intermediate values unless specified; present final outputs with 2-decimal precision.
5. Finance & Control Decision Rules (Transferable Patterns)
AP / Claims Batches
- A claim is payable if its open AP balance is
> 0and it is not blocked by CRM. - A claim is paid if its status is already
paid(goes intopaid_claim_ids). - A claim is blocked if on CRM hold (
crm_required_claim_ids==blocked_claim_ids). batch_status:"blocked"if any claim is blocked.- Otherwise
"ready"or status derived from prompt rules.
reviewed_claim_count= total unique claims examined.
AP Stale Snapshot Reconciliation
- Cross-reference the stale CSV / snapshot against live
GET /ap/claims/batch/{batch_id}andGET /ap/open-balance. eligible_claim_ids: claims that are live-matched, approved, and have a legitimate balance.not_ready_claim_ids: claims that are void, unapproved, mismatched, or have zero balance.stale_snapshot_corrections: map every claim ID in scope to a canonical reason string (e.g.,block_unapproved_claim,ignore_void_bill,exclude_amount_or_vendor_mismatch,replace_with_matched_paid_bill,mark_in_flight_payment).close_log_required: object with booleanrequiredandidsarray of close log IDs (sorted) when corrections exist.batch_status: typically"needs_ap_refresh"when stale mismatches are found.
Onboarding / UBO Release
- For each business in the batch, fetch UBO screening and profile data.
reportable_ubo_counts: count of UBOs that meet the reportable threshold per jurisdiction.hard_stop_flags: list all applicable stop flags per business (e.g.,confirmed_pep,expired_license,vendor_on_hold,bank_name_mismatch,shell_company_suspected,bank_closed,screening_not_run,missing_required_documents). Sort the list lexicographically.- Decision logic:
- Any hard stop →
"escalate"or"awaiting_information"depending on missing-doc vs. confirmed-risk rules in prompt. - Clean + UBO thresholds met →
"approve".
- Any hard stop →
follow_up_business_ids: all businesses whose decision is not"approve".overall_release_ready:trueonly if all businesses are approved and no hard stops exist.
Prepaid Amortization Close
selected_invoice_ids: only invoices included in theclose-scoperesponse for the givenperiodandentity.- Per-invoice schedule (
GET /finance/prepaid/amortization-schedule):- Extract
march_amortization(or period-specific amortization),cumulative_amortization_through_march, andending_balance. default_missing_term_flag:truewhen the schedule uses a fallback term because the original term is missing.exception_flag:truefor invoices that trigger control exceptions (e.g., ending balance mismatch, missing term, duplicate, or out-of-sequence amortization).
- Extract
account_rollup:- Sum
selected_invoice_count,original_amount_total,march_amortization_total,cumulative_amortization_through_march. schedule_ending_balance= sum of invoice ending balances for that account.gl_ending_balancecomes from the close-scope GL snapshot.variance_amount=schedule_ending_balance - gl_ending_balance.variance_flag:trueifvariance_amount != 0.has_default_missing_term_flag:trueif any invoice in the account has the flag.account_status:"requires_reconciliation"whenvariance_flagistrueor missing-term flags exist; otherwise"ok"per prompt rules.
- Sum
Vendor Account Change Batch
- For each
business_idin the batch payload, compare:bank-detailsvs. change request →bank_mismatch_ids.tax-idvalidity →invalid_tax_ids.licenseexpiration vs.as_of_date→expired_license_ids.- Risk-score overrides →
risk_score_override_flags.
- Decisions:
"release"only when zero mismatches, valid tax, valid license, and no risk override."hold"for bank mismatches or risk overrides without disqualifying tax/license issues."escalate"for invalid tax IDs, expired licenses, or combined severe flags.
review_queue_ids: union of all businesses that are not"release".
6. Pitfalls
- Do not omit zero-balance entries in
ap_balance_by_claim; include every claim in scope with its exact live balance. - Do not invent endpoint names — copy them verbatim from the prompt and
environment_access.md. - Ensure lexicographic sort on every list and every object key before emitting JSON; unsorted output fails validation even if values are correct.
- Prepaid ending balance may legitimately be
0.01due to rounding; treat it as non-zero and do not round to zero. - Hard-stop flags must be sorted internally per business; missing this causes array-mismatch failures.
- Batch status strings are lowercase snake_case (e.g.,
blocked,needs_ap_refresh,ready). Match exactly. - Do not include test-specific answer values in the skill — this SOP is for future solvers; keep rules generic.
7. Execution Checklist
- Read
prompt.txtand identify the exact API calls. - Read
answer_template.jsonto lock the required output schema. - Call endpoints in the order dictated by dependencies (e.g., fetch batch list first, then per-item details).
- Apply control rules, sort all IDs/keys, round money to 2 decimals.
- Validate that no extra keys were added and all required keys are present.
- Write final JSON to
answer.json.