← Files PicsartARCHIVED FILE
docs/PLATFORM-ASKS.md
11.9 KB · Oct 10, 2026 · 18:02 UTC
# Platform asks — capabilities the film pipeline needs from Picsart
Findings from the 2026 best-practices research and the `pa-ai-agent-skills`
analysis. These are relays, not plugin work: each exists in the industry (or
already inside Picsart's agent platform) and is missing from the MCP surfaces
the plugin can call.
1. **Model-level identity lock** (LoRA / PuLID-class character fine-tune).
The studio-grade consistency tier: encode a lead's face into weights once,
hold it across every generation. Prompt+reference discipline (what the
pipeline does today) is the ceiling without it.
2. **Video upscale / frame interpolation on the gen-ai surface.** The
practitioner post chain is upscale → grain → grade. **Done 2026-09-09**:
video upscalers are on the gen-ai surface; `film-finishing` picks one from
the live catalog at the time of the pass and names none, because the tools
change.
3b. **Word-level speech alignment on the film plugin's own surface.** The rough
cut (default-on, `film-edit`) times every dialogue shot from its line's word
boundaries — first word, last word, where the tail silence really starts —
and that is also how "the line reads" gets checked against the script. The
capability exists twice on the platform and neither is reachable here:
`video-transcribe-audio` ships only with the **classic** Picsart API plugin,
and `pcp/v1/whisperx-stt` (word segments, forced alignment — what
`video2clip` uses) is an agent-platform workflow with no MCP surface. Note
the ask is narrower than transcription: **we already know the words.** A
forced-alignment call taking audio plus the expected text would be smaller,
cheaper and more accurate than open transcription, and it is the shape this
pipeline actually wants. Without either, every shot's timing falls back to
its planned beat clock — a real rough cut, but blind to what the take did.
**Parked with the automatic rough cut (2026-09-04)**: a run arrives cut by
the model, so no trim is derived any more. Still wanted for "the line
reads" — checking a take's dialogue against the script.
3. **Scene-detect + audio beat analysis as MCP tools.** Both already run on
the agent platform (`media-platform/v1/videos/scene-detect` — PySceneDetect
with cut lists/EDL; BPM/beat/key analysis). On the MCP surface they would
let the film flow detect unintended model-inserted cuts inside takes and
cut trailers on beats. **Since 2026-09-03 this is load-bearing rather than
nice-to-have**: scenes now generate as one multi-shot take (a *run*,
`film-scenes`) and the delivered file has to be split back into shots where
the model actually cut — near the declared times, not on them. Today that is
contact-sheet frames around each planned time plus a look; a cut list from
scene-detect would make the split exact, free of charged frames, and would
catch a wrong cut count before anyone watches.
4. **Subject-tracked reframe** (`autoframe_reframe`-class): measured
per-moment subject centers → a crop track. The finishing stage promises
9:16/1:1 promo reframes and currently judges crops manually per shot.
5. **Video-LLM "watch"** (`deep_analyze_media`-class): one-pass "what
happens, who is on screen, where the beats are" over a clip — replaces
several contact-sheet + vision round trips in take QC and join QC.
6. **Durable upload grant for the MCP service principal** (tracked from the
Drive durability fix): `type=web`-class uploads currently reject the
service token, so Drive saves of ephemeral URLs fall back to honest
`durability: "expiring"` warnings.
6b. **A horizontal camera angle on the shot card (server repo, small).** The
card records shot size and camera height but not which *side* of the subject
the camera is on — so the 30° rule (two shots of one subject need ≥30° of
camera movement between them, or the cut reads as a glitch) cannot be
checked, because there is no angle to compare. The size-step form is what we
enforce instead (`film-scenes/references/SEAMS.md`) and it catches the ugly
cases, but it is a proxy: a camera that stays put while the lens changes
passes the size check and still stutters. What it needs is a per-shot
horizontal angle — clock positions around the subject would match the
vocabulary the lighting presets already use — and the shotlist board is
where it belongs, beside size and height.
7. **Widget follow-up (server repo, small):** the Scene Review board's
thumbnails and expanded player assume video; still images (the animatic
boards from `film-scenes` step 3) should render via inferred media type.
8. **Voice registration — the second half of a flow whose first half already
ships.** The one missing link
in the whole voice chain, and the reason a *designed* voice cannot be kept in
sync. The sync-preserving repair is speech-to-speech on a take's own dialogue
(`eleven-sts-v2`: ±3ms over 5.3s, envelope correlation 0.852 at zero lag), and
both sts models take `audioUrl` + **`voiceId`**. A described voice's identity
is a sample file, and nothing on the surface converts one into an id —
ElevenLabs' own instant/professional voice cloning does exactly this. With it,
every designed voice becomes swappable onto finished takes and the dub route
disappears. Without it, describing a voice forecloses lip-sync, which is a
trap in a feature we ship.
**The gap is narrower than "add voice cloning".** Checked 2026-08-27 across
all 23 audio models and the classic REST specs (a search for "voice" in the
OpenAPI specs returns nothing — the classic surface has no voice management at
all). What IS exposed: `eleven-voice-create` — *"generate voice previews from
a description to audition before committing"* — whose schema is a bare
`prompt` and whose output is audio, plus `eleven-voice-design-v3`/`-v2`, same
shape. Upstream, that previews call returns generated-voice ids and a second
call turns the chosen preview into a permanent voice. **We surface the
audition and not the commit** — the model's own description says "before
committing" and there is nothing to commit to. Wiring that second call (and
returning the id on the passport) is the whole ask; `/v1/voices/add`-class
registration from an arbitrary sample would cover the rest.
9. **Speaker separation (diarization) on an audio track.** `eleven-audio-isolation`
splits voice from background, not speaker A from speaker B. A two-hander shot
comes back as one mixed track, so per-character voice work on it is only
possible where the lines do not overlap (cut by transcript timings first).
Overlapping dialogue currently cannot be re-voiced at all.
10. **A lip-sync pass: video + new audio → the mouth re-animated.** The single
tool that would make the voice problem disappear, and the standard 2026
practitioner answer to it (LatentSync, MuseTalk, Wav2Lip; commercially Sync).
With it the flow is one rule — shoot normally, replace the dialogue with the
approved voice, re-drive the mouth — and nothing has to be decided before the
take. Without it there is no way to put an approved voice on a finished shot
whose mouth is on screen, except regenerating that shot from the audio
(`ltx-2.3-a2v`), which changes generators mid-scene.
Checked the surface: no v2v model accepts an audio input. `ltx-v2.3-retake`
advertises "replace audio, video, or both" but its exposed schema is
`prompt` + `duration` + `videoUrl` only — no audio parameter — so the
capability is either not wired through or not real. Worth confirming with the
model owners before building on the description.
11. **Run grouping on the shotlist board (server repo, medium).** The unit of
generation is the run — one multi-shot generation for as much of the film
as fits the model's ceiling, scenes included (`film-scenes`, 2026-09-03) —
and the board has no way to show it. The user's experience of the board is
meant to stay exactly as it is — short cards, presets per shot — with the
grouping visible on top. Three things it needs, in order of value:
a **run marker** spanning the rows that share a generation (and a way to move
the split), so the user can see what one re-roll costs; **`genSec` and the
video commit per run** rather than per row — the board's per-shot `genSec`
is now read as "what this shot would cost alone" and ignored inside a run;
and **free-form `sec` inside a run** — the pills offer 3|5|7|8|10|12, but a
shot inside a run keeps its exact cut length (a 5.3s line is a 6.3s shot,
no ladder) because only the run's total snaps to the model. Until it lands,
the grouping is said in chat when the list is approved and lives only in
`film.json.scenes[].runs`.
12. **Let `picsart_save_asset` lock on sheet approval (server repo, small).**
**Done 2026-09-05** on `film-ux-polish`: `lockBlockers` no longer asks for
a battery — an absent `stressTest` blocks nothing, a recorded battery with
failures still does, a waiver still clears it. The same change disabled
`picsart_asset_sheet` (decorator swapped for a no-op, source kept) and
rewrote the `picsart_save_asset` / `picsart_asset_review` descriptions to
the one-sheet, approval-is-the-lock flow, because the old tool text was
pulling the model back into per-angle stills and a stress test.
13. **Auto-emit one crop per declared state at save (server repo, medium).**
A sheet is how identity is generated; a single-panel **view** is how it
travels, and today the plugin cuts those views itself with
`picsart_media_export` and files them in `referenceImages[]`. The ask is for
`picsart_save_asset` to do it: given the sheet, its grid and the panel map
it already receives, emit and store one crop per declared state, addressable
as `@tag.state` (`@alina.adult_formal`), and return those URLs on the
passport. Then a prompt references a state instead of a file the assistant
had to remember to cut, the library holds a view per state for every project
by construction, and the sc04a/sc04b failure — a panel pointer resolved
differently on each generation — has no way back in. Two dependencies of
ours worth stating: the crops must be **byte-stable** across reads (the same
state must hand back the same file, not a re-render), and each must carry
its box, so a wrong crop is diagnosable without re-deriving it.
14. **A server-side verify gate on `picsart_generate` (server repo, the only
thing that makes this certain).** The plugin now has a prompt-verify step
(`film-scenes/references/PROMPT-VERIFY.md`) and a deterministic checker for
its mechanical half (`film-scenes/scripts/check_dispatch_intent.py`), and
both are mandatory in the skill text. **Skill text cannot guarantee
execution.** Every safeguard here is an instruction an assistant follows or
forgets, and the failure this step exists to fix was committed by an
assistant that could quote the rules correctly minutes beforehand. Only the
server can refuse. The ask, smallest version first: `picsart_generate`
accepts an optional `verify` object — `{ sha256, kind }` — and when the
project's `film.json` carries `verify.required: true`, a call whose
`sha256` does not match a fingerprint of the arguments actually being
dispatched is **rejected before the charge**, with the verdict's own error
text returned. The fingerprint is already computed and returned by the
checker (`requestSha256`), so the plugin side exists; what is missing is
something that says no. A film that opts in then cannot spend credits on an
unverified prompt, in any client, by any assistant, including a future one
that never read this file. Second, larger version: the checks themselves
move server-side, so the rules are enforced for every user of the film
surface rather than every user who happens to be running these skills.
SHA-256: cbf32ea9c6e773cfd18538bd6fef4cd8f40a669d7eed4309ad8f6b0e00f3c9a1