expense-transaction-extraction¶
expense-transaction-extraction0.1.0noneTags: cost-allowability post-award expense extraction federal-grants research-administration
Audience: post-award-staff, sponsored-programs-staff, grant-accountants
Manifestations in repo: prompt.md
Normalizes one expense — receipt, invoice, purchase order, p-card line, or general-ledger detail — into a single structured transaction record covering date, vendor, amount, account coding, description, and documentation status. It is the input-normalization step of the federal cost-allowability analysis workflow.
Output contract: schema.json
Contract scope: repo-local
Inputs¶
Expense documentation for a single charge — a receipt, vendor invoice, purchase order, procurement-card statement line, or general-ledger detail row — as pasted text, an attachment, or analyst notes. Reviewer questions may be included and are carried into notes.
Outputs¶
A single JSON object — see schema.json — with the transaction's identifying and accounting fields. Missing scalars are null; missing lists are empty arrays. The component does not assess allowability.
Contract scope¶
Repo-local. The expense record is a prompt-library normalization contract consumed by the downstream cost-allowability check components. It is not a shared AI4RA-UDM schema, though its fields align to sponsored-project transaction semantics (vendor, amount, account coding, period).
Triad integration¶
- Evaluation datasets: none yet — repo-local synthetic coverage planned.
- Harness notes: canonical manifestation is
prompt.md; validation surface isschema.json. Invoked as a Step 1 task of thecost-allowability-analysisworkflow. - Shared UDM relationship: aligned to sponsored-project transaction semantics; does not define or depend on a shared UDM schema.
Manifestations¶
prompt.md— canonical, LLM-agnostic prompt
Evals¶
See evals/.
Provenance¶
Created 2026-05-21 as the input-normalization component of the federal cost-allowability analysis component set.
Contract scope¶
-
Output format:
json_object -
Contract scope:
repo_local_normalization_contract -
Validation surfaces:
json_schema -
Schema entrypoints:
# -
Notes: Repo-local single-expense transaction record normalized from receipt, invoice, purchase-order, p-card, or general-ledger evidence. Input-normalization contract for the cost-allowability analysis workflow; not a shared AI4RA-UDM schema.
-
Machine-readable catalog entry:
component_catalog.json
Triad integration¶
-
UDM alignment:
repo_local_normalization_contract— Fields align to sponsored-project transaction semantics (vendor, amount, account coding, period) but the record is a prompt-library normalization contract, not a shared UDM schema. -
Evaluation datasets: no shared
evaluation-data-setscatalog entry recorded yet; current references are repo-local eval artifacts. -
Harness notes: Validate JSON output against schema.json. Canonical invocation surface is prompt.md. Invoked as a Step 1 task of the workflows/cost-allowability-analysis Vandalizer workflow.
-
Related component:
regulated-activity-classifier(provides_input_to) — The normalized expense record is the classifier's primary input.
Prompt body¶
Source: prompt.md.
Show prompt
Expense Transaction Extraction¶
Purpose: Normalize one expense — from a receipt, invoice, purchase order, p-card line, or general-ledger detail — into a single structured transaction record.
Expected input: Expense documentation as pasted text, an attachment, or analyst notes.
Expected output: One JSON object conforming to
schema.json.
This component is the input-normalization step of the federal cost-allowability analysis workflow. It does not judge allowability — it produces the clean expense record that the downstream check components consume.
Prompt¶
You are a research-administration expense-extraction assistant. Read the supplied expense documentation and emit exactly one structured expense-transaction record.
Return only a single JSON object. Do not emit prose, Markdown, comments, or code fences.
What to extract¶
Populate every field defined by the schema:
-
expense_id— an analyst or file reference for this expense, when one is supplied. -
source_document— what the record was read from (e.g., "vendor invoice #4471", "p-card statement line", "GL detail export"). -
transaction_date— the date the cost was incurred (purchase date or service date), quoted in the document's format. -
vendor— the supplier, payee, or merchant. -
description— what was purchased or paid for, in the document's words. -
amount— the charge as a JSON number: no quotes, no currency symbol, no thousand separators. "$1,250.00" becomes 1250.00. -
currency— the ISO currency code; default "USD" when the document does not state otherwise. -
gl_account— the general-ledger account or object code. -
cost_code— the project, fund, grant, or activity code the charge was booked to. -
quantity— units purchased, when stated. -
invoice_reference— invoice, purchase-order, or requisition number. -
documentation_on_hand— the supporting records actually supplied with the expense (e.g., "itemized receipt", "invoice", "approval email"). Empty array when none are present. -
purchaser— the person who incurred or requested the charge. -
project_role— that person's role on the project, when stated (e.g., "PI", "graduate student", "lab manager"). -
expense_category_hint— the apparent cost category if it is obvious from the description (e.g., "Travel", "Supplies", "Equipment"); null when not obvious. This is a hint only; category determination is a downstream step. -
notes— anything else the reviewer should know, including reviewer questions carried in the input.
Rules¶
-
One transaction. If the documentation covers several distinct charges, extract the primary charge and record the others briefly in
notes. -
No fabrication. Use null for any scalar the documentation does not state and an empty array for any absent list. Never infer an amount, date, vendor, or account code that is not in the source.
-
Verbatim where it matters. Quote dates and account codes as the document presents them; do not reformat or "correct" them beyond the numeric encoding rule for
amount. -
Stay neutral. Do not comment on whether the expense is allowable, reasonable, or in budget. That is the job of the downstream check components.
Produce the JSON object now.
Output schema¶
Source: schema.json.
Show schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/AI4RA/prompt-library/components/expense-transaction-extraction/schema.json",
"title": "Expense Transaction Extraction \u2014 Output",
"description": "Structured single-expense transaction record normalized from receipt, invoice, purchase-order, p-card, or general-ledger evidence. Input-normalization contract for the federal cost-allowability analysis workflow.",
"version": "0.1.0",
"type": "object",
"additionalProperties": false,
"required": [
"transaction_date",
"vendor",
"description",
"amount",
"currency",
"documentation_on_hand"
],
"properties": {
"expense_id": {
"type": [
"string",
"null"
],
"description": "Analyst or file reference for this expense."
},
"source_document": {
"type": [
"string",
"null"
],
"description": "What the record was read from (invoice number, GL line, p-card statement, etc.)."
},
"transaction_date": {
"type": [
"string",
"null"
],
"description": "Date the cost was incurred, quoted in the document's format."
},
"vendor": {
"type": [
"string",
"null"
],
"description": "Supplier, payee, or merchant."
},
"description": {
"type": [
"string",
"null"
],
"description": "What was purchased or paid for, in the document's words."
},
"amount": {
"type": [
"number",
"null"
],
"description": "Charge amount as a JSON number with no currency symbol or thousand separators."
},
"currency": {
"type": "string",
"minLength": 1,
"description": "ISO currency code. Defaults to USD when the document does not state otherwise."
},
"gl_account": {
"type": [
"string",
"null"
],
"description": "General-ledger account or object code."
},
"cost_code": {
"type": [
"string",
"null"
],
"description": "Project, fund, grant, or activity code the charge was booked to."
},
"quantity": {
"type": [
"string",
"null"
],
"description": "Units purchased, when stated."
},
"invoice_reference": {
"type": [
"string",
"null"
],
"description": "Invoice, purchase-order, or requisition number."
},
"documentation_on_hand": {
"type": "array",
"description": "Supporting records supplied with the expense. Empty array when none.",
"items": {
"type": "string",
"minLength": 1
}
},
"purchaser": {
"type": [
"string",
"null"
],
"description": "Person who incurred or requested the charge."
},
"project_role": {
"type": [
"string",
"null"
],
"description": "That person's role on the project, when stated."
},
"expense_category_hint": {
"type": [
"string",
"null"
],
"description": "Apparent cost category when obvious from the description; null otherwise. Advisory only."
},
"notes": {
"type": [
"string",
"null"
],
"description": "Other reviewer-relevant detail, including reviewer questions and any secondary charges."
}
}
}
Changelog¶
Source: CHANGELOG.md.
All notable changes to this component. Versions follow semver: MAJOR for output-contract breaks, MINOR for backward-compatible additions, PATCH for wording or clarity.
[0.1.0] — 2026-05-21¶
- Initial experimental release.
- Structured single-expense transaction record: identifying fields, accounting codes, documentation inventory, and an advisory category hint.
amountis a JSON number;documentation_on_handis a string array; absent scalars are null.- No eval cases yet — status
experimentaluntil at least one golden extraction is added underevals/cases/.