Implement TREV-WP-0002 Stage 0 foundation: schemas, pure fold, golden Phase
Delivers the offline runnable specification foundation for the Trust Layer (TSD §3-§6), not a hosted Trust Service: - JSON Schemas for Phase Manifest, Ledger Entry, Extension Contract, and Conversion Attestation, encoding the Stage 0 working defaults (Q3 future license enum, Q6 single-currency Phases, Q8 required longstop_at). - src/target_revenue: pure Outstanding Target fold, SHA-256 hash-chain verification, Ed25519 signing helpers, extension conformance checks (including a core-term-redefinition heuristic), and conversion detection that never requires an attestation document to determine conversion status. - examples/phase-001: golden Phase package matching the concept doc's worked example, generated via scripts/generate_golden_phase.py so the hash chain is computed by the library itself, not hand-typed. - 32 passing pytest tests covering manifest/ledger/extension conformance, tamper/reorder detection, and the full lifecycle fold to conversion. - docs/adr/ADR-0001: proposed (not accepted) Stage 0 stack choice, per the WP-0002-T01 human-accept gate — implementation proceeded against the proposal as the workplan note permits, but the task stays open. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
658b1af00d
commit
57c7111cbc
28 changed files with 1751 additions and 7 deletions
52
schemas/conversion_attestation.schema.json
Normal file
52
schemas/conversion_attestation.schema.json
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://target-revenue.example/schemas/conversion_attestation.schema.json",
|
||||
"title": "Conversion Attestation",
|
||||
"description": "Stage 0 schema per specs/TechnicalSpecificationDocument.md §3.5. Evidence of conversion only — never a precondition for conversion status (PRD FR-7/G6, working default Q13). Tooling must be able to recompute conversion from the Phase Manifest and Target Ledger alone, without this document.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"phase",
|
||||
"milestone_release",
|
||||
"conversion_timestamp",
|
||||
"future_license",
|
||||
"final_development_credit",
|
||||
"final_remission_credit",
|
||||
"final_outstanding_target",
|
||||
"ledger_checkpoint"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"phase": {
|
||||
"type": "string",
|
||||
"pattern": "^trsl:phase:[a-zA-Z0-9._-]+$"
|
||||
},
|
||||
"milestone_release": {
|
||||
"type": "string",
|
||||
"description": "Must match phase.milestone_release.name in the Phase Manifest."
|
||||
},
|
||||
"conversion_timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The moment the ledger fold first reaches Outstanding Target = 0."
|
||||
},
|
||||
"future_license": {
|
||||
"type": "string",
|
||||
"enum": ["MIT", "Apache-2.0"]
|
||||
},
|
||||
"final_development_credit": { "type": "number", "minimum": 0 },
|
||||
"final_remission_credit": { "type": "number", "minimum": 0 },
|
||||
"final_outstanding_target": {
|
||||
"type": "number",
|
||||
"const": 0,
|
||||
"description": "MUST equal 0."
|
||||
},
|
||||
"ledger_checkpoint": {
|
||||
"type": "string",
|
||||
"description": "Points to the last ledger entry id or hash included in the fold."
|
||||
},
|
||||
"signature": {
|
||||
"type": "string",
|
||||
"description": "Ed25519 signature over the canonical serialization. Optional for Stage 0 fixtures."
|
||||
}
|
||||
}
|
||||
}
|
||||
92
schemas/extension_contract.schema.json
Normal file
92
schemas/extension_contract.schema.json
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://target-revenue.example/schemas/extension_contract.schema.json",
|
||||
"title": "Monetization Extension Contract",
|
||||
"description": "Stage 0 schema per specs/TechnicalSpecificationDocument.md §3.3. Structural conformance only — the semantic rule that allocation.rule may not redefine core terms is enforced in code (src/target_revenue/validation.py), not expressible in JSON Schema alone.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"version",
|
||||
"value",
|
||||
"pricing",
|
||||
"allocation",
|
||||
"recognition",
|
||||
"reversal",
|
||||
"evidence",
|
||||
"status"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^trsl:extension:[a-zA-Z0-9._-]+$"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+(\\.[0-9]+)*$"
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"required": ["description"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"description": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"pricing": {
|
||||
"type": "object",
|
||||
"required": ["method"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"method": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"allocation": {
|
||||
"type": "object",
|
||||
"required": ["rule"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"rule": { "type": "string", "minLength": 1 },
|
||||
"default_rate": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "Default development_allocation fraction, per canonical profile defaults (working default Q11)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"recognition": {
|
||||
"type": "object",
|
||||
"required": ["event"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"event": {
|
||||
"type": "string",
|
||||
"enum": ["order", "invoice", "payment-settled", "delivery"],
|
||||
"description": "Working default Q10: payment-settled only for Stage 0 fold inputs."
|
||||
}
|
||||
}
|
||||
},
|
||||
"reversal": {
|
||||
"type": "object",
|
||||
"required": ["rule"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"rule": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"type": "object",
|
||||
"required": ["requirement"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"requirement": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["registered", "canonical", "deprecated"],
|
||||
"description": "Assigned by Trust Service / maintainer review, not the extension author. canonical promotion is a documented human action (SCOPE §4)."
|
||||
}
|
||||
}
|
||||
}
|
||||
108
schemas/ledger_entry.schema.json
Normal file
108
schemas/ledger_entry.schema.json
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
"$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",
|
||||
"conversion-checkpoint"
|
||||
],
|
||||
"description": "Closed set per TSD §3.2; not extensible per-project."
|
||||
},
|
||||
"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"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
108
schemas/phase_manifest.schema.json
Normal file
108
schemas/phase_manifest.schema.json
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://target-revenue.example/schemas/phase_manifest.schema.json",
|
||||
"title": "Phase Manifest",
|
||||
"description": "Stage 0 schema per specs/TechnicalSpecificationDocument.md §3.1 and specs/OpenQuestions-WorkingDefaults.md Q3/Q6/Q8. Field names and semantics are authoritative from spec/TargetRevenueLicenseConcept.md §16.",
|
||||
"type": "object",
|
||||
"required": ["framework", "license", "phase"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"framework": {
|
||||
"type": "string",
|
||||
"description": "Framework version tag, e.g. TRF-0.1."
|
||||
},
|
||||
"license": {
|
||||
"type": "string",
|
||||
"description": "TRSL version tag, e.g. TRSL-0.1."
|
||||
},
|
||||
"phase": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"milestone_release",
|
||||
"initial_target",
|
||||
"future_license",
|
||||
"degeneration_policy",
|
||||
"longstop_at",
|
||||
"ledger"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^trsl:phase:[a-zA-Z0-9._-]+$",
|
||||
"description": "Globally unique, immutable once published."
|
||||
},
|
||||
"milestone_release": {
|
||||
"type": "object",
|
||||
"required": ["name", "source_revision"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"source_revision": { "type": "string" },
|
||||
"artifact_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "Recommended; required if a built artifact (not just source) is governed."
|
||||
}
|
||||
}
|
||||
},
|
||||
"initial_target": {
|
||||
"type": "object",
|
||||
"required": ["amount", "currency"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"amount": { "type": "number", "exclusiveMinimum": 0 },
|
||||
"currency": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z]{3}$",
|
||||
"description": "ISO 4217 code. Working default Q6: one native currency per Phase."
|
||||
}
|
||||
}
|
||||
},
|
||||
"target_basis": {
|
||||
"type": "object",
|
||||
"description": "Recommended transparency metadata (working default Q5), not legally required.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"estimated_effort_days": { "type": "number", "minimum": 0 },
|
||||
"daily_rate": { "type": "number", "minimum": 0 },
|
||||
"approved_direct_costs": { "type": "number", "minimum": 0 },
|
||||
"target_multiple": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"description": "Open decimal per working default Q4. Guidance classes {0,1,10,100,1000} are not a closed enum."
|
||||
}
|
||||
}
|
||||
},
|
||||
"future_license": {
|
||||
"type": "string",
|
||||
"enum": ["MIT", "Apache-2.0"],
|
||||
"description": "Working default Q3: closed enum for Stage 0."
|
||||
},
|
||||
"degeneration_policy": {
|
||||
"type": "string",
|
||||
"pattern": "^trsl:policy:[a-zA-Z0-9._-]+@[0-9]+(\\.[0-9]+)*$",
|
||||
"description": "e.g. trsl:policy:linear-longstop-v0@1.0 (working default Q7)."
|
||||
},
|
||||
"longstop_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Required for Stage 0 per working default Q8. Full-remission / maximum-protection instant."
|
||||
},
|
||||
"ledger": {
|
||||
"type": "string",
|
||||
"description": "URL or relative path URI to the authoritative Target Ledger for this Phase."
|
||||
}
|
||||
}
|
||||
},
|
||||
"extensions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^trsl:extension:[a-zA-Z0-9._-]+@[0-9]+(\\.[0-9]+)*$"
|
||||
},
|
||||
"description": "Optional. Applicable monetization profiles/extensions for this Phase."
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue