# Audit & traceability

## Link to operations

Financial artifacts should be joinable to operational artifacts without ambiguity:

| Accounting artifact | Typical operational anchor |
| --- | --- |
| Journal entry | Batch run id, document id, or event id |
| Journal line | Granular source line (e.g., PO line, movement id, invoice line) when posting granularity supports it |

Prefer **stable external identifiers** (UUIDs or immutable numeric ids) over mutable business keys for linkage fields.

## Correlation ID propagation

- **Correlation ID** threads through orchestration (inventory, sales, exports, etc.) and should be **copied into journal entry metadata** when posting is triggered by a traced workflow.
- Same correlation ID may tie **multiple** ledger entries (e.g., split recognition across accounts) but must not tie unrelated tenants or unrelated source documents.

## Audit narrative

Auditors and support engineers should be able to answer:

1. **What operation** caused this journal line?
2. **Which posting rule version** mapped it?
3. **Who / what process** posted it, and **when**?

Immutable ledger rows plus append-only operational movements satisfy **non-repudiation** when combined with application audit logs (authentication and authorization events remain separate but complementary).

## Reflection-layer stance

Accounting explains and aggregates economic substance **after** operational facts exist. Traceability is **downstream clarity**, not upstream control of inventory or fulfillment state.

---

## Journal entry linkage to operations

Every automated journal entry produced from operations should persist:

| Stored field | Requirement |
| --- | --- |
| `tenant_id` | Same tenant as source movement/receipt |
| `source_system` | Emitting module (e.g., inventory, procurement) |
| `source_type` | Event or document type at commit time |
| `source_id` | Immutable id of the operational commit (receipt id, fulfillment id, transfer completion id) |
| `idempotency_key` | Full key string as defined in `posting-idempotency.md` |
| `posting_rule_version` | Mapping/rule set version used for the lines |

**Journal lines** should repeat `source_*` at line granularity when the operation splits across accounts (e.g., COGS vs inventory) so auditors can tie **each line** back without guessing splits.

Manual journals (adjustments, period close) use **`source_type = manual_adjustment`** (or equivalent) and **approval metadata**; they do not replace operational linkage for automated flows.

---

## End-to-end trace

A complete trace answers one chain of questions with **no dead ends**:

1. **Operational artifact** — receipt, fulfillment, transfer, return (immutable id and revision history if applicable).
2. **Domain event / posting command** — correlation ID and idempotency key from `posting-idempotency.md`.
3. **Posting pipeline** — worker id, attempt count, outcome timestamp (`posting-pipeline.md`).
4. **Journal entry** — header id, period, currency, rule version.
5. **Journal lines** — accounts, dimensions, amounts, linkage to source line ids where modeled.

**Reverse navigation** must work: from **journal line** → source operation → related documents (PO, SO, shipment) via stable ids and correlation ID.

**Traceability > convenience:** shortcuts that omit `source_id` or reuse ambiguous keys are unacceptable for production automated posting.
