delivery-kid: finalize webhook updates draft state (status, final_cid)#95
Merged
jMyles merged 1 commit intoJun 1, 2026
Conversation
The Coconut webhook handler was only updating the *job* state — not the draft state — when a finalize-side job completed. Net effect: - HLS got transcoded and pinned to IPFS ✓ - job.hlsCid was set ✓ - But draft.json never got `status: finalized` or `final_cid` written - Wiki diagnostics panel stayed stuck on "finalizing" forever - Blue Railroad Imports bot never saw a finalized draft, so no Release page got created Verified end-to-end against terrapin re-finalize (PR cryptograss#94 deploy): Coconut V2 ran cleanly, HLS pinned at QmVUq..., but the wiki page showed nothing past "transcoding-submitted" and no Release appeared. Two fixes: ## 1. content.py finalize path adds draftId to job_state The preview-path job_state already had draftId so the webhook handler could map back to a draft. The finalize-path job_state was missing it — so even with the new _update_draft_finalize below, the webhook wouldn't know which draft to update. ## 2. coconut.py adds _update_draft_finalize + wires it in Mirror of _update_draft_preview for the finalize side. On job.completed: state.status = "finalized", state.final_cid = hlsCid, finalize_log appended, wiki snapshot fired. On job.failed: state.status = "finalize_failed", error logged. Webhook handler's tail now branches on isPreview to call the right updater rather than only handling preview jobs. This is a pre-existing gap exposed by PR cryptograss#94 — pre-V2, the finalize fast path was reusing preview_cid and the slow Coconut-finalize path was rarely hit, so the missing draft-state update went unnoticed.
6 tasks
jMyles
added a commit
that referenced
this pull request
Jun 1, 2026
PR #95 closed half the gap — _update_draft_finalize now updates delivery-kid's draft.json with status=finalized + final_cid when Coconut V2 completes. But the wiki ReleaseDraft:{id} page YAML stays on the pre-finalize state because the historical "write the YAML edit" step was done by browser-side JS responding to an SSE 'complete' event that the slow Coconut path never sends (the SSE closes after 'transcoding-submitted' minutes before Coconut actually completes). Net effect through PR #95: HLS was pinned, draft.json reflected it, but no Blue Railroad Imports bot trigger fired because the bot reads the wiki page edit history for "Finalized: pinned to IPFS as <cid>" summaries — and that edit was never made. This PR closes the second half: ## 1. pickipedia_client: write_finalized_to_releasedraft New method that: - Loads the current ReleaseDraft:{id} YAML - Sets status=finalized, final_cid=<cid>, finalized_at=<iso> - Saves with summary "Finalized: pinned to IPFS as <cid>" - Preserves all user-supplied YAML fields (title, description, venue, performers, etc.) by parse+update+dump rather than rewriting from scratch Async wrapper runs the sync mwclient calls in a thread so the FastAPI event loop isn't blocked during the wiki round-trip. ## 2. coconut.py _update_draft_finalize: call it on success After the existing draft.json update + diagnostics-snapshot, fire the wiki YAML update as another asyncio task (fire-and-forget, same pattern as the snapshot). On the next Blue Railroad bot run, the bot's find_cid_from_history picks up the summary and creates Release:{cid}. ## 3. Also: narrate the webhook stages in finalize_log The wiki diagnostics panel had a 2-minute gap between "transcoding-submitted" and "complete" — single jump. Add separate log entries for webhook-received / HLS-pinned / complete so the panel renders the progression. They all land in one draft.json save (we don't have a stream back to the browser; the panel picks them up on its next poll). ## Test plan after deploy - Re-finalize the terrapin draft (or any in-flight) - Watch docker logs: should see "pickipedia_client: marked ReleaseDraft:<id> finalized" after the Coconut callback - Wiki page revision history should show a "Finalized: pinned to IPFS as Qm..." edit by Magent@magent - Blue Railroad Imports bot creates Release:<cid> on next cron - New Release page resolves to a directory with master.m3u8 + variant playlists + segments — real playable video, not 421-byte metadata.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
The Coconut webhook handler only updates draft state for preview jobs. For finalize jobs it pins HLS to IPFS, stores `hlsCid` in the job state, returns 200 — and never touches the draft. So the wiki page stays stuck on "finalizing", and the Blue Railroad Imports bot never sees a finalized draft, so no Release page is ever created.
Verified end-to-end against today's terrapin re-finalize (PR #94 deploy):
```
17:07:24 - Coconut V2 job submitted → 201
17:09:49 - Webhook received: job.completed
17:09:49 - HLS pinned: QmVUqPwgpSAYy7UmpeCfG64UzpxLZq6UZyULkdZnujny5H
[silence — no Release page, no diagnostics-panel update]
```
What this PR does
1. `content.py` finalize path adds `draftId` to `job_state` (was missing — preview-path had it, finalize-path didn't, so even with the new webhook updater below, mapping job → draft wouldn't work).
2. `coconut.py` adds `_update_draft_finalize` (mirror of `_update_draft_preview` for finalize) and wires it in:
```python
if job.get("draftId"):
if job.get("isPreview"):
_update_draft_preview(staging_dir, job)
else:
_update_draft_finalize(staging_dir, job)
```
On `job.completed`: sets `state.status = "finalized"`, `state.final_cid = hlsCid`, appends to `finalize_log`, fires the wiki-snapshot hook (terminal-state trigger).
On `job.failed`: sets `state.status = "finalize_failed"`, logs the error.
How this got missed
Pre-existing gap, exposed by #94. Pre-V2, the finalize fast path was happily reusing `preview_cid` as the Release CID, so the slow-Coconut-finalize path rarely ran in practice. With the fast path disabled (V2 preview is mp4-only, not finalize-grade HLS), every finalize now goes through the slow path and hits this gap.
Test plan