Skip to content

feat(handoff): posting.json per film; a posting dispatch is draft-only - #15

Merged
duyetbot merged 2 commits into
mainfrom
feat/posting-film-contract
Oct 27, 2026
Merged

duyetbot merged 2 commits into
mainfrom
feat/posting-film-contract

Conversation

@duyet

@duyet duyet commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

What changes

posting.anyrouter.dev is taking over the nightly film schedule (duyet/anyrouter#6688). This PR is the additive half of the contract. The GitHub schedule: stays until posting dispatches on its own, so there is never zero or two schedulers.

  • render-video.yml gets a requested_by input (owner default, or posting). A posting dispatch is a workflow_dispatch nobody pressed, so lib/publish.mjs isUnattended() now treats REQUESTED_BY=posting like schedule: draft Release only, no YouTube, no replace. The decide step refuses regen and force for it.
  • lib/handoff.mjs writes posting.json beside post.md in each posting-drafts folder (schema anyrouter.posting-film/v1). draft is posting's AgentDraft JSON keyed on the Release tag, with the film as a sha256-keyed media item. Beside it are the film file name, sha256, bytes, frame size, the cover name and model_ids (new optional kind hook modelIds, set on model-drop). Copy links point at kind.link, never the draft Release, which is not public.

posting reads <tag>/posting.json out of the artifact with ranged reads (no full zip download), so the artifact name and layout are now a contract (README).

Order

  1. This PR (additive).
  2. duyet/anyrouter: wf_model_video dispatches with requested_by: posting, polls, imports.
  3. Follow-up here: drop schedule: the hour the owner enables wf_model_video.
  4. Retire youtube.yml once posting's YouTube publish is verified.

Verification

node --test: 202 pass, 0 fail. New cases: a posting dispatch is refused YouTube, non-draft and replace, then makes exactly one draft Release; posting.json holds only AgentDraft keys, the right sha256, and no github.com link; the workflow refuses regen and force for posting. Mutation check: removing the REQUESTED_BY clause fails the posting dispatch test.

🤖 Generated with Claude Code

…-only

posting.anyrouter.dev is taking over the nightly schedule. It dispatches
render-video with requested_by=posting and reads <tag>/posting.json out of
the posting-drafts artifact. That run counts as unattended: draft Release
only, no YouTube, no regen, no force. The GitHub schedule stays until
posting is live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
posting.json copy (X, LinkedIn, YouTube description) linked bare
anyrouter.dev for model-drop films, which had no link hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@duyetbot
duyetbot merged commit de3226c into main Oct 27, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants