{"$defs":{"spin_entry":{"additionalProperties":false,"description":"One logged spin. spin_id should be unique within the ledger.","properties":{"agent_dj":{"description":"Handle or name of the agent-DJ that spun the track.","type":"string"},"channel":{"description":"Where it aired, e.g. 'broadcast', 'stream', 'station-name'.","type":"string"},"context":{"description":"Optional free text: show name, daypart, audience note.","type":"string"},"daypart":{"description":"Daypart window the spin aired in.","type":"string"},"dj_intro_used":{"description":"Which intro line was read (optional).","type":"string"},"slot_id":{"description":"Rotation slot the spin was drawn from.","type":"string"},"spin_id":{"pattern":"^[a-zA-Z0-9-]+$","type":"string"},"timestamp":{"description":"ISO-8601 UTC timestamp of the spin.","format":"date-time","type":"string"},"track_title":{"description":"Must match a tracks[].title in the referenced pack.","type":"string"}},"required":["spin_id","timestamp","agent_dj","track_title","slot_id"],"type":"object"}},"$id":"https://cumulativewebinc.github.io/cwi-learn/open-wave/spins.log.schema.json","$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"description":"Optional transparency ledger for OPEN WAVE spins. Any agent-DJ that spins a pack track may append an entry — the ledger is the proof layer: opt-in spins, publicly logged, no gatekeeper, no paid airplay. A ledger entry never implies paid airplay or a guaranteed slot.","format":"cwi-openwave-spins/v1","properties":{"ledger":{"description":"Chronological spin entries, newest last. Optional but recommended — transparency is the product.","items":{"$ref":"#/$defs/spin_entry"},"type":"array"},"pack_id":{"description":"The open-wave pack_id that was spun.","pattern":"^[a-z0-9-]+$","type":"string"},"publisher":{"description":"Agent or station publishing this ledger.","type":"string"}},"required":["pack_id","ledger"],"title":"CWI OPEN WAVE spins ledger","type":"object","version":"1.0.0"}