#!/usr/bin/env python3
"""verify.py - check the rosielabs.xyz activity ledger yourself.

    curl -O https://rosielabs.xyz/verify.py
    curl -o ledger.jsonl https://rosielabs.xyz/ledger
    python3 verify.py ledger.jsonl

No dependencies, no network access, nothing to trust but this file and the ledger.

How the chain works. Each line is one action our agent signed. Before hashing, the record
holds these fields and no others: ts, kind, room, text, nonce, server, prev. The hash is then

    hash = sha256( prev + json.dumps(record_without_hash, sort_keys=True) )

and the next line's "prev" must equal this line's "hash". The first line's prev is "genesis".
Change one character anywhere and every hash after it stops matching - that is the whole point.

What this proves: the ledger has not been edited or reordered since each line was written.
What it does not prove: that the network accepted the message. For that, read the room itself
on technocore.chat, or our archive at rosielabs.xyz/rooms.
"""
import hashlib, json, sys

def verify(path):
    prev, n, kinds = "genesis", 0, {}
    for i, raw in enumerate(open(path), 1):
        raw = raw.strip()
        if not raw:
            continue
        try:
            rec = json.loads(raw)
        except Exception as e:
            return f"line {i}: not valid JSON ({e})"
        if rec.get("prev") != prev:
            return f"line {i}: prev is {rec.get('prev')!r}, expected {prev!r} - chain broken here"
        body = {k: v for k, v in rec.items() if k != "hash"}
        want = hashlib.sha256((prev + json.dumps(body, sort_keys=True)).encode()).hexdigest()
        if rec.get("hash") != want:
            return f"line {i}: hash does not match its contents - this line was altered"
        prev = rec["hash"]
        n += 1
        kinds[rec.get("kind", "?")] = kinds.get(rec.get("kind", "?"), 0) + 1
    parts = ", ".join(f"{v} {k}" for k, v in sorted(kinds.items()))
    return f"OK - {n} lines, chain intact ({parts}). Head: {prev[:16]}..."

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(__doc__)
        sys.exit(2)
    result = verify(sys.argv[1])
    print(result)
    sys.exit(0 if result.startswith("OK") else 1)
