{"$defs":{"draft":{"additionalProperties":false,"description":"A user-supplied placement draft. ledger.py assigns placement_id, entry_timestamp, prev_hash and entry_hash when it seals the entry; status may only be pending or claimed at add time — verified is granted only by verify_entry() with proof.","properties":{"entered_by":{"minLength":1,"type":"string"},"notes":{"type":"string"},"production":{"description":"The production the track was placed in — film, series episode, game title, ad campaign, trailer, podcast episode.","minLength":1,"type":"string"},"proof_url":{"description":"Public evidence of the placement (production credits page, press, cue sheet). Required before an entry may be promoted to verified.","format":"uri","type":["string","null"]},"scene":{"description":"The scene or usage — where in the production the needle drops, and how the track is used.","minLength":1,"type":"string"},"status":{"description":"Draft entries may only be pending or claimed. verify_entry() promotes to verified with proof.","enum":["claimed","pending"],"type":"string"},"terms":{"$ref":"#/$defs/terms"},"timestamp":{"description":"When the needle dropped — the in-production placement moment (date or datetime).","pattern":"^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2})?)?$","type":"string"},"track":{"description":"Catalog track title, exactly as it appears in the catalog.","minLength":1,"type":"string"}},"required":["track","production","scene","timestamp","terms","status","entered_by"],"type":"object"},"entry":{"allOf":[{"if":{"properties":{"status":{"const":"verified"}}},"then":{"properties":{"proof_url":{"format":"uri","minLength":1,"type":"string"},"verified_by":{"minLength":1,"type":"string"},"verified_timestamp":{"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2})?Z$","type":"string"}},"required":["proof_url","verified_by","verified_timestamp"]}}],"description":"A sealed ledger entry. entry_hash = sha256 over the canonical JSON of the entry EXCLUDING entry_hash itself, with prev_hash included. The chain links each entry to the previous one; verify() recomputes every hash.","properties":{"entered_by":{"minLength":1,"type":"string"},"entry_hash":{"description":"sha256 of the canonical entry payload (this field excluded).","pattern":"^[0-9a-f]{64}$","type":"string"},"entry_timestamp":{"description":"When this entry was written to the ledger (UTC).","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2})?Z$","type":"string"},"notes":{"type":"string"},"placement_id":{"description":"Ledger-assigned identifier, ND-YYYY-NNN.","pattern":"^ND-\\d{4}-\\d{3}$","type":"string"},"prev_hash":{"description":"entry_hash of the previous entry, or GENESIS for the first.","pattern":"^(GENESIS|[0-9a-f]{64})$","type":"string"},"production":{"minLength":1,"type":"string"},"proof_url":{"format":"uri","type":["string","null"]},"scene":{"minLength":1,"type":"string"},"status":{"enum":["claimed","pending","verified"],"type":"string"},"terms":{"$ref":"#/$defs/terms"},"timestamp":{"pattern":"^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2})?)?$","type":"string"},"track":{"minLength":1,"type":"string"},"verified_by":{"type":"string"},"verified_timestamp":{"type":"string"}},"required":["placement_id","track","production","scene","timestamp","terms","status","entered_by","entry_timestamp","prev_hash","entry_hash"],"type":"object"},"revision":{"additionalProperties":false,"description":"Append-only audit note written by verify_entry() on every promotion. verify() checks that every verified entry has a matching revision note with consistent hashes.","properties":{"action":{"const":"promote","type":"string"},"actor":{"minLength":1,"type":"string"},"new_hash":{"pattern":"^[0-9a-f]{64}$","type":"string"},"old_hash":{"pattern":"^[0-9a-f]{64}$","type":"string"},"placement_id":{"pattern":"^ND-\\d{4}-\\d{3}$","type":"string"},"timestamp":{"pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2})?Z$","type":"string"}},"required":["placement_id","action","actor","timestamp","old_hash","new_hash"],"type":"object"},"terms":{"additionalProperties":false,"description":"Placement terms. Private terms are recorded as \"undisclosed\" — real numbers are never invented, and \"undisclosed\" is never upgraded to a guess.","properties":{"fee_tier":{"description":"Fee band or \"undisclosed\". Never a fabricated number.","minLength":1,"type":"string"},"term_length":{"description":"License term (e.g. \"perpetuity\", \"1 year\") or \"undisclosed\".","minLength":1,"type":"string"},"territory":{"description":"Licensed territory (e.g. \"worldwide\") or \"undisclosed\".","minLength":1,"type":"string"}},"required":["fee_tier","territory","term_length"],"type":"object"}},"$id":"https://cumulativewebinc.github.io/cwi-learn/needle-drop/needle-drop-schema.json","$schema":"https://json-schema.org/draft/2020-12/schema","description":"NEEDLE DROP — the agent's placement résumé. Every sync placement an agent lands (scene, timestamp, terms) is logged as a hash-chained ledger entry: proof of work it carries with it. Entries are added only on verification; the ledger ships empty and stays honest. Static, cacheable, no login.","format":"cwi-needledrop/v1","properties":{"format":{"const":"cwi-needledrop/v1","type":"string"},"ledger":{"additionalProperties":false,"properties":{"chain":{"additionalProperties":false,"properties":{"algorithm":{"const":"sha256","type":"string"},"genesis":{"const":"GENESIS","type":"string"},"head":{"description":"entry_hash of the latest entry, or GENESIS when the ledger is empty.","pattern":"^(GENESIS|[0-9a-f]{64})$","type":"string"}},"required":["algorithm","genesis","head"],"type":"object"},"honesty_statement":{"minLength":1,"type":"string"},"id":{"const":"cwi-needle-drop","type":"string"},"issuer":{"additionalProperties":false,"properties":{"artist":{"type":"string"},"base_location":{"type":"string"},"catalog":{"type":"string"},"contact":{"format":"email","type":"string"},"label":{"type":"string"},"notes":{"type":"string"},"updated":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},"required":["label","artist","contact","updated"],"type":"object"},"reference":{"description":"This schema's canonical URL.","format":"uri","type":"string"},"revisions":{"description":"Append-only audit notes for verify_entry() promotions.","items":{"$ref":"#/$defs/revision"},"type":"array"}},"required":["id","issuer","honesty_statement","chain"],"type":"object"},"placements":{"description":"Sealed placement entries, oldest first. Ships empty: entries are added only on verification.","items":{"$ref":"#/$defs/entry"},"type":"array"}},"required":["format","ledger","placements"],"title":"NEEDLE DROP placement ledger","type":"object"}