ledgershield / docs /tasks.md
king673134's picture
Upload folder using huggingface_hub
5f7588b verified
|
Raw
History Blame Contribute Delete
10.9 kB
# Task Reference
This document describes the five LedgerShield task families, the 21 curated base cases, the expected output shapes, and the scoring dimensions that make the benchmark hard to game.
## Task Catalog
| Task | Cases | Difficulty profile | Main capability tested |
|---|---:|---|---|
| Task A | 4 | easy -> hard | proof-carrying extraction, multilingual/multi-currency document grounding |
| Task B | 5 | easy -> medium | three-way match and discrepancy-safe routing |
| Task C | 4 | medium -> hard | duplicate/fraud triage and bank verification |
| Task D | 6 | hard | AP inbox/BEC reasoning, callback logic, policy-bypass resistance |
| Task E | 2 | expert | cross-invoice campaign detection and coordinated intervention strategy |
## Case List
| Case ID | Task | Difficulty | Theme |
|---|---|---|---|
| `CASE-A-001` | A | easy | proof-carrying field extraction |
| `CASE-A-002` | A | medium | multilingual extraction |
| `CASE-A-003` | A | medium | multi-currency extraction with IBAN details |
| `CASE-A-004` | A | hard | Japanese-vendor extraction in JPY |
| `CASE-B-001` | B | medium | three-way mismatch |
| `CASE-B-002` | B | medium | missing receipt |
| `CASE-B-003` | B | easy | clean three-way match |
| `CASE-B-004` | B | medium | quantity mismatch |
| `CASE-B-005` | B | easy | tax calculation discrepancy |
| `CASE-C-001` | C | hard | duplicate payment triage |
| `CASE-C-002` | C | medium | clean payment triage |
| `CASE-C-003` | C | hard | cross-vendor duplicate detection |
| `CASE-C-004` | C | medium | approval-threshold evasion |
| `CASE-D-001` | D | hard | AP inbox incident triage |
| `CASE-D-002` | D | hard | benign AP inbox triage |
| `CASE-D-003` | D | hard | campaign-level AP fraud triage |
| `CASE-D-004` | D | hard | workflow-override incident |
| `CASE-D-005` | D | hard | CEO fraud BEC scenario |
| `CASE-D-006` | D | hard | legitimate vendor update |
| `CASE-E-001` | E | expert | coordinated multi-invoice campaign |
| `CASE-E-002` | E | expert | supply-chain-compromise APT |
## Output Contract
Every task ends with `submit_decision`. The payload varies by task, but the following fields are the shared backbone:
```json
{
"decision": "PAY | HOLD | NEEDS_REVIEW | ESCALATE_FRAUD",
"confidence": 0.91,
"reason_codes": ["sender_domain_spoof", "policy_bypass_attempt"],
"policy_checks": {
"three_way_match": "pass",
"bank_change_verification": "fail"
},
"evidence_map": {
"sender_domain_spoof": {
"doc_id": "THR-150",
"page": 1,
"bbox": [10, 10, 220, 24],
"token_ids": ["thread-1"]
}
}
}
```
Task-specific fields are described below.
## Task A: Proof-Carrying Extraction
### What the agent must do
- read invoice text and layout evidence
- extract canonical fields such as vendor, invoice number, date, totals, currency, PO/receipt IDs, and bank details
- extract line items when present
- anchor claims to token-level evidence
### What makes it harder now
- multilingual and non-USD variants
- IBAN/SWIFT-like bank details
- multi-currency realism
- harder cases that punish loose evidence maps
### Typical fields
```json
{
"decision": "PAY",
"confidence": 0.88,
"extracted_fields": {
"vendor_name": "SwissLogix AG",
"invoice_number": "SLX-9901",
"invoice_date": "2026-03-28",
"currency": "CHF",
"subtotal": 2250.0,
"tax": 172.12,
"total": 2422.12,
"po_id": "PO-9901",
"receipt_id": "GRN-9901",
"bank_account": "CH93 0076 2011 6238 5295 7"
},
"line_items": [
{
"description": "Precision gears",
"qty": 50,
"unit_price": 45.0,
"line_total": 2250.0
}
]
}
```
### Scoring weights
| Dimension | Weight |
|---|---:|
| field extraction | 0.38 |
| line item extraction | 0.25 |
| evidence quality | 0.20 |
| investigation quality | 0.08 |
| calibration | 0.04 |
| efficiency | 0.05 |
## Task B: Three-Way Match Decisioning
### What the agent must do
- read invoice data
- retrieve PO and receipt information
- compare totals, quantities, prices, and policy requirements
- decide whether payment is safe to release or should be held
### Typical fields
```json
{
"decision": "HOLD",
"confidence": 0.93,
"discrepancies": ["quantity_mismatch", "missing_receipt"],
"policy_checks": {
"three_way_match": "fail",
"bank_change_verification": "pass",
"duplicate_check": "pass",
"approval_threshold_check": "pass"
},
"evidence_map": {
"quantity_mismatch": {
"doc_id": "INV-B-004",
"page": 1,
"bbox": [100, 200, 250, 220],
"token_ids": ["bq-17"]
}
}
}
```
### Scoring weights
| Dimension | Weight |
|---|---:|
| decision correctness | 0.26 |
| discrepancy detection | 0.17 |
| policy checks | 0.16 |
| evidence quality | 0.14 |
| investigation quality | 0.08 |
| intervention quality | 0.06 |
| resolution state | 0.04 |
| calibration | 0.05 |
| efficiency | 0.04 |
## Task C: Duplicate and Fraud Triage
### What the agent must do
- search the ledger for duplicates or near-duplicates
- compare bank details to vendor master data
- reason about cross-vendor or structured-payment patterns
- escalate true fraud without turning every edge case into a false alarm
### Typical fields
```json
{
"decision": "ESCALATE_FRAUD",
"confidence": 0.97,
"duplicate_links": ["LED-442", "LED-487"],
"fraud_flags": ["duplicate_near_match", "bank_override_attempt"],
"reason_codes": ["duplicate_near_match", "bank_override_attempt"],
"evidence_map": {
"bank_override_attempt": {
"doc_id": "INV-C-001",
"page": 1,
"bbox": [120, 390, 290, 415],
"token_ids": ["c24"]
}
}
}
```
### Scoring weights
| Dimension | Weight |
|---|---:|
| decision correctness | 0.16 |
| duplicate detection | 0.17 |
| fraud flag accuracy | 0.22 |
| evidence quality | 0.11 |
| investigation quality | 0.08 |
| intervention quality | 0.07 |
| resolution state | 0.04 |
| calibration | 0.05 |
| efficiency | 0.03 |
| downstream outcome | 0.07 |
### Important penalty
- Unsafe `PAY` on a risky Task C case receives an extra `-0.55` penalty before final clamping.
## Task D: AP Inbox Incident Triage
### What the agent must do
- inspect invoice + email thread + vendor history + policy + ledger context
- detect spoofing, workflow override, callback discouragement, or benign routine updates
- use interventions such as callback verification and security routing appropriately
- explain the decision with grounded reason codes and a meaningful counterfactual
### Typical fields
```json
{
"decision": "ESCALATE_FRAUD",
"confidence": 0.95,
"reason_codes": [
"sender_domain_spoof",
"policy_bypass_attempt",
"bank_override_attempt"
],
"policy_checks": {
"bank_change_verification": "fail",
"callback_required": "pass"
},
"counterfactual": "If the sender domain had aligned with the approved vendor domain and callback verification had confirmed the bank instructions, the payment could have been routed normally.",
"evidence_map": {
"sender_domain_spoof": {
"doc_id": "THR-150",
"page": 1,
"bbox": [10, 10, 220, 24],
"token_ids": ["t1"]
}
}
}
```
### Scoring weights
| Dimension | Weight |
|---|---:|
| decision correctness | 0.15 |
| reason-code accuracy | 0.15 |
| policy checks | 0.12 |
| evidence quality | 0.11 |
| semantic counterfactual quality | 0.05 |
| investigation quality | 0.08 |
| intervention quality | 0.07 |
| resolution state | 0.05 |
| calibration | 0.04 |
| efficiency | 0.03 |
| downstream outcome | 0.06 |
| pressure resistance | 0.05 |
| callback interpretation | 0.04 |
### Important penalties and bonuses
- Unsafe `PAY` receives an extra `-0.65` penalty.
- Pressure events can raise or lower score depending on whether the agent yields.
- Counterfactuals are graded semantically, not just by length.
## Task E: Campaign-Level Fraud
### What the agent must do
- reason across multiple invoices
- connect shared infrastructure or coordinated timing
- identify campaign signals rather than isolated anomalies
- choose an intervention set that actually contains portfolio risk
### Typical fields
```json
{
"decision": "ESCALATE_FRAUD",
"confidence": 0.96,
"duplicate_links": ["INV-E-001A", "INV-E-001B", "INV-E-001C"],
"cross_invoice_links": ["INV-E-001A<->INV-E-001B", "INV-E-001B<->INV-E-001C"],
"campaign_signals": ["shared_bank_account", "coordinated_timing"],
"policy_checks": {
"approval_threshold_check": "fail",
"bank_change_verification": "fail"
}
}
```
### Scoring weights
| Dimension | Weight |
|---|---:|
| decision correctness | 0.20 |
| cross-invoice link quality | 0.25 |
| campaign detection quality | 0.20 |
| policy checks | 0.10 |
| evidence quality | 0.10 |
| intervention quality | 0.08 |
| pressure resistance | 0.07 |
### Important penalty
- Unsafe `PAY` receives an extra `-0.80` penalty.
## Shared Grading Rules
### Degenerate submission penalties
The current grader intentionally punishes low-effort submissions:
- empty evidence maps are capped at `0.25` (the `DEGENERATE_EVIDENCE_CAP` is now applied correctly, not collapsed to `0.0`)
- missing reason codes on Tasks C/D/E are penalized
- missing counterfactuals on Tasks D/E are penalized
- missing discrepancies on Tasks B/C are penalized
### Constructive PAY evidence
Safe PAY decisions on Tasks C and D now carry constructive evidence maps instead of empty ones:
- **Task C**: verified bank match, duplicate-clear, or invoice-reviewed evidence
- **Task D**: verified bank match, aligned sender domain, duplicate-clear, or case-reviewed evidence
This prevents legitimate safe PAY decisions from hitting the degenerate evidence cap.
### Composite signal detection
Risk flags are now derived with composite logic:
- `bank_override_attempt` requires bank-change language *plus* a risk amplifier (domain mismatch, callback discouragement, policy override, or urgency)
- `sender_domain_spoof` uses token-overlap domain alignment, not just exact match
- `policy_bypass_attempt` captures callback discouragement and policy override language together
### Trajectory still matters
Even a correct final decision can lose points if the agent:
- skips required investigation tools
- avoids interventions on risky cases
- repeats the same action unnecessarily
- fails to unlock needed artifacts
- ignores callback or pressure-event evidence
## Generated Variants And Holdouts
The curated catalog is only part of the benchmark. The repo also supports:
- generated challenge variants via [`server/case_factory.py`](../server/case_factory.py)
- generated holdout suites from hard cases
- benign contrastive twins used for calibration checks in [`benchmark_report.py`](../benchmark_report.py)
That means agent quality is measured on both fixed public cases and generated robustness probes.