SSM-Clock Stamp – Minimal CLI (8.3)

Goal. Show an end-to-end stamp → verify → (optional) anchor path using Python stdlib only. All math and comparisons are plain ASCII and deterministic.


A. Stamp (essential steps)

  1. Read file bytes and hash
# bytes -> digest (default sha256; streaming OK)
h_file = sha256(file_bytes)

  1. Fix iso_utc and compute epoch seconds
iso_utc = "YYYY-MM-DDTHH:MM:SSZ"  # exact Z, no subseconds, no offsets
unix_seconds = seconds_since_1970_UTC(iso_utc)

  1. Deterministic clock from UTC
wrap360(x) = x - 360*floor(x/360)
theta_deg  = wrap360( (unix_seconds / 86400) * 360 )
theta_str  = print_fixed(theta_deg, digits=theta_prec, rounding="half-even")  # default theta_prec=5
rasi_idx   = floor(theta_deg / 30)

  1. Build stamp_core and chain
stamp_core = "SSMCLOCK1|" + iso_utc + "|" + rasi_idx + "|" + theta_str + "|" + h_file_hex
chain_0    = "0"*64
chain_k    = sha256( ascii(chain_{k-1} + "|" + stamp_core) )  # or H_chain per kv:chain_algo

  1. Emit one ASCII line
SSMCLOCK1|iso_utc|rasi_idx|theta_str|h_file_hex|chain_hex[|kv:...]

Defaults if kv: absent: algo=sha256;chain_algo=sha256;theta_prec=5;float=ieee75464;time_mode=derived_utc.


B. Verify (essential steps)

  1. Parse fields and re-hash
h_prime = H_algo(file_bytes)  # from kv:algo or sha256
require h_prime == recorded_hex  -> HASH_OK=true

  1. Recompute clock from iso_utc
theta_deg' = wrap360( (unix_seconds(iso_utc) / 86400) * 360 )
rasi_idx'  = floor(theta_deg' / 30)
theta_str' = print_fixed(theta_deg', digits=theta_prec, rounding="half-even")
require rasi_idx' == rasi_idx_recorded
and     theta_str' == theta_str_recorded    # preferred
# optional numeric fallback when print-policy drift suspected:
# abs(theta_deg' - theta_deg_recorded) <= 0.5 * 10^(-theta_prec)

  1. Rewalk chain (if a ledger exists)
prev = "0"*64
for each row k in ledger order:
    calc = H_chain( ascii(prev + "|" + stamp_core_k) )
    require calc == row.chain
    prev = calc
require some row matches this file's chain -> CHAIN_OK=true
# if no ledger: CHAIN_OK=na

  1. Anchor parity (if a day note exists)
sort stamps by (iso_utc, stamp_core, chain)
joined   = "Stamp_1|...|Stamp_n"
rollup_D = sha256( ascii(joined) )
require rollup_D == rollup_sha256_in_note and counts match  -> ANCHOR_OK=true
# if no note: ANCHOR_OK=na

  1. Flags and verdict (stdout, ASCII)
HASH_OK=true CLOCK_OK=true CHAIN_OK=true ANCHOR_OK=na EVIDENCE_OK=absent
VERDICT=PASS


C. One-minute sanity (copy-ready mini demo)

Inputs:

file bytes: "hello\n"
iso_utc_1  = "2025-10-13T10:53:57Z"
iso_utc_2  = "2025-10-13T10:53:58Z"

Expected derived values:

sha256("hello\n") = 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
theta(iso_utc_1)  -> "163.48750" ; rasi_idx_1 = 5
theta(iso_utc_2)  -> "163.49167" ; rasi_idx_2 = 5

Chaining from zero:

chain_0 = "0"*64
chain_1 = sha256( ascii(chain_0 + "|" + stamp_core_1) )
chain_2 = sha256( ascii(chain_1 + "|" + stamp_core_2) )

Daily roll-up (two stamps, canonical sort and join):

rollup_D = sha256( ascii(Stamp_1 "|" Stamp_2) )

All outputs are lowercase 64-hex, joins are with literal |, and everything is 7-bit ASCII.


D. Notes and guardrails

  • UTC only: iso_utc must be YYYY-MM-DDTHH:MM:SSZ; stamps with :60 are invalid (no stamping at 23:59:60).
  • Binary64 math: intermediate math uses IEEE-754 binary64; print theta_deg with exact digits and half-even rounding.
  • ASCII discipline: ascii(x) for every hashed concatenation; no Unicode punctuation; no spaces around separators.
  • Unknown kv: keys: must be ignored by verifiers; recognized keys must pass domain checks.
  • Streaming OK: large-file hashing by chunks must equal monolithic hashing.

Navigation
Back: SSM-Clock Stamp – Build & (Optionally) Sign the Verify Pack (8.2)
Next: SSM-Clock Stamp – Quick Start (9)