⚙️ Autonomous detect 💬 Conversational explain

Record-to-Report Close Variance

SAP S/4HANABlackLineDatabricksOpenLineageTagetikServiceNow
1📋

Overview & business value

This agent finds and explains GL variances during the month-end close. Scheduled reconciliation rules flag accounts outside expected ranges; the agent then traces each variance to its source across the ledger and the data pipelines, reasons about whether it is a failed pipeline, a misposting or a genuine business change, and explains it to the controller in plain English with the evidence. It reads and reasons freely; a correcting journal or close-task action goes through an Action Ticket carrying a MOP.

Problem

The close is a stressful hunt. A GL account looks off and someone spends a day tracing whether it is a real business change, a misposting, or a broken data pipeline feeding the ledger. Restatements and late closes follow when the cause is found too late.

Solution approach

Scheduled controls flag accounts outside range (BlackLine / SAP). The agent traces the number back across the GL and the data pipelines (Databricks + lineage), classifies the cause, and explains it with evidence — bridging the finance number to the data that produced it.

Core capabilities

  • Reconciliation-rule variance detection
  • GL detail pull from SAP
  • Pipeline trace via Databricks + lineage
  • Cause classification (data / posting / real)
  • Plain-English controller explanation
  • Correcting-entry recommendation
  • Journal post via SAP BAPI (approval)
  • Tagetik flash + close-task update

How it helps

A faster, calmer close. Root cause of a variance in minutes, not days. Fewer restatements, and a clear bridge from the finance number to the data behind it — the cross-product story with the data platform.

Illustrative value model — plug in your own figures

↓ days
Close cycle reduction
A
Accounts auto-explained / close
↓ risk
Restatements avoided

Value = analyst days saved × rate × closes/year, plus reduced restatement and audit risk. Placeholders — substitute your baseline.

2📖

The story (for the sales conversation)

The one-liner

"At close, a number looks wrong and nobody knows if it's a real business change, a misposting, or a broken data feed. This agent traces it to the source in minutes and tells the controller exactly what happened — in plain English."

😣 Today, without the agent

It's day three of the close. Revenue account 410000 is $1.2M over forecast. Maria, the controller, doesn't know if the quarter genuinely beat plan or if something is wrong. She pulls GL detail, asks the data team if a pipeline changed, waits for answers, and re-checks postings — a full day gone before she even knows whether to trust the number. The close clock keeps running.

😌 The same morning, with the agent

The reconciliation control flags 410000. The agent traces the number: GL detail ties to the gold sales table; lineage shows a Databricks job whose join was changed last week now double-counts one region. It classifies the variance as a data error, not a business change, and tells Maria in plain English with the evidence — and recommends a correcting entry. She approves; the agent posts it and updates the Tagetik flash.

"It explains before it acts. It never posts a correcting journal on its own — it shows the controller the evidence and the recommended entry, and posts only on approval. The bridge from number to data is automatic."

The trust point — lead with this for the Controller and CFO org
1
The villain: the unexplained number

A variance with no known cause stalls the whole close.

2
The hero: trace to source

The agent bridges GL to the data pipeline and names the cause.

3
The reason to trust it

Correcting journals are reversible Action Tickets, posted only on approval.

💡How to use this tab: open here for the Controller/CFO org, tell the before/after, land the trust line, then show "Sample questions" and "Live scenarios". Keep Tools/Governance for the technical buyer.
3📥

Input data

Source systemField / entityTypePurpose
BlackLinereconciliation, variance flagobjectTrigger: account outside range
SAP S/4HANAGL balance, journal entriesobjectGL detail for the variance
Databrickspipeline run, source tableobjectData behind the GL load
OpenLineageupstream edgeslistTrace number to source
Tagetikconsolidation / flashobjectUpdate the flash post-fix
ServiceNowclose taskrecordTrack the variance to closure
ℹ️Developer note: trigger is a BlackLine reconciliation flag (or scheduled SAP GL range check) during the close window. The payload carries the account + period.
4⚙️

Processing flow (tools mapped per step)

ℹ️Each step shows its path and whether it is read-only or a write via Action Ticket.
1

Variance flagged deterministic

Reconciliation rules flag an account outside its expected range.

blackline.read · reconciliation flag
2

Pull GL detail deterministic

Read the GL balance and journal entries for the account and period.

sap.read · GL balance + journals
3

Trace to data source non-deterministic

Walk lineage from the GL load to the warehouse; query the pipeline run.

lineage.query → databricks.sqlQuery
4

Classify the cause non-deterministic

Reason: failed/changed pipeline vs misposting vs genuine business change.

reasoning over GL + pipeline evidence
5

Explain to controller non-deterministic

Plain-English explanation with the evidence chain and a recommendation.

teams.post · controller summary
6

Recommend correcting entry non-deterministic human approval

Draft the correcting journal; present for approval. Never posts unprompted.

draft journal → approval gate
7

Post correction deterministic Action Ticket

On approval, post the correcting journal via SAP BAPI.

sap.write · BAPI_ACC_DOCUMENT_POST (via ticket)
8

Update flash + close task deterministic Action Ticket

Refresh the Tagetik flash and update the ServiceNow close task; confirm reconciliation clears.

tagetik.dataPush · servicenow.incident (via ticket)
5🔧

Skills & tools (real connectors)

ℹ️Each tool maps to a real processorKey. Read tools are direct; writes only run inside an Action Ticket.
blackline.readRESTSOURCE
cpm.processors.BlackLineConnector
BlackLine close connector — journal entries, account reconciliation and intercompany via REST. OAuth 2.0.
{baseUrl}/api/v1/{resourcePath}
READ · direct
sap.readOData v4SOURCE
erp.processors.SAPS4HanaPull
Pulls GL balances and journal entries from SAP S/4HANA OData v4 services.
{baseUrl}/sap/opu/odata4/sap/{serviceName}/{entitySet}
READ · direct
sap.writeBAPI / RFCTRANSFORM
erp.processors.SAPBAPICall
Posts a correcting journal via BAPI_ACC_DOCUMENT_POST; parses bapiret2; commit/rollback.
BAPI_ACC_DOCUMENT_POST
WRITE · via Action Ticket
databricks.sqlQuerySQL API 2.0SOURCE
lakehouse.processors.DatabricksSQLQuery
Queries the warehouse to inspect the pipeline output behind the GL load. OAuth2 / PAT.
POST /api/2.0/sql/statements
READ · direct
lineage.queryOpenLineageSOURCE
governance.processors.LineageTracker
Tracks lineage edges to trace the GL number back to its source table and job.
upstream edges (read)
READ · direct
tagetik.scenarioRunREST · asyncSOURCE
cpm.processors.TagetikScenarioRun
Triggers Tagetik consolidation/forecast scenarios and pulls outputs. Async run-id tracking.
{"operation":"RunScenario|GetRunStatus|PullScenario"}
READ · direct
tagetik.dataPushREST / ODataSINK
cpm.processors.TagetikDataPush
Pushes budget/forecast/consolidation data (entity, account, period, scenario) into CCH Tagetik. Used to refresh the flash.
multi-dimensional fact records
WRITE · via Action Ticket
servicenow.incidentTable APISOURCE
itsm.processors.ServiceNowIncident
Tracks the variance as a close task via the Table API.
/api/now/v2/table/incident
WRITE · via Action Ticket
teams.postGraphSINK
collaboration.processors.TeamsSendMessage
Explains the variance to the controller in plain English with the evidence chain.
TeamsSendMessage · channel/chat
WRITE · via Action Ticket
⚠️Connectivity honesty: the correcting journal posts via the SAP BAPI path (BAPI_ACC_DOCUMENT_POST); there is no generic "post journal" sink. BlackLine and Tagetik are real CPM connectors (BlackLine read; Tagetik read via ScenarioRun, write via DataPush). Lineage trace uses LineageTracker.
6🤖

Agent prompt (production)

🤖 System prompt
You are the Record-to-Report Close Variance Orchestrator.

## Operating rules
1. Read/reason freely across SAP GL, BlackLine, Databricks and lineage.
2. You NEVER write directly. A correcting journal, flash refresh or close-task
   update is an Action Ticket carrying a MOP; ProcBot executes, Sherlock validates.
3. Deterministic for: reconciliation range checks, pulling GL detail, posting an
   approved correcting entry, updating the flash and close task.
4. Non-deterministic for: tracing a variance to its source, classifying the cause
   (failed pipeline vs misposting vs genuine business change), the explanation.
5. Human approval before: posting any correcting journal or blocking the close.
6. Always bridge the finance number to the data that produced it, with evidence.
   Never invent balances or journal amounts.

## Tools
READ (direct): blackline.read, sap.read, databricks.sqlQuery, lineage.query,
  tagetik.scenarioRun
WRITE (Action Ticket only): sap.write (BAPI_ACC_DOCUMENT_POST), tagetik.dataPush,
  servicenow.incident, teams.post

## Output (every step)
{ "decision":"...", "path":"deterministic | non-deterministic", "confidence":0.0,
  "action_ticket": { "mop":"...", "scope":"...", "approval":"auto | human" } | null,
  "evidence":[ { "tool":"...", "record":"..." } ], "message_to_user":"..." }
7🛡️

Execution governance — Action Ticket → MOP

No journal posting or flash change reaches a system from the model. The agent reasons and explains; an Action Ticket carries the MOP; ProcBot executes; Sherlock validates; the ticket is reversible. Posting a correcting journal or blocking the close requires human approval first.

1 · Reason

Agent classifies the variance and recommends a fix.

2 · Action Ticket

MOP id, scope, journal lines, approval level.

3 · ProcBot executes

Posts via SAP BAPI / refreshes Tagetik. Model never writes.

4 · Sherlock validates

Confirms the posting and that reconciliation clears; rolls back on failure.

{
  "action_ticket": "AT-8001",
  "mop": "MOP-GL-CORRECTING-ENTRY",
  "approval": "human",
  "target": { "tool": "sap.write", "processorKey": "erp.processors.SAPBAPICall" },
  "procedure": { "bapi": "BAPI_ACC_DOCUMENT_POST",
    "documentheader": { "comp_code":"1000", "doc_type":"SA", "pstng_date":"2026-05-31" },
    "accountgl": [ { "itemno":1, "gl_account":"410000", "amount":-1200000 },
                   { "itemno":2, "gl_account":"199999", "amount":1200000 } ] },
  "validation": { "owner":"sherlock", "expect":"bapiret2.TYPE in ['S'] && recon clears" },
  "reversible": true
}
8🔀

Data flow

flowchart TD A([Close: recon flags 410000]) --> B[Pull GL detail sap.read] B --> C[Trace to source lineage.query] C --> D[Inspect pipeline output databricks.sqlQuery] D --> E[Classify cause data / posting / real] E --> F[Explain to controller teams.post] F --> G{Correcting entry?} G -->|Yes| H[Human approval] H --> I{{MOP-GL-CORRECTING-ENTRY}} I --> J[BAPI_ACC_DOCUMENT_POST] J --> K{{MOP-FLASH-REFRESH}} K --> L[tagetik.dataPush + close task · recon clears] G -->|No, real change| M[Document as business change close task]
9🏗️

Systems touched

📒 BlackLine — reconciliation + variance flag
🟡 SAP S/4HANA — GL detail (read), correcting entry (write BAPI)
🔷 Databricks — pipeline output behind the GL load
🔗 OpenLineage — trace number to source
📊 Tagetik — consolidation flash refresh
🛠️ ServiceNow + Teams — close task + controller explanation
10🗄️

Mock data (seed to demo)

BlackLine flag
SAP GL detail
Lineage
Databricks query
Classification
// blackline.read reconciliation flag
{ "account":"410000", "name":"Revenue", "period":"2026-05",
  "actual":13200000, "expected":12000000, "variance":1200000, "status":"flagged" }
// sap.read GL 410000 journals (May)
{ "account":"410000", "balance":13200000,
  "loadSource":"DATABYTE_SALES_LOAD", "lastLoad":"2026-05-31T02:10:00Z" }
// lineage.query { target:"GL.410000", direction:"upstream" }
[ "gl_load:DATABYTE_SALES_LOAD", "table:gold.sales_daily", "job:daily_sales_etl" ]
// databricks.sqlQuery on gold.sales_daily (May)
{ "regions":["NA","NA","EU","APAC"],   // NA appears twice
  "note":"join change on 2026-05-24 duplicated NA region",
  "overstatement":1200000 }
// classification
{ "cause":"data_error", "detail":"NA region double-counted after a join change",
  "isBusinessChange":false, "recommendedFix":"correcting entry -1,200,000 + fix pipeline" }
11💬

Sample questions (conversational triggers)

The natural-language prompts this agent is built to answer. Each maps to the live scenarios below.

"Why is account 410000 off this month?"→ Scenarios 1–5
📉"What's driving the revenue variance in the May close?"→ Scenarios 3–4
🧭"Is this a real business change or a data error?"→ Scenario 4 (classification)
🔗"Trace the GL number back to its source."→ Scenario 3 (lineage)
✍️"Post the correcting entry."→ Scenarios 6–7 (approval + post)
🔄"Refresh the flash and close this item."→ Scenario 8
🎯 Recommended demo run
Seed the flagged account + the pipeline error, then ask "Why is account 410000 off this month?" — the agent pulls GL detail (2), traces lineage to the Databricks job (3), classifies it as a data error (4), explains to the controller (5), recommends + (on approval) posts the correcting entry (6–7), and refreshes the flash and close task (8). Scenarios 9–10 cover a genuine-business-change case and a misposting.
12🎬

Live scenarios (tool-execution traces)

ℹ️Ten end-to-end runs. Each step is a read (SOURCE), reasoning, an Action Ticket with a MOP, or an agent message.