Data AnalyticsReliable reporting automation

Create a report manifest with timestamps and row counts

PK
Pankit Kumar
Sr. Data Scientist at Parexel (a Goldman Sachs–backed company) · 20 September 2026 · 3 min read
Technically reviewed by Ishaan Sharma
In this article (6 sections)

A report manifest is a compact record of what produced a report and which files belong to it. It should let a reviewer identify the source snapshot, configuration, code, runtime, quality counts and output artifacts without reverse-engineering a spreadsheet filename.

Keep analytical facts separate from operational timestamps. “Generated today” does not mean the report contains today's data.

Record the evidence needed to reproduce the result

The original automation lab produces a bundle with three files: selected event rows, a metrics JSON and a manifest JSON.

The manifest records the run ID, source-data hash, source-manifest hash, configuration hash, pipeline-code hash, Python version, output hashes, creation time and preparation status. The metrics file records the reporting period, event watermark, extraction time, raw and unique counts, replay count and selected totals.

Those responsibilities are intentionally linked: the manifest's checksum identifies the exact metrics file containing the counts. A useful manifest need not duplicate every metric if it reliably references the artifact that contains it.

Inspect and verify a generated bundle

python
import json
from pathlib import Path
from tempfile import TemporaryDirectory
from pipeline import run,verify_bundle,digest

config = json.loads(Path('report-config.json').read_text())
with TemporaryDirectory(prefix='report-manifest-example-') as temporary:
    folder,created = run('events.csv','source-manifest.json',config,temporary)
    manifest = verify_bundle(folder)
    metrics = json.loads((folder/'metrics.json').read_text())
    assert manifest['run_id']==folder.name
    assert manifest['status']=='prepared_for_review'
    assert manifest['distribution']=='not_sent'
    assert manifest['outputs']['metrics.json']==digest((folder/'metrics.json').read_bytes())
    assert (metrics['raw_rows'],metrics['unique_events'],metrics['identical_replays'],metrics['selected_events'])==(7,6,1,3)
    assert metrics['amount_paise']==3500 and metrics['amount_unit']=='paise'
    assert metrics['period_end']=='2026-01-12T00:00:00Z'
    assert metrics['extracted_at']=='2026-01-12T01:00:00Z'
    print({'run_id':manifest['run_id'],'counts':{key:metrics[key] for key in (
        'raw_rows','unique_events','identical_replays','selected_events')},
        'status':manifest['status'],'distribution':manifest['distribution']})

Seven raw rows become six unique events after one identical replay is removed. Three paid events fall inside the configured period. These counts explain the transformation; a single final row count would not.

Name timestamps by the event they describe

The reporting period ends at January 12 midnight. The source is extracted at 01:00. The bundle is generated whenever this example runs. Those times can legitimately differ by months when reproducing a historical report.

Do not update the historical period or source extraction time to the current time simply to make a freshness indicator look recent. Use creation time to describe the artifact, and source-related times to describe the evidence.

The source watermark has a different meaning again: it is the source's declared event-time coverage. Its reliability depends on the upstream contract, not on the manifest field merely existing.

Treat hashes as integrity evidence with limits

Python's hashlib documentation provides the digest primitives. The lab uses SHA-256 to identify exact bytes and detect changes against recorded expectations.

A hash is not a human approval, an authenticity signature or proof of source completeness. Someone with write access to both data and manifest can replace both. Protect the storage and use stronger provenance or signing when the deployment requires it.

Likewise, the recorded Python version is useful but does not capture every environmental dependency in a more complex application. This lab uses the standard library. A package-based pipeline should record its relevant dependency lock or environment evidence too.

Make status describe an actual completed step

The bundle is prepared for review and not sent. It is not labeled approved merely because all automatic checks pass. If a later human approval exists, record it as separate evidence bound to the exact artifact version.

Avoid mutable filenames such as final_latest_really_final.xlsx as the only history. A readable title can coexist with a stable run identity and an explicit pointer to the currently selected version.

Exercise: edit the selected-events CSV after generation and verify that bundle validation fails. Then explain how an approved manifest would need to bind the reviewer decision to the original bytes rather than to a reusable filename.

NeuraPath's Data Analytics with Generative AI course connects reproducible scripting with audit-friendly reporting. A useful manifest makes the report's evidence and status inspectable without claiming more assurance than the checks provide.

Continue learning

This article is part of the Reliable reporting automation sequence. Use the neighbouring tasks when you need the prerequisite or the next application.

PK
Pankit Kumar
Lead Instructor, NeuraPath Academy

Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.

This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.

Explore Data Analytics with Generative AI
Counselling is free · no obligation

Not sure which programme fits?

Tell us your background and we will map it to the right entry point — including saying so when a cheaper programme is the better fit. A counsellor replies within one working day.