draft-vods: defer media.track publication to publishDraft time master
place.stream.media.track records were published at processing time (in publishRecords), which leaked half-published content: the tracks went live immediately while the video record wasn't created until the user published the draft. With drafts, that gap can be long. Defer track creation to publishDraft. - publishRecords stops calling publishTrack. It still publishes place.stream.media.origin (server-repo blob availability attestation) and now stores the track-publishing inputs on the Upload row: signing_key, probe_json (video/audio codec/dims/fps/rate/channels), and blob_size. SetUploadProcessed signature updated accordingly. - markDraftReadyFromUpload: the draft reaches 'ready' with source=nil (no track refs exist yet) and durationMs set (known at processing time). - PublishDraft publishes the tracks at publish time via the new publishTracksFromUpload: reads the probe+signingKey+size+CID from the tied Upload row, calls publishTrack per A/V stream, and builds the video's source from the fresh strongRefs. Falls back to a carried-over source if the draft has no tied upload (legacy). - Upload row gains SigningKey, ProbeJSON, BlobSize columns. TrackURIs is vestigial (left for the legacy publishVideo path). Tests updated: the lifecycle test now asserts source is nil at ready time and the Upload row carries the deferred inputs. build + tests + lint clean. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>