target-revenue/schemas/ledger_entry.schema.json
tegwick 2b675c11ad Split administrative-correction into typed development/remission corrections
Resolves the WP-0003-T06 review flag: the single administrative-correction
ledger entry type had an unstated fold-side effect (concept §17 names the
type but never says which side of the target it corrects). Maintainer chose
option (a) — split into administrative-correction-development and
administrative-correction-remission so the corrected side is explicit in
the type name rather than an implicit library default.

- schemas/ledger_entry.schema.json: enum split, no other behavior change.
- src/target_revenue/fold.py: each new type maps to its named side only.
- specs/TargetLedgerSpecification.md, TechnicalSpecificationDocument.md
  §3.2, ProductRequirementsDocument.md FR-5: updated to the split types.
- tests/test_ledger_fold.py: dedicated coverage for both new types plus a
  regression test that the old unsplit type name is now rejected.

spec/TargetRevenueLicenseConcept.md §17 is left unedited — its entry-type
list is explicitly non-exhaustive ("may include"), so this specializes
rather than contradicts it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 09:16:22 +02:00

109 lines
3.7 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://target-revenue.example/schemas/ledger_entry.schema.json",
"title": "Target Ledger Entry",
"description": "Stage 0 schema per specs/TechnicalSpecificationDocument.md §3.2 and specs/OpenQuestions-WorkingDefaults.md Q6/Q10/Q14. Append-only; corrections are new compensating entries, never mutation.",
"type": "object",
"required": [
"id",
"phase",
"type",
"amount",
"currency",
"recognized_at",
"evidence_reference",
"previous_entry_hash"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"pattern": "^trsl:entry:[a-zA-Z0-9]+$",
"description": "Globally unique, monotonically orderable (ULID or equivalent)."
},
"phase": {
"type": "string",
"pattern": "^trsl:phase:[a-zA-Z0-9._-]+$"
},
"type": {
"type": "string",
"enum": [
"development-credit",
"remission-credit",
"credit-reversal",
"remission-correction",
"administrative-correction-development",
"administrative-correction-remission",
"conversion-checkpoint"
],
"description": "Closed set per TSD §3.2; not extensible per-project. administrative-correction-development/-remission split 2026-07-29 to make the corrected target side explicit in the type name (specs/TargetLedgerSpecification.md §2)."
},
"amount": {
"type": "number",
"description": "Positive for credits; the fold interprets sign by entry type (see fold.py). Reversal/correction entries reduce their target's cumulative total."
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"description": "Must match the Phase's initial_target.currency (working default Q6). No FX conversion in the pure fold."
},
"recognized_at": {
"type": "string",
"format": "date-time",
"description": "Settlement time, not invoice time (Rule 4 / working default Q10 payment-settled)."
},
"extension": {
"type": "object",
"description": "Required for development-credit/remission-credit entries.",
"required": ["id", "version"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"pattern": "^trsl:(extension|policy):[a-zA-Z0-9._-]+$"
},
"version": { "type": "string" }
}
},
"evidence_reference": {
"type": "string",
"description": "URI, may use the confidential: scheme. Tiering per working default Q10 (E0/E1/E2)."
},
"previous_entry_hash": {
"type": "string",
"pattern": "^[a-f0-9]{64}$|^GENESIS$",
"description": "SHA-256 hex digest of the previous entry's canonical serialization for this Phase, or the literal GENESIS for the first entry."
},
"signature": {
"type": "string",
"description": "Ed25519 signature over the canonical serialization (working default Q14). Optional in Stage 0 fixtures, required for any public claim."
},
"reverses": {
"type": "string",
"pattern": "^trsl:entry:[a-zA-Z0-9]+$",
"description": "Required on credit-reversal and remission-correction entries: the entry id being reversed or corrected."
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "credit-reversal" } }
},
"then": { "required": ["reverses"] }
},
{
"if": {
"properties": { "type": { "const": "remission-correction" } }
},
"then": { "required": ["reverses"] }
},
{
"if": {
"properties": {
"type": { "enum": ["development-credit", "remission-credit"] }
}
},
"then": { "required": ["extension"] }
}
]
}