target-revenue/specs/TargetLedgerSpecification.md
tegwick 8da3c6b3de Fix stale administrative-correction reference in TargetLedgerSpecification §5
Found while preparing WP-0003-T06 for review: §5's prose still named the
unsplit administrative-correction type (renamed to
administrative-correction-development/-remission earlier this session) and
incorrectly implied both admin-correction types require a reverses
pointer, when only credit-reversal and remission-correction do.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 19:49:51 +02:00

77 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Target Ledger Specification (Normative Extract)
**Document version:** TRF-Ledger-0.1
**Status:** Normative extract, Stage 0
**Extracted from:** `specs/TargetRevenueLicenseConcept.md` §17 and `specs/TechnicalSpecificationDocument.md` §3.2
**Machine-readable counterpart:** `schemas/ledger_entry.schema.json` — implemented and tested under `workplans/TREV-WP-0002-trust-service-foundation.md` T03 (`src/target_revenue/hashing.py`, `src/target_revenue/fold.py`). This document is the prose normative reference; the schema and library are the authoritative machine-checkable implementation.
---
## 1. Purpose
The Target Ledger is the append-only record of everything that moves a Phase's Outstanding Target. It is the sole input, together with the Phase Manifest, to the Outstanding Target fold and therefore to Conversion Event detection (`specs/TargetRevenueFrameworkCore.md` §1.7§1.8).
## 2. Entry types (closed set)
| Type | Effect on fold | Notes |
|---|---|---|
| `development-credit` | `+= amount` to Development Credit | Rule 4: normally arises only from settled payments. |
| `remission-credit` | `+= amount` to Remission Credit | Rule 5: never represented as revenue. |
| `credit-reversal` | `-= amount` from Development Credit | Rule 8: compensating entry; requires `reverses` pointing to the original entry id. Never edits or deletes the original. |
| `remission-correction` | `+= amount` to Remission Credit (amount may be negative) | Requires `reverses`. |
| `administrative-correction-development` | `+= amount` to Development Credit | Generic correction on the development side, not tied to a specific prior credit entry. |
| `administrative-correction-remission` | `+= amount` to Remission Credit | Generic correction on the remission side, not tied to a specific prior remission entry. |
| `conversion-checkpoint` | No numeric effect | Marker only. |
**Resolved 2026-07-29:** the concept document (§17) lists a single, non-exhaustive `administrative-correction` entry type ("permitted entry types **may include**...") without specifying which side of the target it adjusts. This extract specializes it into the two typed entries above, closing that ambiguity in the type name itself rather than leaving it as an unstated fold-side default. This does not contradict the concept document — its list was illustrative, not a closed enum — but it is a Stage 0 interpretation this extract adds beyond direct citation, so it remains listed for `workplans/TREV-WP-0003-normative-core-extraction.md` T06 review alongside the rest of this file.
This set is closed for Stage 0: a project **must not** invent new entry types; new monetization behavior belongs in an extension (`specs/MonetizationExtensionSpecification.md`), not a new ledger entry type.
## 3. Required entry fields
| Field | Type | Notes |
|---|---|---|
| `id` | string (URN `trsl:entry:<id>`) | Globally unique, monotonically orderable. |
| `phase` | string (Phase URN) | Must reference a published Phase Manifest. |
| `type` | enum (§2) | |
| `amount` | decimal | Sign convention per §2. |
| `currency` | ISO 4217 code | **Must match** the Phase's `initial_target.currency` (working default Q6). No FX conversion in the pure fold; a currency mismatch is rejected, not converted. |
| `recognized_at` | ISO 8601 timestamp | Settlement time, not invoice time (Rule 4; working default Q10: `payment-settled` recognition only). |
| `extension.id` / `extension.version` | string / string | Required for `development-credit` / `remission-credit`: identifies the monetization profile or degeneration policy that produced the entry. |
| `evidence_reference` | URI (`confidential:` scheme allowed) | Tiered per working default Q10 (E0 opaque id / E1 settled payment reference / E2 contract+invoice+settlement). |
| `previous_entry_hash` | hex-64 or literal `GENESIS` | SHA-256 of the prior entry's canonical serialization for this Phase (§4). |
| `signature` | string | Ed25519 signature over the canonical serialization (working default Q14); optional in Stage 0 fixtures, required for any public claim. |
| `reverses` | string (entry URN) | Required on `credit-reversal` and `remission-correction`. |
## 4. Hash chain and canonical serialization
**Working default (Q14), accepted via ADR-0001:** canonical serialization is JSON with sorted keys, no insignificant whitespace, UTF-8 encoding, excluding the `signature` and `previous_entry_hash` fields themselves. The chain hash is SHA-256 over that serialization. The first entry for a Phase has `previous_entry_hash: GENESIS`; every subsequent entry's `previous_entry_hash` must equal the SHA-256 digest of the immediately preceding entry's canonical bytes.
Reference implementation: `src/target_revenue/hashing.py::entry_hash`, `verify_chain`.
## 5. Corrections without erasure
Per Rule 8, the ledger is append-only. A correction or reversal is always a **new** entry — `credit-reversal` and `remission-correction` reference the entry they correct via `reverses`; `administrative-correction-development` and `administrative-correction-remission` are generic corrections not tied to a specific prior entry (§2) — never an edit or deletion of the original. This preserves the audit trail even when the correction is disputed.
## 6. Outstanding Target fold (normative definition)
```text
Outstanding Target = max(0, Initial Target Σ(development-credit, administrative-correction-development)
Σ(remission-credit, remission-correction, administrative-correction-remission)
+ Σ(credit-reversal))
```
Equivalently, per entry type effect in §2, folded left-to-right over the Phase's entries in ledger order. The fold is **pure**: identical `(Initial Target, entries)` input always yields identical output, with no hidden state (TSD §6.1). Reference implementation: `src/target_revenue/fold.py::fold_outstanding_target`.
The fold **must** be independently reproducible by any conformant external tool from the Phase Manifest and Target Ledger alone — no Trust Service state is required (PRD NFR-1).
## 7. Currency consistency rule
Working default Q6: every entry's `currency` must equal the Phase's `initial_target.currency`. A mismatch is rejected outright in Stage 0; there is no FX conversion step in the pure fold. A future FX extension may be registered, but until then multi-currency Phases are out of scope. Reference implementation: `src/target_revenue/validation.py::check_currency_consistency`.
## 8. Not covered here
- Phase Manifest fields: `specs/PhaseManifestSpecification.md`.
- Extension contract fields referenced by `extension.id`/`extension.version`: `specs/MonetizationExtensionSpecification.md`.
- Conversion Attestation document schema: `specs/TechnicalSpecificationDocument.md` §3.5 (a dedicated extract is not yet planned; the TSD section remains authoritative).
- Signature key management and rotation: working default Q14 notes an append-only key history document; not yet specified in a dedicated file.