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
128
scripts/generate_golden_phase.py
Normal file
128
scripts/generate_golden_phase.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Regenerate examples/phase-001/ledger.json with a correct hash chain.
|
||||
|
||||
The golden Phase package must exercise a real SHA-256 hash chain, not
|
||||
hand-typed digests. This script builds the entry sequence from
|
||||
spec/TargetRevenueLicenseConcept.md §23's illustrative example and writes it
|
||||
out via the same hashing.entry_hash() the library and tests use, so the
|
||||
fixture and the code that verifies it can never silently drift apart.
|
||||
|
||||
Run: python3 scripts/generate_golden_phase.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "src"))
|
||||
|
||||
from target_revenue import hashing # noqa: E402
|
||||
|
||||
PHASE_ID = "trsl:phase:example-001"
|
||||
|
||||
|
||||
def entry(
|
||||
entry_id: str,
|
||||
entry_type: str,
|
||||
amount: float,
|
||||
recognized_at: str,
|
||||
extension_id: str,
|
||||
extension_version: str,
|
||||
evidence_reference: str,
|
||||
previous_entry_hash: str,
|
||||
) -> dict:
|
||||
return {
|
||||
"id": entry_id,
|
||||
"phase": PHASE_ID,
|
||||
"type": entry_type,
|
||||
"amount": amount,
|
||||
"currency": "USD",
|
||||
"recognized_at": recognized_at,
|
||||
"extension": {"id": extension_id, "version": extension_version},
|
||||
"evidence_reference": evidence_reference,
|
||||
"previous_entry_hash": previous_entry_hash,
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
entries: list[dict] = []
|
||||
previous_hash = hashing.GENESIS
|
||||
|
||||
specs = [
|
||||
# (id, type, amount, recognized_at, extension_id, evidence_reference)
|
||||
(
|
||||
"trsl:entry:example0010001",
|
||||
"development-credit",
|
||||
25000,
|
||||
"2026-09-01T09:00:00Z",
|
||||
"trsl:extension:development-license",
|
||||
"confidential:evidence:example-001-dc-0001",
|
||||
),
|
||||
(
|
||||
"trsl:entry:example0010002",
|
||||
"development-credit",
|
||||
10000,
|
||||
"2026-09-15T09:00:00Z",
|
||||
"trsl:extension:phase-sponsorship",
|
||||
"confidential:evidence:example-001-dc-0002",
|
||||
),
|
||||
(
|
||||
"trsl:entry:example0010003",
|
||||
"development-credit",
|
||||
2000,
|
||||
"2026-10-01T09:00:00Z",
|
||||
"trsl:extension:service-with-development-allocation",
|
||||
"confidential:evidence:example-001-dc-0003",
|
||||
),
|
||||
(
|
||||
"trsl:entry:example0010004",
|
||||
"remission-credit",
|
||||
18000,
|
||||
"2026-12-01T00:00:00Z",
|
||||
"trsl:policy:linear-longstop-v0",
|
||||
"confidential:evidence:example-001-rc-0001",
|
||||
),
|
||||
(
|
||||
"trsl:entry:example0010005",
|
||||
"development-credit",
|
||||
30000,
|
||||
"2027-03-01T09:00:00Z",
|
||||
"trsl:extension:development-license",
|
||||
"confidential:evidence:example-001-dc-0004",
|
||||
),
|
||||
(
|
||||
"trsl:entry:example0010006",
|
||||
"remission-credit",
|
||||
15000,
|
||||
"2027-06-01T00:00:00Z",
|
||||
"trsl:policy:linear-longstop-v0",
|
||||
"confidential:evidence:example-001-rc-0002",
|
||||
),
|
||||
]
|
||||
|
||||
for entry_id, entry_type, amount, recognized_at, ext_id, evidence in specs:
|
||||
record = entry(
|
||||
entry_id,
|
||||
entry_type,
|
||||
amount,
|
||||
recognized_at,
|
||||
ext_id,
|
||||
"1.0",
|
||||
evidence,
|
||||
previous_hash,
|
||||
)
|
||||
entries.append(record)
|
||||
previous_hash = hashing.entry_hash(record)
|
||||
|
||||
out_path = REPO_ROOT / "examples" / "phase-001" / "ledger.json"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(entries, f, indent=2)
|
||||
f.write("\n")
|
||||
print(f"wrote {len(entries)} entries to {out_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue