← AI Producer by OpusClipCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to AI Producer by OpusClip
Snapshot Sep 30, 2026 · 22:59 UTC · version 1.2.8
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "aip",
"description": "Create or update an editable AI Producer video. Use when someone provides footage or an existing project and asks AI Producer to cut, caption, add motion graphics or music, restyle, export, or adapt a named Motion Library template, in any language (剪视频 / 剪辑 / 加字幕 / 做动效 / 配乐 / 导出成片 / 素材 / 插入图片 / 插一段视频). Settle the rough cut, fine cut and finishes rounds for a new project when the request leaves them open. Deliver the editable project link by default, export only on explicit request, and stop without inspecting the preview or output video.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 106
},
{
"relative_path": "references/handoff.md",
"size_in_bytes": 10046
},
{
"relative_path": "references/progressive-publication.md",
"size_in_bytes": 9073
},
{
"relative_path": "references/workspace.md",
"size_in_bytes": 6184
},
{
"relative_path": "scripts/__pycache__/editing_script_sync.cpython-314.pyc",
"size_in_bytes": 40930
},
{
"relative_path": "scripts/__pycache__/preflight.cpython-314.pyc",
"size_in_bytes": 12839
},
{
"relative_path": "scripts/__pycache__/progressive_checkpoint.cpython-314.pyc",
"size_in_bytes": 20915
},
{
"relative_path": "scripts/__pycache__/progressive_publish.cpython-314.pyc",
"size_in_bytes": 35818
},
{
"relative_path": "scripts/__pycache__/publication_guard.cpython-314.pyc",
"size_in_bytes": 13652
},
{
"relative_path": "scripts/__pycache__/upload_batch.cpython-314.pyc",
"size_in_bytes": 8816
},
{
"relative_path": "scripts/editing_script_sync.py",
"size_in_bytes": 24712
},
{
"relative_path": "scripts/preflight.py",
"size_in_bytes": 9168
},
{
"relative_path": "scripts/progressive_checkpoint.py",
"size_in_bytes": 12803
},
{
"relative_path": "scripts/progressive_publish.py",
"size_in_bytes": 24839
},
{
"relative_path": "scripts/publication_batch.js",
"size_in_bytes": 10662
},
{
"relative_path": "scripts/publication_guard.py",
"size_in_bytes": 8110
},
{
"relative_path": "scripts/upload_batch.py",
"size_in_bytes": 4879
}
],
"skill_md_contents": "---\nname: aip\ndescription: \"Create or update an editable AI Producer video. Use when someone provides footage or an existing project and asks AI Producer to cut, caption, add motion graphics or music, restyle, export, or adapt a named Motion Library template, in any language (剪视频 / 剪辑 / 加字幕 / 做动效 / 配乐 / 导出成片 / 素材 / 插入图片 / 插一段视频). Settle the rough cut, fine cut and finishes rounds for a new project when the request leaves them open. Deliver the editable project link by default, export only on explicit request, and stop without inspecting the preview or output video.\"\n---\n\n# AI Producer preview\n\nCreate one editable AI Producer preview from the user's footage and creative brief. Shape the edit around the user's intent, the footage, and its audience.\n\n## Targeted changes to an existing project\n\nWhen the request targets an existing AI Producer project, begin from its current saved edit and make only the requested change. Do not upload the source again, restart project preparation, or reopen the rough cut, fine cut and finishes rounds unless the user asks to revisit one of them.\n\nA natural request to use or adapt a Motion Library template, together with its `Project` and `Template` context line, is an existing-project change. Read the [Motion Library handoff](references/handoff.md) once and follow it before the new-project flow below. The handoff also owns compatibility with legacy Motion Library references.\n\n## What to settle before you cut\n\nThe rough cut, the fine cut and the finishes decide the edit. Settle all three before you start editing, then edit without coming back for more.\n\nPreparing the project is not editing, and it waits for no answer. In the turn the footage arrives, start it before you ask anything: mint the upload target with `sign_upload`, PUT the bytes, then call `start_transcribe_project`. Only then read the saved default and put up the first round. Ingesting and transcribing the source is the long part of the run and no answer in the rounds changes what it does, so a card raised first buys nothing and charges the user the whole wait. The three rounds are asked while preparation runs, and because the project exists by the time an answer comes back, each one is written down where it is given. Two things hold preparation back, and only these. A conversation with no computer behind it, which Known issues below covers: nothing is signed there. And the user asking to talk the edit through before anything is spent: that is an instruction, so tell them what preparing costs, settle what they want to settle, and start preparation when they say to go ahead.\n\nPreparation spends, so whatever you say when you start it carries its price: the message that raises the first round, or your first reply when their opening settles every round and no card goes up. The price is read from `get_pricing` and never quoted from memory, and it reaches the user in plain words, as what getting their video ready costs.\n\nAsk only for what the user has not already told you. Read their opening message against the rounds below; a round whose answer follows from what they wrote is settled, and you do not put it to them. Ask the rounds that are still open, in the order they are listed, one at a time. Every round settled - from their words or from their answers - is the signal to start production. Nothing else gates the work: there is no mode to pick and no feature list to shop.\n\n### Start from the saved default\n\nAt the start of every new project, before the first round, read `get_editing_preset`.\n\n- It returns a preset: put those settings to the user in plain words and ask them to confirm or change anything, in cards built from the same components the rounds use, each picker carrying the stored value as its `selected`. A text component takes no prefill - a card renders its field empty whatever you send - so a stored `editing_preference` is quoted back in your own message and the empty field is where a change goes. A card holds at most six server components and a full preset is five, so one card carries the whole of it, in round order, and you ask for the confirmation once at the end rather than after each setting. Confirmed as it stands, you edit with it and ask nothing further, and you write the confirmed values down with `record_choices` under the same card ids an answer would have used, so the project's own record says the rounds are settled and no later turn asks them again. Changed, you edit with the changed values and write those down the same way.\n- It returns nothing: run the rounds.\n\nRead it fresh on every project rather than remembering it between them. The user can change these settings away from the conversation, and this is the only place that change shows.\n\nThe default is the user's to set, and they set it on the settings page on the web, never through you: the server has a `save_editing_preset` tool, but it is not yours to call, and nothing in a conversation asks the user to keep their answers.\n\n### The rounds\n\nEach round is one card: call `present_choices` with that round's components, end your turn, and wait. Preparation is already under way by the first card, so `record_choices` has a project to write to and each answer lands as it arrives. A card needs no project behind it, so in the exceptional case where a round is raised before one exists - preparation refused, or the user answering a round you have not reached - the answer is carried and written down as soon as the project is created. When the user answers - on the card or in their own words - write it down with `record_choices` under that round's card id, then raise the next round - unless that round names something of its own that comes first. The latest recording for a card wins, so a user who changes their mind is recorded again, not argued with. `get_project` carries `choices`, what is answered, and `pending_choices`, what is not, in round order; a turn that picks up a conversation already in progress reads those two rather than guessing. A card's title and note are sentences the user reads, so they follow Talk to the user and name no card, component or tool.\n\n| Round | Card id | Components | What you write down |\n| --- | --- | --- | --- |\n| Rough cut | `roughcut` | `rough_cut_boldness` | the value alone |\n| Fine cut | `branding` | `editing_preference_example`, `editing_preference` | `<component id>=<value>`, one per answer they gave |\n| Finishes | `finishing` | `caption_style`, `bgm_enabled`, `sfx_enabled` | the caption style's value alone, and the two toggles as `bgm_enabled=on`, `sfx_enabled=off` |\n\n**Rough cut.** `off` means keep the original cut: no filler word, retake, false start or pause is removed. `off` is not a boldness and never travels on to anything that takes one. The other three - `conservative`, `balanced`, `aggressive` - say how far the clean-up goes. You make this cut yourself by writing the speaker clips, so its scope is yours to keep: on their own, these levels remove only filler words, verbatim restarts, abandoned false starts, failed retakes, and dead-air pauses. A fluent, complete sentence is content at every level, even when it seems less important, repetitive, or off topic; dropping it needs editorial scope from the user, and a scripted read with no disfluencies is left whole under cleanup alone. Without a requested duration, highlights, short version, or named removal, the speaker clips cover the rest of the source in order. Cut to the settled value and to the user's requested scope and duration, preserving the speaker's intended meaning. For a rough-cut-only or targeted speech-cleanup request, skip visual research and default visual treatments unless they are also requested. When revising the rough cut of an existing project, start from its current saved state: preserve choices outside the requested rough-cut change, and update affected captions, visuals, and audio timing to follow the revised cut. When the request includes both rough cut and fine cut, settle the content cut before finalizing timed treatments, then complete both. Pause for rough-cut review only when the user asks for it.\n\nFor a requested duration, highlights, or short version, select valuable, fluent speech and settle an engaging opening, the core argument, and a complete ending before fitting the length. Choose a self-contained final thought from the original speech, such as a conclusion, summary, or recommendation, with the context it needs. Do not fill the duration sequentially and truncate: avoid ending mid-sentence, mid-list, on a conjunction, or on a promise of more explanation. Keep the full final word and a short natural pause from the source; that closing pause is not disposable dead air. An approximate duration allows modest variation for a complete ending. For an exact duration or strict maximum, adjust earlier selections or choose a shorter complete ending instead of cutting the final sentence short.\n\n**Fine cut.** This round asks how the user wants the footage edited: one worked example to start from, and their own words beside it. Both answers reach no tool. They are recorded, and applying them is yours - they are the direction you design the cut under. `editing_preference_example` offers `more-broll-image`, `more-motion-graphics` and `custom`; `custom` is the user saying the examples do not fit, so it carries nothing on its own and the words in `editing_preference` are the answer. `custom` with nothing typed is therefore not an answer: ask for their words before you record it, or the round reads as settled while holding no direction at all. An example on its own is a complete answer, and so is nothing at all - a user who wants neither is not blocked, so record what they did give and design the cut yourself.\n\nThe reference image is not on this card, because a card collects one line of text and an image is a file. So the card's note says nothing about a picture, and the ask is a message of its own. Look back over what the user has already sent. When they handed a picture over, put it into the project with `sign_workspace_upload` and write `reference_image=<path>` into the same `record_choices` call as the two answers, and ask them for nothing. When they sent none, record the two answers on their own, and then, before the finishes round goes up, ask them for the picture in plain words - your own sentence, not a card and not a line inside the note: whether they want to send a reference image to set the styling, and that answering \"skip\", or anything else, carries on without one. End the turn there and wait for the reply. An image comes back: upload it with `sign_workspace_upload` and record `branding` a second time - the two answers you already wrote down and `reference_image=<path>` beside them, because a recording replaces the whole entry for a card and an answer left out of the second call is gone - then raise the finishes round. \"skip\" or any other reply: raise the finishes round. Ask once for the whole project, and never a second time - not after a skip, and not when a turn picking the conversation back up finds `reference_image` already recorded under `branding` or the fine cut already behind it in `choices`. A user with no image to give is not blocked by the round.\n\n**Finishes.** `caption_style` offers `no-caption` (\"No captions\") and eight caption patterns. Write the chosen token unprefixed, including `no-caption`, while the two toggles carry their component ids: `on` on its own identifies no question. A pattern goes to the caption skill without picking again. An omitted `caption_style` stays Auto: let the caption skill choose the pattern, rather than treating it as `no-caption`. Recording replaces the whole entry for a card, so write every finishing answer you hold each time you record one, or the ones you leave out are gone.\n\n`no-caption` is a card answer, not a caption pattern: skip `build_captions` and omit the `narrator-captions` host from `render-engine/index.html`. For an existing captioned project, remove only that host, preserve transcript and editor artifacts, then upload the changed root and `commit_workspace`. Recording the answer alone does not change the edit. A saved preset that carries `no-caption` is read back unchanged.\n\n`bgm_enabled=on` is the instruction to call `add_music` afterwards, and `off` is the instruction not to. `off` declines a new music run; it does not strip a bed already mixed into the cut, so do not offer to take music away with it. `on` is an answer, not a payload: it is not a value `add_music` takes, and that call's own inputs are stated where it states them. Music spends, and `get_pricing` is what says how much - never quote an amount from memory.\n\n`sfx_enabled=on` is the instruction to call `add_sound_effects` on this project, and `off` is the instruction not to, so nothing is spent on sound effects. Where each effect lands is yours to decide: read the finished cut's timeline and place a hit where a sound earns its place - a cut, a beat of emphasis, the instant a motion graphic enters - in milliseconds on that timeline, never the source's. So call it once the cut and its timed treatments are settled, and when a later edit moves the cut, place the hits again. Send every hit in one call, 1 to 12 of them, because a call replaces the project's previous sound-effect track rather than adding to it. `on` is an answer, not a payload, exactly as with music. Sound effects spend, so read `get_pricing` before the call - never quote an amount from memory.\n\nNot every install has the cards. When `present_choices` is not among your tools, the rounds are still asked, in plain text: each still-open round as one question of its own, in the user's language, offering the same options by name and in the order the table above lists them, one round per turn. Each round's options are named where that round is explained above, with one exception: the eight caption styles are not, so read them from the [dynamic caption skill](../aip-dynamic-caption/SKILL.md) before you ask the finishes round - with no card, the server is not the one offering them, and a style you invent is not one the caption layer can be built with. Write nothing down - `record_choices` is absent with it, and so are the preset tools, so skip the saved-default read - and carry the settled answers in the conversation instead. Everything else stands: preparation starts first and on the same terms, the reference image is still asked for as its own question, and a round the user's opening already settles is still not put to them.\n\n## Source supporting visuals\n\nOnce the rounds are settled, apply the default editorial taste and research supporting material in the initial plan. Identify transcript beats that need real products, interfaces, devices, places, or event imagery. Use suitable supplied assets first; respect requests to avoid external sources.\n\n- Review every supplied B-roll across its full time range: use representative frames for an overview, then inspect candidate action boundaries closely. Match each retained speech beat against operations, results, project lists, templates, feature entries, and tools, not just the first obvious actions. Finish that comparison before deciding coverage; finding a few matches is not a stopping rule. Match what the footage actually shows: a feature entry can illustrate availability, but does not demonstrate the operation or its result.\n- Choose B-roll boundaries by action completeness, existing edits, topic changes, and dead time, not a fixed seconds threshold. Keep short complete shots and coherent pre-edited clips continuous; divide longer videos where distinct topics or operations warrant it. Preserve the necessary setup, action, and readable result. One demonstration may cover several consecutive related sentences. Avoid word-by-word cuts, source-time jumps within one operation, repeated close-up/wide switches, and brief presenter flashes between related demonstrations.\n- A-roll follows the settled speech cut; fit B-roll to it without recutting speech to accommodate an asset's length. Trim irrelevant head or tail, adjust coverage over related speech, choose another excerpt, or return to the presenter when a clip does not fit. Do not default to loops, freezes, or speed changes to fill time. Let useful matches and continuity decide coverage, without a fixed clip count or coverage quota. Keep a concise local mapping of speech beats, source in/out times, and cut placements.\n- For missing material, search the Web and open official or primary source pages to find images or clips. An empty `find_broll` result requires this lookup before falling back to diagrams. Use one batch of up to three targeted queries, plus at most one such follow-up batch for unresolved material.\n- Batch page reads and downloads. Before authoring, inspect a downsized image sheet or representative source frames for subject match, usable detail, and crop suitability. Replace unsuitable candidates within the research limit.\n- Use accepted assets in relevant beats with framing or motion that explains the speech. Unless the user names a trigger or a count, use each image or single-shot clip once at its best-fitting beat. A long video with multiple relevant moments can supply several distinct excerpts across the edit; do not restrict the source file to one use or repeat the same excerpt by default. A stated trigger such as \"whenever X is mentioned\" applies at every matching beat. Record source URLs locally; apply the [on-screen text rules](#on-screen-text) to visible labels.\n\n## Delivery boundary\n\nDeliver the editable project link by default. Treat \"finished video\" or \"final cut\" as a completed preview, not an explicit MP4 request. Export only when the user explicitly requests an MP4, rendered video file, or export. For an authorized export, wait for completion and return its link without opening, playing, sampling, or analyzing the output.\n\nDo not inspect the generated preview or MP4, including browser playback, screenshots, contact sheets, frame extraction, audio analysis, or delegated inspection. Do not start a post-delivery review, repair, or aesthetic iteration. This stopping condition applies whether the deliverable is a preview or an explicitly requested export. Input-media analysis, including retrieved source assets, and local static contract checks before submission remain allowed.\n\nUse only this package's [AI Producer composition contract](../aip-composition/SKILL.md) and [workspace reference](references/workspace.md) for integration. Read the workspace reference once before source upload or export, the composition contract once before authoring, and the [framing skill](../aip-framing/SKILL.md) once before deciding the speaker's frame for each beat; load the linked PIP example only when needed, and read the [dynamic caption skill](../aip-dynamic-caption/SKILL.md) once before the caption layer when it is listed. Do not search global HyperFrames or media-use skills, backend source, or repository documentation to make this video. Resolve these links relative to the skill actually loaded, never a remembered versioned cache path. If that path is stale, use the host's installed-plugin listing once to find the enabled package and its version.\n\n## Talk to the user\n\nTreat every commentary, confirmation, progress update, warning, refusal, and final reply as user-facing product copy. Match the user's language. Lead with the user's current state: what is ready, what is still happening, and what they need to do next. Keep routine progress concise.\n\nCall the product AI Producer in everything the user reads, and never name the environment it runs against, the endpoint, the server, this plugin, or any part inside it.\n\nDo not narrate implementation policy or expose skill names, tool names, IDs, tasks, digests, graphs, checkpoints, commits, upload signing, provider or runtime checks, internal files, or status codes. Keep those details inside tool calls and local logs. Translate a necessary limitation into its effect on the user's project and the next available step.\n\nPlain language must remain accurate. Say that a project is ready only after the corresponding operation succeeds. For a refusal or failure, explain what could not be completed, how it affects the project, and what can happen next. Do not repeat a non-actionable internal warning unless it materially changes what the user should expect.\n\n## Known issues\n\n**The host reports that the MCP server requires OAuth reauthentication, or this plugin's tools are absent from the tool list with nothing else offered to explain it.** This is the client validating the credential it stores locally, not a service fault. No request leaves the client, so no service error exists to read and nothing can be retried or repaired from inside the conversation. Signing in clears it, but the session that hit it does not reliably reload the tools, so do not wait for them and do not deliberate over whether to. When the host reports a condition of its own, such as the service being unreachable or a network failure, that is a different problem and signing in does not address it: report what it means for the user's project instead of running this flow.\n\nBoth steps belong to the user, in this order.\n\n1. Ask the user to sign in once to the `ai-producer` server in their own client. In Claude Code this is `/mcp`, then `plugin:aip:ai-producer`, which is how that host namespaces the same connection. In Codex, on the desktop app as much as in the CLI, it is `codex mcp login ai-producer` run by the user in their own terminal: the desktop app carries no sign-in control of its own for a plugin's connection, and the commands you run reach no network, so this is not something you can do for them. Name the entry for the host they are on, because the user selects it by name, and keep everything around it in product language. Do not assemble an authorization link, do not advise reinstalling the plugin, and do not modify MCP configuration. None of these restores the connection, and each can cost the user a working install.\n2. Then ask the user to start a new chat and resume the work there. The hosts differ: in Codex the user @-mentions this plugin, and in Claude Code the user simply makes the request again, which loads it. State exactly what carries over: an existing project keeps its footage and its edit behind its project link, while anything the failed connection prevented from reaching AI Producer has to be sent again.\n\nA plugin update can require signing in once more. That is expected, and it happens once.\n\n**The conversation has no computer behind it: nothing you can run a command on, nowhere to write a file, and a video the user attached is something the host holds rather than a file you have.** In ChatGPT that is a Chat conversation. This plugin runs in Work and in Codex, each of which gives the conversation a computer of its own; Chat does not, and nothing on the AI Producer side changes that. The upload the service signs waits for bytes only a computer can send, and the edit is authored as files only a computer can write, so starting anyway ends in an error that reads as the plugin's or the video's when the cause is the kind of conversation. So do not start: no upload, no project, and no other route for the footage. Tell the user that their video is fine and so is AI Producer, and that editing it needs a Work chat or a Codex task: in ChatGPT on the web and in the desktop app, Work is the tab above the message box, and if it is not offered where they are, those two places have it. Ask them to start that conversation and mention AI Producer in it. What carries over is what already reached AI Producer: a project that exists keeps its footage and its edit behind its project link, so a follow-up on one takes the link there and not the footage again, while a video that only ever reached this conversation has to be attached again in the new one. Codex and Claude Code always have a computer, so this never applies to them.\n\n## Show progress in Codex\n\nIn Codex, as soon as an AI Producer creation/preparation tool returns `project_id`, call `get_view_url`. In the same code-mode call, parse its single-use `url` and durable `agent_page_url` with `URL`. Require the same origin and the expected `/p/<project_id>` path. On the project URL, replace its query with `mcp=1&embed=1` followed by the original parameters other than `mode`, `mcp`, and `embed`; preserve `host` and other parameters. Set only the exchange URL's `next` parameter to that project path plus query and fragment; preserve its ticket and all other parameters. Pass the resulting exchange URL directly to `open_in_codex` with `target: {type: \"browser\", url: <exchange url>}` and `placement: \"right\"`, omitting `threadId`. Open during preparation; use the transformed `agent_page_url` for any later reopening in that browser. The exchange URL is single-use: do not fetch it separately or include it in messages or files.\n\nFor every user-facing project link, including the link given when a run starts, the final reply, and follow-up handoffs, parse `page_url` with `URL` and replace its query with `mcp=1&embed=0` followed by the original parameters other than `mode`, `mcp`, and `embed`; preserve `host` and other parameters. Never give the user the exchange URL or `agent_page_url`.\n\nOpening is a status-only handoff to the user, not inspection. Use no external browser or computer-use action that returns page content. Keep the tab for live updates without reopening, refreshing, polling, playing, or inspecting it.\n\n`queued` means pending. Retry an explicit failure at most once with the same tool, obtaining a fresh exchange URL only if the first may have been consumed. If unavailable or still failing, report it and continue editing; never claim the page opened.\n\n## Default editorial taste\n\nA settled round is the user's own instruction, so it outranks every default below, and a default never fills a round that is still open. A footage-only or vague opening is not licence to skip the rounds: settle them first, then plan from these defaults for everything the rounds and the user left unsaid.\n\nPlan each new talking-head edit from its supplied media and publishing brief. The user's request, in the brief or in a later edit, is the highest instruction: it overrides any default below, and nothing listed or unlisted among your skills blocks it. A listed skill sets a default and the method for it; an unlisted one only drops that default, so a treatment the user asks for is still delivered with the tools the service exposes. Keep the rest of the defaults. Preserve established choices in follow-up edits unless the user requests changes.\n\n### Editing\n\n- Open with a sharp punch-in, then hold the framing; when sound effects are on for this project, a whoosh placed with `add_sound_effects` lands on the punch-in. Place massive, extra-bold text behind the presenter, spanning 80-90% of the frame width, partially occluded by the head but still readable. Reveal words individually; split or wrap instead of shrinking. Use high-contrast text, preserve the original background, and animate only the text after the punch-in.\n- Use presenter close-ups and zooms for emphasis.\n- For concrete subjects, prefer relevant real footage, then images, then vectors.\n- Show the specific change described by the speech. Use generic geometric shapes, expanding cards, or checkmarks only when they clarify that change; prefer a direct demonstration when suitable footage or assets are available.\n- Captions are on by default while aip-dynamic-caption is listed, and they stay on during visual moments; the framing skill places the band for each layout. Apply the finishing round's choice.\n- For sarcasm, self-deprecation, or brief reminders, use a monochrome or desaturated presenter close-up for at most one sentence, then restore color.\n- Use smooth effects and layout transitions; minimize hard cuts.\n- No background music.\n\n### Visual style\n\n- Use a pure black canvas with near-black foreground surfaces, fills only, no strokes; preserve source-media colors unless a specific treatment is intended.\n- For abstract relationships, mechanisms, and processes, prefer 3D animation, then SVG or vector.\n- Every visual must animate purposefully from entry to exit; each motion reveals a step, relationship, or change; transitions and camera moves don't count.\n- No titles, headings, or decorative copy. If a beat has no meaningful visual without its copy, show the presenter, with captions only when enabled.\n- Center the focal point within each visual area. Keep all graphics inset at least 10% from the edges throughout the animation; avoid dense repetition and unnecessary layers so graphics stay large.\n\n### On-screen text\n\nThese rules govern extra authored copy; spoken captions remain a separate layer governed by the caption skill.\n\n- Authored vectors, diagrams, and animations default to no secondary text. Keep core values and units attached to the quantities they depict. Add an object, category, or relationship label only when its absence creates a specific ambiguity that the visual and simultaneous speech do not resolve. Omit labels that merely name a recognizable object or restate what the visual and speech already convey.\n- Sourced B-roll or images may carry one short source or example label, only when the material could be mistaken for the speaker's own footage or demonstration. Authored graphics carry no provenance labels, \"illustration\" disclaimers, or explanatory footnotes.\n- Before publishing each effect, apply a deletion test to its local composition source: if removing an extra label preserves the meaning in the context of the speech, remove it. This is a source-text check before submission, not inspection of the generated preview.\n\n## Make, submit, stop\n\nInspect the supplied media and plan once. When the user ties a visual to an on-screen cue such as a gesture, a prop, or an action, locate that moment from representative source frames as well as the transcript; this is input-media analysis, not output inspection. Batch independent metadata reads and material downloads in one script. Fetch a transcription only after its task completes; do not repeatedly fetch an unfinished transcript. When the available tool schema supports `wait_seconds`, use it with the supported limit; otherwise obey the returned polling interval. Waiting is not a reason to load more skills or inspect backend code.\n\nPlan the whole edit locally. When the current schema exposes `authoring`, set it to `true` on a new project's creation/preparation request or an existing project's first `sign_workspace_upload` request. Set it to `true` on any intermediate commit and `false` on the final commit, so the service can retain and then close external-authoring status. This uses existing calls only; never add a provider call, model subtask, heartbeat, or polling round for status. Omit the field when the schema lacks it.\n\nFor a fresh project in Codex, use the [progressive checkpoint flow](references/progressive-publication.md). Plan the complete edit once. Publish the first effect as soon as it is ready. Then author the remaining effects in batches of up to two while the preceding batch publishes. Keep drafts isolated and let the helper publish each effect in order using the AI Producer MCP tools already loaded in the current task. Preserve the planned effects, timing, and transitions; batching controls scheduling only. Keep unfinished beats full-length with normal presenter framing, and publish without intentional delays. Do not launch another Codex CLI, app server, task, or model subtask. The last commit closes authoring status: the final batch of a caption-free edit, otherwise the caption commit that follows the last batch.\n\nRun the batch helper in the execution that writes its drafts. It handles signing, uploading, committing, held waiting, and receipt acceptance without separate model coordination or receipt-collection turns. The final receipt includes earlier warnings. If the host cannot keep an execution alive while authoring continues, await each batch without claiming overlap. Other hosts, existing effect graphs, and zero-effect edits use ordinary complete-graph publication. Measure actual tokens and duration; overlapping work is not a cost or quality guarantee.\n\nThe progressive helper runs the local contract and timeline checks, freezes the hashes the current task supplies to `commit_workspace`, and advances only from that commit's accepted receipt. Use the plan it returns once; do not recompute its digest or expected files in the host. For ordinary publication, run [preflight.py](scripts/preflight.py) as described in the workspace reference, or skip it and let admission report contract errors if no Python 3.9+ interpreter is available; batch signatures and uploads with [upload_batch.py](scripts/upload_batch.py) or the host's batch HTTP tools, then commit with the current `base_digest`. Every commit remains all-or-nothing. A signing, upload, commit, task, or receipt failure leaves the current checkpoint closed without automatically retrying a mutation or adopting another writer's digest. Report it with the last successful effect count; do not restart the full sequence. Tool descriptions own authentication, limits, and task state.\n\nAfter the final requested graph is accepted, deliver the durable project link (`page_url`, retrieved if missing and transformed for the user as above) in the final reply, then stop unless an export was explicitly requested. Give the user that link in the same reply that says the run has started, not only at the hand-back: the project exists and is watchable from the moment it is created, and a run is long. A view-ticket url is never that link - it is single-use and signs whoever opens it into your own account, so it does not go to the user. Translate refusals and material warnings under the user-facing language contract; do not repeat internal codes or mechanisms. Do not claim visual quality, audio synchronization, or export compatibility. Close by handing final confirmation to the user: state what was applied, then ask them to confirm the result on the project page, already open beside the conversation in Codex, otherwise at the link in this reply. Word this as a completed delivery waiting on the user's review.\n"
}SHA-256: 13e475e5f1e76c67df6def919254c0c57bcce7e858e29d193224b64fbfe0c771