BaoCut
Use the bundled resolver for every command. On macOS/Linux:
BAOCUT_SKILL_ROOT="<this-skill-directory>"
"$BAOCUT_SKILL_ROOT/bin/baocut" --json version
On Windows, run the native PowerShell resolver (WSL is not required):
$env:BAOCUT_SKILL_ROOT = "<this-skill-directory>"
& "$env:BAOCUT_SKILL_ROOT\bin\baocut.ps1" --json version
Mandatory startup version gate
Run this gate once at the start of every BaoCut task, before spec, doctor,
any project command, or reuse of an existing bcut serve:
- Explicitly run the platform resolver's
--json version command above and
retain its appVersion and commit. A successful resolver handshake, a
compatible spec, doctor, or serve --status is not an update check.
- Immediately read and execute references/updates.md:
fetch the published appcast and compare its version numerically with the
local
appVersion. Only an unavailable appcast may be reported as skipped.
- When the appcast is newer, update the standalone skill and let its refreshed
resolver download, verify, and cache the pinned CLI before continuing. Do
not merely report the update or keep using the compatible old CLI. Never
overwrite a development checkout or an App-bundled skill; use the supported
source/App update path documented in the reference instead.
- After any CLI update, run the refreshed resolver with
serve --background,
then serve --status. This idempotent start replaces an older same-root
service, restores its mounts, and must report the refreshed CLI's
appVersion and commit; also require HTTP 200 from its health endpoint.
Discard any URL discovered before the restart.
Only after this gate may capability preflight and the requested work begin.
The resolver locates the right CLI on its own — never call bcut directly:
- An explicit
BAOCUT_CLI (or BCUT_EXECUTABLE / BAOCUT_BIN) override wins.
Point it only at a CLI built for this machine's architecture — see the
architecture guard below.
- In a BaoCut development checkout (this skill directory inside the source
tree) it uses the workspace build — newest of release/debug, under
core/target/{release,debug}/bcut or core/target/<host-triple>/… — or
runs the sources via cargo run when nothing is built yet (it looks for
cargo in ~/.cargo/bin, Homebrew's rustup, and ~/.rustup/toolchains
when PATH lacks it). It prints a development checkout detected note to
stderr in that case, and a separate note when it must compile from source
or when it falls back to the installed App CLI because nothing is built and
cargo is unavailable — read those notes instead of guessing why a version
gate failed. A foreign-architecture build in the tree (for example
core/target/x86_64-apple-darwin/… on Apple Silicon) is never selected.
- In a released install it uses the CLI embedded in BaoCut.app, in either
/Applications or ~/Applications; every App release ships with its
matching baocut-cli, so App and CLI versions always move together.
- Then a
bcut on PATH.
- Then the cached CLI this skill pinned earlier, under
${XDG_CACHE_HOME:-~/.cache}/baocut/cli/<version>-build.<build>/bcut.
On Windows, bin/baocut.ps1 uses the same explicit overrides,
development-checkout build, and PATH lookup first. It then checks cached
<version>-build.<build> CLIs newest-first — by version and build, because
the handshake only reports the marketing version and cannot tell two builds
apart — and compatibility-checks them locally. Only when no compatible cache
exists does it find the newest stable baocut-v<version>-build.<build> GitHub
Release that includes windows-cli-release.json, downloads its x64 Windows
archive, verifies the manifest-pinned SHA-256, and caches bcut.exe under
%LOCALAPPDATA%\BaoCut\cli\<version>-build.<build>\bcut.exe. "Newest" is the
highest <version>/<build> parsed from the release tags, not the first entry
the API returns: Windows assets are appended to an already-published macOS
release, so creation order does not track build order. The Windows
archive is currently an unsigned preview, so SmartScreen, Smart App Control,
or enterprise policy may warn about or block it; SHA-256 proves download
integrity, not publisher identity.
A compatible cache normally ends the search, so a rebuild published under the
same marketing version is not picked up on its own — nothing local announces
it, since the Windows skill ships no CLI pin and --json version carries no
build number. Set BAOCUT_SKILL_CLI_UPDATE_CHECK=1 to let the cache path
compare against the newest release and adopt a higher build; unset, that path
stays entirely offline, and any failed check silently keeps the cached CLI.
BAOCUT_SKILL_NO_DOWNLOAD=1 still wins over this opt-in.
Before choosing a Windows cache or release, the resolver runs
bin/detect-windows-cli-variant.ps1. The detector uses nvidia-smi and selects
cuda13 only when at least one NVIDIA GPU has compute capability 8.0+ (Ampere /
RTX 30 series or newer) and the installed driver is >= 580; a missing or failed
probe and an incompatible GPU select cpu. The CUDA choice additionally
requires backend candle-cuda, gives the cache directory a -cuda13 suffix,
and downloads the release's windows-cli-cuda-release.json and
…-x86_64-pc-windows-msvc-cuda13.zip asset, extracting the bundled CUDA runtime
DLLs next to bcut.exe. No CUDA Toolkit install is needed. If no release ships
the selected CUDA asset yet, the resolver fails clearly instead of silently
using a different build. BAOCUT_VARIANT=cpu|cuda13 remains an explicit force
override for troubleshooting and controlled environments; normal installs do
not need it.
The resolver then checks the CLI contract and minimum BaoCut App version
before it runs the requested command, and finally checks the CLI's
architecture against the host: --json version reports target (and, on
current CLIs, rosetta), and a CLI built for another architecture — typically an
x86_64 bcut on Apple Silicon, which macOS silently runs under Rosetta 2 with
backend: candle-cpu — is refused for auto / transcribe (exit 3) and only
warned about for other commands. Do not work around that refusal by setting
BAOCUT_ALLOW_FOREIGN_ARCH=1 (or the CLI's own BCUT_ALLOW_ROSETTA=1); a
100-second clip once sat 40+ minutes in VAD on such a binary while the native
build finished the whole pipeline in about three. Resolve it by choosing a
native CLI: BaoCut.app's bundled CLI, a native workspace build, or the pinned
release CLI.
If nothing above resolves, or the resolved CLI is older than
metadata.minAppVersion, the resolver downloads the CLI pinned by this
skill's cli-release.json — the standalone release archive built from the
same commit as the matching App. It verifies the archive's SHA-256 against
the pin before extracting anything, unpacks bcut and its co-located
mlx.metallib into the cache, and reruns the full contract and version
handshake against the downloaded binary. Any failure exits 3 with the manual
download URL. The download carries no com.apple.quarantine attribute and the
Developer ID signature lives in the binary itself, so the cached CLI runs
without a Gatekeeper prompt. The resolver exports the packaged Metal library
path before executing the cached CLI, so local MLX transcription never depends
on a metallib left behind on the release build machine.
Two deliberate exceptions never trigger the download: an explicit
BAOCUT_CLI-style override and a development checkout. Both are chosen on
purpose, so a failing handshake there must be fixed at the source — update the
override or rebuild the workspace — rather than silently shadowed by a release
binary. Set BAOCUT_SKILL_NO_DOWNLOAD=1 to disable the download entirely;
BAOCUT_SKILL_NO_DEV=1 disables development-checkout detection.
The skill copy bundled inside BaoCut.app has no cli-release.json, because an
App install always ships its own matching CLI beside it.
If the resolver exits 3, follow its guidance instead of bypassing the check.
Choose the workflow
- For transcription, polish, and translation, create the project in the shared
projects library first, start the preview server, then run the pipeline;
read references/workflows.md.
- For a complete local pipeline, use
auto; read
references/workflows.md. It defaults to the fast
path without closing refinement; only pass --refine after the user chooses
quality-first execution.
- To run transcription on another machine on the same local network instead of
this one, read the remote-node note in
references/workflows.md.
- For an Agent-backed AI stage with pending calls, immediately read and follow
references/agent-tasks.md. For a short clip
its "short-job fast path" is the whole procedure (see "Right-size the run"
below). For long media its on-demand worker
rules — pool sized from the actual page plan (translate uses
ceil(source words / 880) by default (--align-fusion rows), or /2200
under --align-fusion on|off; align
also enforces at most 40 items and a
complexity budget, all capped by real slots), per-stage worker tiers (mid-tier for
translate/polish, high-reasoning tier for align and repair), hand-written
align answers with no scripted cutting and no unchanged resubmits — and its
consolidated-repair rules (including what refine-align --only-hard really
dispatches) are execution requirements, not optional tuning.
- For the Subtitle Studio browser preview — serving and mounting projects,
applying page edits, page requests, history recovery, punctuation display,
or preview troubleshooting — read
references/studio.md. The page code itself is this
skill's
templates/ directory, served live by serve.
- For source cuts, OUTPUT clip arrangement, appended media, or rough cutting,
read references/editing.md.
- For overlays, B-roll, watermarks, text styles, or debug frames, read
references/elements.md.
- For overlay motion, read references/animation.md.
- For reusable foreground templates — caption slot, segment rail, progress bar,
station logo — and the
data.json data layer that binds them, read
references/templates.md.
- For text baked into video frames, read
references/screentext.md.
- For delivery, run
check --strict and then use the export recipes in
references/exports.md.
- For granular project edits, discover the installed surface with
spec and
command --help; do not infer commands from older BaoCut releases.
- For deterministic Transcript lookup, replacement, or lexical name fixes,
use the CLI before opening Subtitle Studio: run
transcript find, then
transcript replace --expect <count>. Use --scope all when the same text
must change in both cue content and speaker display names; use
speakers rename for an id-based speaker-only rename. Re-read with
transcript find after the mutation. Do not search or type through the page
when the CLI exposes the operation; the browser is for visual review and
user-driven interactive edits. If spec lacks transcript find/replace,
update the CLI instead of silently falling back to DOM editing.
- For checking whether this skill or the CLI has a newer release, verifying
skill/CLI version consistency, or helping the user update, read
references/updates.md.
Optional completion accounting
- Keep stage timing and call accounting disabled by default. Enable it only
when the user explicitly requests stage timing, call counts, performance
statistics, or a run summary containing them. Do not collect baselines or
add an accounting table otherwise.
- When enabled, start a run ledger before the first long or mutating command.
If the project may use
--llm agent, snapshot task status <project> --json
and retain the existing (task, callId) pairs as the baseline.
- Record wall-clock start and finish times for every workflow stage that
actually runs. For
auto, split the ledger at JSONL stage transitions;
keep per-language work distinct (for example translate:zh-Hans and
align:zh-Hans) and include repair, quality-check, and export stages when
they run. Mark reused or skipped stages explicitly instead of assigning
invented durations.
- After the producer's terminal event, read
task status once more. Diff
completedCalls against the baseline, group the new accepted calls by their
stage/kind, and count repair or retry calls in the stage that caused them.
Unless the user defines another meaning, “calls” means new Agent/LLM calls,
not shell or CLI invocations. Follow the timing rules in
references/agent-tasks.md.
- When enabled, end the task with a compact table containing
Stage, Wall time, New calls, and Result, followed by end-to-end wall time and total
new calls. Use 0 for stages that made no Agent/LLM call and unobserved
when timing evidence is unavailable. Never sum overlapping queueMs,
workerMs, or totalMs values and present the result as elapsed wall time.
Shared projects library and multi-client sync
- New transcription/translation projects belong in the shared projects
library so the BaoCut App sees them immediately. Resolve it with
"$BAOCUT_SKILL_ROOT/bin/baocut" --json project dir (macOS default:
~/Library/Application Support/BaoCut/projects); create projects there with
project create unless the user names another location. Projects created in a
temporary or scratch directory are not added to the library (they would leave
a dead entry once the directory is wiped); the CLI reports
data.registered: false and warns. Use project register <path> only when
the user explicitly wants such a project listed.
- For URL media, never invent or derive a
--download-dir. Omit the flag unless
the user explicitly names a one-off destination; the CLI then honors the
shared download.dir setting. When it is absent, the video lands in the
user's system download folder (Windows Downloads Known Folder, ~/Downloads
on macOS and Linux) — never inside the project.
- After any URL-media run downloads or reuses a video, read its actual path from
data.media in a transcribe result or from
--json project show <project> at data.manifest.media.path. Tell the user
that exact path explicitly; do not merely say that the download completed.
- Progress is shared state: the App, the browser preview, and other CLI
sessions all observe the same project registry and per-project progress
files. A transcription started from this skill shows up — with live
progress — in the App and at the preview URL; do not duplicate work you can
already observe.
- After starting a transcription, always surface the preview URL (see
references/workflows.md): open it in the
agent's built-in browser to verify, and print it for the user so they can
open the same page in their own browser.
Safety and truth sources
- Treat
transcript.json words[] as the persistent text/time truth. Use BaoCut
commands or Subtitle Studio apply operations; do not hand-edit word atoms,
fingerprints, stage stamps, trans, or transAlign.
- Translation alignment is target-first: freeze natural target-language display
pieces before mapping them to consecutive sentence-word spans. Never copy,
infer, or preserve original subtitle cue boundaries for this purpose; the
local Agent and Cloud Model follow the same contract.
- Treat
timeline.json as command-owned truth. Source-local cuts and OUTPUT
clips are separate layers; overlays live on OUTPUT time. Do not hand-edit the
timeline, AI provenance, revisions, or fingerprints.
- Preserve input media. A normal pipeline writes into a
.bcut project and does
not modify the source file. Feed the original container directly; transcribe
decodes and resamples it itself, so extracting a WAV first only repeats work
the command already does.
- Prefer
--json for short commands and --jsonl for long commands. JSONL
cancellation is one stdin line: {"cmd":"cancel"}.
- AI
--review output is only a candidate. Inspect it, then explicitly run
review accept or review reject.
- A successful polish is not the end of a named multi-speaker task while
placeholder labels remain. After accepting any polish review, follow
the confirmed-speaker sync:
apply only evidence-backed identities with
speakers rename, preserve
ambiguous labels, and report every unresolved speaker id.
- Run
check --strict before claiming a deliverable is ready. Exit 2 means the
quality gate found unresolved work; exit 3 means a compatibility or worker
handoff condition.
- Treat
source-language-mismatch, target-language-mismatch,
translation-placeholder, translation-source-copy, and
translation-duplicate-collapse as hard failures. Follow the returned
sentence-scoped fix command; do not bypass the validator or reuse an older
task response manually.
- Re-read state after every edit. Exit 0 proves the mutation committed, not that
its visual timing or composition is correct; use list commands and
frames,
broll preview, or animation preview as appropriate.
Capability preflight
"$BAOCUT_SKILL_ROOT/bin/baocut" --json spec
"$BAOCUT_SKILL_ROOT/bin/baocut" doctor --quick --json
Complete the mandatory startup version gate before running this preflight.
Do not treat a missing ffmpeg/ffprobe in the doctor report as a blocker and
do not preinstall them. They are on-demand, task-level dependencies: common
workflows (transcription, waveforms, single continuous main-media export) run
without them, and the tasks that do need them (URL download merging, complex
timeline flattening, BCF video encoding) fail at the point of use with a clear
error — install only when such a task actually asks for it.
In a development checkout, long local transcribe and auto commands require
an optimized CLI. When only a debug build is current, the resolver runs
scripts/dev/prepare-bcut.sh before continuing instead of silently accepting
roughly 2x slower inference. Weigh that against the media length: a release
build of the workspace costs many minutes, while debug inference on a clip
under about 15 minutes costs seconds to a few minutes more than release — so
for such a short clip, when only a native debug build is current, export
BAOCUT_ALLOW_DEBUG_INFERENCE=1 and run it rather than compiling first. Let
the resolver prepare the release CLI for long media, and keep the flag off for
anything else. For an Agent-backed AI pipeline, pass
--llm agent explicitly; this prevents a stale BCUT_LLM_DEFAULT from
silently selecting a provider that has no usable key.
Right-size the run
Decide the shape of the run from the media length before starting anything,
and keep the shape fixed. For a media file or URL, yt-dlp --print duration_string / ffprobe or project show tells you the duration up front.
- Short clip (under ~15 minutes, transcript on one page — up to ~2200 source
words): the fast Agent-backed pipeline is a fixed serial chain of five to six
calls —
analysis → polish → translate-brief → translate →
align-edges, plus align-rewrite only if a chunk is over the hard width;
closing refinement is not part of the default run. Every
call has exactly one pending item, so there is nothing to parallelize:
answer them yourself in the orchestrating session, one after another,
claim → read contract and payload in the same step → write → submit --next. Do not start worker subagents, do not spawn a task-tracker of
seven pipeline steps, and do not read the fleet-sizing rules of
references/agent-tasks.md as instructions for
this case — its "short-job fast path" section is what applies. Two settings
are part of this shape, not optional tuning: export
BCUT_LLM_MAX_WORKERS=1 before starting auto, so the engine plans one
polish page for the whole transcript instead of splitting it across the
default three worker slots (a 1500-word clip otherwise dispatches three
~600-word polish pages plus a seam-repair, and every extra page waits in
the queue while you answer the previous one); and watch the JSONL only for
"event":"(batch-dispatch|error|done)" — a filter that also matches
transcribe stage lines floods the monitor with one event per recognized
segment. Expected wall clock on native hardware: transcription of a
2-minute clip finishes within about 3 minutes including model checks, and
each AI call takes about one minute of your own answering (the single
translate page of an 8–10 minute clip is the largest, several minutes);
the whole task should be over in roughly 10 minutes with under 40 tool
calls.
- Long media (a talk, a lecture): follow the on-demand worker rules in
references/agent-tasks.md — pool size from the
workerPlan, tiers per stage, --next chaining.
Whatever the size, watch the JSONL event stream through one Monitor (or
one background tail) rather than polling, and apply a stall budget: a
phase:"model-wait" event is an explicit, cancellable wait for another model
download or repair, not a silent stall; keep watching until it advances or
cancel the run if that model work is no longer wanted. Otherwise, on a
short clip, no new progress event for 3 minutes during transcribe means
something is wrong — check --json version (target, backend, rosetta),
ps for the process's CPU time, and the project's progress file — do not
wait for a 20-minute monitor timeout. Read the JSONL's event:"done" (or an
error event) as the terminal signal: after it, do not task claim again;
run check --strict, project show, and the preview verification. In fast
mode, summarize data.refineOffer[], state the optional refinement's benefit
and cost, and ask whether the user wants it; do not start it without a new
affirmative answer.
When the resolver reports a version or handshake problem, follow
references/updates.md and do not bypass the refreshed
CLI handshake.
Use spec as the machine-readable source of supported commands and flags. Keep
project paths quoted and use BCP-47 language tags such as zh-Hans, en, or
ja. This skill requires CLI spec >=1.31,<2.0; if a recipe and spec differ,
stop and follow the compatibility error rather than guessing.
1---2name: baocut3description: BaoCut-only operator for the installed `bcut` CLI and `.bcut` projects. Implicitly trigger only when the request explicitly names BaoCut or `bcut`, targets a `.bcut` project or BaoCut Subtitle Studio, or continues a BaoCut workflow already established in the conversation. Do not trigger solely for generic audio or video, transcription, subtitles, translation, editing, animation, review, rendering or export, FFmpeg, or another NLE. Once triggered, execute and verify the requested BaoCut transcription, subtitle or timeline, overlay, review, render, or export workflow. Being inside the BaoCut source repository is not itself a trigger; ordinary code and documentation tasks follow repository instructions unless they also operate the product or a `.bcut` project.4---56# BaoCut78Use the bundled resolver for every command. On macOS/Linux:910```bash11BAOCUT_SKILL_ROOT="<this-skill-directory>"12"$BAOCUT_SKILL_ROOT/bin/baocut" --json version13```1415On Windows, run the native PowerShell resolver (WSL is not required):1617```powershell18$env:BAOCUT_SKILL_ROOT = "<this-skill-directory>"19& "$env:BAOCUT_SKILL_ROOT\bin\baocut.ps1" --json version20```2122## Mandatory startup version gate2324Run this gate once at the start of every BaoCut task, before `spec`, `doctor`,25any project command, or reuse of an existing `bcut serve`:26271. Explicitly run the platform resolver's `--json version` command above and28 retain its `appVersion` and `commit`. A successful resolver handshake, a29 compatible `spec`, `doctor`, or `serve --status` is not an update check.302. Immediately read and execute [references/updates.md](references/updates.md):31 fetch the published appcast and compare its version numerically with the32 local `appVersion`. Only an unavailable appcast may be reported as skipped.333. When the appcast is newer, update the standalone skill and let its refreshed34 resolver download, verify, and cache the pinned CLI before continuing. Do35 not merely report the update or keep using the compatible old CLI. Never36 overwrite a development checkout or an App-bundled skill; use the supported37 source/App update path documented in the reference instead.384. After any CLI update, run the refreshed resolver with `serve --background`,39 then `serve --status`. This idempotent start replaces an older same-root40 service, restores its mounts, and must report the refreshed CLI's41 `appVersion` and `commit`; also require HTTP 200 from its health endpoint.42 Discard any URL discovered before the restart.4344Only after this gate may capability preflight and the requested work begin.4546The resolver locates the right CLI on its own — never call `bcut` directly:4748- An explicit `BAOCUT_CLI` (or `BCUT_EXECUTABLE` / `BAOCUT_BIN`) override wins.49 Point it only at a CLI built for this machine's architecture — see the50 architecture guard below.51- In a BaoCut development checkout (this skill directory inside the source52 tree) it uses the workspace build — newest of release/debug, under53 `core/target/{release,debug}/bcut` or `core/target/<host-triple>/…` — or54 runs the sources via `cargo run` when nothing is built yet (it looks for55 `cargo` in `~/.cargo/bin`, Homebrew's rustup, and `~/.rustup/toolchains`56 when PATH lacks it). It prints a `development checkout detected` note to57 stderr in that case, and a separate note when it must compile from source58 or when it falls back to the installed App CLI because nothing is built and59 `cargo` is unavailable — read those notes instead of guessing why a version60 gate failed. A foreign-architecture build in the tree (for example61 `core/target/x86_64-apple-darwin/…` on Apple Silicon) is never selected.62- In a released install it uses the CLI embedded in BaoCut.app, in either63 `/Applications` or `~/Applications`; every App release ships with its64 matching `baocut-cli`, so App and CLI versions always move together.65- Then a `bcut` on PATH.66- Then the cached CLI this skill pinned earlier, under67 `${XDG_CACHE_HOME:-~/.cache}/baocut/cli/<version>-build.<build>/bcut`.6869On Windows, `bin/baocut.ps1` uses the same explicit overrides,70development-checkout build, and PATH lookup first. It then checks cached71`<version>-build.<build>` CLIs newest-first — by version *and* build, because72the handshake only reports the marketing version and cannot tell two builds73apart — and compatibility-checks them locally. Only when no compatible cache74exists does it find the newest stable `baocut-v<version>-build.<build>` GitHub75Release that includes `windows-cli-release.json`, downloads its x64 Windows76archive, verifies the manifest-pinned SHA-256, and caches `bcut.exe` under77`%LOCALAPPDATA%\BaoCut\cli\<version>-build.<build>\bcut.exe`. "Newest" is the78highest `<version>`/`<build>` parsed from the release tags, not the first entry79the API returns: Windows assets are appended to an already-published macOS80release, so creation order does not track build order. The Windows81archive is currently an unsigned preview, so SmartScreen, Smart App Control,82or enterprise policy may warn about or block it; SHA-256 proves download83integrity, not publisher identity.8485A compatible cache normally ends the search, so a rebuild published under the86same marketing version is not picked up on its own — nothing local announces87it, since the Windows skill ships no CLI pin and `--json version` carries no88build number. Set `BAOCUT_SKILL_CLI_UPDATE_CHECK=1` to let the cache path89compare against the newest release and adopt a higher build; unset, that path90stays entirely offline, and any failed check silently keeps the cached CLI.91`BAOCUT_SKILL_NO_DOWNLOAD=1` still wins over this opt-in.9293Before choosing a Windows cache or release, the resolver runs94`bin/detect-windows-cli-variant.ps1`. The detector uses `nvidia-smi` and selects95`cuda13` only when at least one NVIDIA GPU has compute capability 8.0+ (Ampere /96RTX 30 series or newer) and the installed driver is >= 580; a missing or failed97probe and an incompatible GPU select `cpu`. The CUDA choice additionally98requires backend `candle-cuda`, gives the cache directory a `-cuda13` suffix,99and downloads the release's `windows-cli-cuda-release.json` and100`…-x86_64-pc-windows-msvc-cuda13.zip` asset, extracting the bundled CUDA runtime101DLLs next to `bcut.exe`. No CUDA Toolkit install is needed. If no release ships102the selected CUDA asset yet, the resolver fails clearly instead of silently103using a different build. `BAOCUT_VARIANT=cpu|cuda13` remains an explicit force104override for troubleshooting and controlled environments; normal installs do105not need it.106107The resolver then checks the CLI contract and minimum BaoCut App version108before it runs the requested command, and finally checks the CLI's109architecture against the host: `--json version` reports `target` (and, on110current CLIs, `rosetta`), and a CLI built for another architecture — typically an111x86_64 `bcut` on Apple Silicon, which macOS silently runs under Rosetta 2 with112`backend: candle-cpu` — is refused for `auto` / `transcribe` (exit 3) and only113warned about for other commands. Do not work around that refusal by setting114`BAOCUT_ALLOW_FOREIGN_ARCH=1` (or the CLI's own `BCUT_ALLOW_ROSETTA=1`); a115100-second clip once sat 40+ minutes in VAD on such a binary while the native116build finished the whole pipeline in about three. Resolve it by choosing a117native CLI: BaoCut.app's bundled CLI, a native workspace build, or the pinned118release CLI.119120If nothing above resolves, or the resolved CLI is older than121`metadata.minAppVersion`, the resolver downloads the CLI pinned by this122skill's `cli-release.json` — the standalone release archive built from the123same commit as the matching App. It verifies the archive's SHA-256 against124the pin before extracting anything, unpacks `bcut` and its co-located125`mlx.metallib` into the cache, and reruns the full contract and version126handshake against the downloaded binary. Any failure exits 3 with the manual127download URL. The download carries no `com.apple.quarantine` attribute and the128Developer ID signature lives in the binary itself, so the cached CLI runs129without a Gatekeeper prompt. The resolver exports the packaged Metal library130path before executing the cached CLI, so local MLX transcription never depends131on a metallib left behind on the release build machine.132133Two deliberate exceptions never trigger the download: an explicit134`BAOCUT_CLI`-style override and a development checkout. Both are chosen on135purpose, so a failing handshake there must be fixed at the source — update the136override or rebuild the workspace — rather than silently shadowed by a release137binary. Set `BAOCUT_SKILL_NO_DOWNLOAD=1` to disable the download entirely;138`BAOCUT_SKILL_NO_DEV=1` disables development-checkout detection.139140The skill copy bundled inside BaoCut.app has no `cli-release.json`, because an141App install always ships its own matching CLI beside it.142143If the resolver exits 3, follow its guidance instead of bypassing the check.144145## Choose the workflow146147- For transcription, polish, and translation, create the project in the shared148 projects library first, start the preview server, then run the pipeline;149 read [references/workflows.md](references/workflows.md).150- For a complete local pipeline, use `auto`; read151 [references/workflows.md](references/workflows.md). It defaults to the fast152 path without closing refinement; only pass `--refine` after the user chooses153 quality-first execution.154- To run transcription on another machine on the same local network instead of155 this one, read the remote-node note in156 [references/workflows.md](references/workflows.md).157- For an Agent-backed AI stage with pending calls, immediately read and follow158 [references/agent-tasks.md](references/agent-tasks.md). For a short clip159 its "short-job fast path" is the whole procedure (see "Right-size the run"160 below). For long media its on-demand worker161 rules — pool sized from the actual page plan (translate uses162 `ceil(source words / 880)` by default (`--align-fusion rows`), or `/2200`163 under `--align-fusion on|off`; align164 also enforces at most 40 items and a165 complexity budget, all capped by real slots), per-stage worker tiers (mid-tier for166 translate/polish, high-reasoning tier for align and repair), hand-written167 align answers with no scripted cutting and no unchanged resubmits — and its168 consolidated-repair rules (including what `refine-align --only-hard` really169 dispatches) are execution requirements, not optional tuning.170- For the Subtitle Studio browser preview — serving and mounting projects,171 applying page edits, page requests, history recovery, punctuation display,172 or preview troubleshooting — read173 [references/studio.md](references/studio.md). The page code itself is this174 skill's `templates/` directory, served live by `serve`.175- For source cuts, OUTPUT clip arrangement, appended media, or rough cutting,176 read [references/editing.md](references/editing.md).177- For overlays, B-roll, watermarks, text styles, or debug frames, read178 [references/elements.md](references/elements.md).179- For overlay motion, read [references/animation.md](references/animation.md).180- For reusable foreground templates — caption slot, segment rail, progress bar,181 station logo — and the `data.json` data layer that binds them, read182 [references/templates.md](references/templates.md).183- For text baked into video frames, read184 [references/screentext.md](references/screentext.md).185- For delivery, run `check --strict` and then use the export recipes in186 [references/exports.md](references/exports.md).187- For granular project edits, discover the installed surface with `spec` and188 command `--help`; do not infer commands from older BaoCut releases.189- For deterministic Transcript lookup, replacement, or lexical name fixes,190 use the CLI before opening Subtitle Studio: run `transcript find`, then191 `transcript replace --expect <count>`. Use `--scope all` when the same text192 must change in both cue content and speaker display names; use193 `speakers rename` for an id-based speaker-only rename. Re-read with194 `transcript find` after the mutation. Do not search or type through the page195 when the CLI exposes the operation; the browser is for visual review and196 user-driven interactive edits. If `spec` lacks `transcript find/replace`,197 update the CLI instead of silently falling back to DOM editing.198- For checking whether this skill or the CLI has a newer release, verifying199 skill/CLI version consistency, or helping the user update, read200 [references/updates.md](references/updates.md).201202## Optional completion accounting203204- Keep stage timing and call accounting disabled by default. Enable it only205 when the user explicitly requests stage timing, call counts, performance206 statistics, or a run summary containing them. Do not collect baselines or207 add an accounting table otherwise.208- When enabled, start a run ledger before the first long or mutating command.209 If the project may use `--llm agent`, snapshot `task status <project> --json`210 and retain the existing `(task, callId)` pairs as the baseline.211- Record wall-clock start and finish times for every workflow stage that212 actually runs. For `auto`, split the ledger at JSONL `stage` transitions;213 keep per-language work distinct (for example `translate:zh-Hans` and214 `align:zh-Hans`) and include repair, quality-check, and export stages when215 they run. Mark reused or skipped stages explicitly instead of assigning216 invented durations.217- After the producer's terminal event, read `task status` once more. Diff218 `completedCalls` against the baseline, group the new accepted calls by their219 stage/kind, and count repair or retry calls in the stage that caused them.220 Unless the user defines another meaning, “calls” means new Agent/LLM calls,221 not shell or CLI invocations. Follow the timing rules in222 [references/agent-tasks.md](references/agent-tasks.md#report-timing-without-double-counting).223- When enabled, end the task with a compact table containing `Stage`, `Wall224 time`, `New calls`, and `Result`, followed by end-to-end wall time and total225 new calls. Use `0` for stages that made no Agent/LLM call and `unobserved`226 when timing evidence is unavailable. Never sum overlapping `queueMs`,227 `workerMs`, or `totalMs` values and present the result as elapsed wall time.228229## Shared projects library and multi-client sync230231- New transcription/translation projects belong in the shared projects232 library so the BaoCut App sees them immediately. Resolve it with233 `"$BAOCUT_SKILL_ROOT/bin/baocut" --json project dir` (macOS default:234 `~/Library/Application Support/BaoCut/projects`); create projects there with235 `project create` unless the user names another location. Projects created in a236 temporary or scratch directory are not added to the library (they would leave237 a dead entry once the directory is wiped); the CLI reports238 `data.registered: false` and warns. Use `project register <path>` only when239 the user explicitly wants such a project listed.240- For URL media, never invent or derive a `--download-dir`. Omit the flag unless241 the user explicitly names a one-off destination; the CLI then honors the242 shared `download.dir` setting. When it is absent, the video lands in the243 user's system download folder (Windows Downloads Known Folder, `~/Downloads`244 on macOS and Linux) — never inside the project.245- After any URL-media run downloads or reuses a video, read its actual path from246 `data.media` in a `transcribe` result or from247 `--json project show <project>` at `data.manifest.media.path`. Tell the user248 that exact path explicitly; do not merely say that the download completed.249- Progress is shared state: the App, the browser preview, and other CLI250 sessions all observe the same project registry and per-project progress251 files. A transcription started from this skill shows up — with live252 progress — in the App and at the preview URL; do not duplicate work you can253 already observe.254- After starting a transcription, always surface the preview URL (see255 [references/workflows.md](references/workflows.md)): open it in the256 agent's built-in browser to verify, and print it for the user so they can257 open the same page in their own browser.258259## Safety and truth sources260261- Treat `transcript.json` `words[]` as the persistent text/time truth. Use BaoCut262 commands or Subtitle Studio apply operations; do not hand-edit word atoms,263 fingerprints, stage stamps, `trans`, or `transAlign`.264- Translation alignment is target-first: freeze natural target-language display265 pieces before mapping them to consecutive sentence-word spans. Never copy,266 infer, or preserve original subtitle cue boundaries for this purpose; the267 local Agent and Cloud Model follow the same contract.268- Treat `timeline.json` as command-owned truth. Source-local cuts and OUTPUT269 clips are separate layers; overlays live on OUTPUT time. Do not hand-edit the270 timeline, AI provenance, revisions, or fingerprints.271- Preserve input media. A normal pipeline writes into a `.bcut` project and does272 not modify the source file. Feed the original container directly; `transcribe`273 decodes and resamples it itself, so extracting a WAV first only repeats work274 the command already does.275- Prefer `--json` for short commands and `--jsonl` for long commands. JSONL276 cancellation is one stdin line: `{"cmd":"cancel"}`.277- AI `--review` output is only a candidate. Inspect it, then explicitly run278 `review accept` or `review reject`.279- A successful polish is not the end of a named multi-speaker task while280 placeholder labels remain. After accepting any polish review, follow281 [the confirmed-speaker sync](references/workflows.md#sync-confirmed-speaker-names-after-polish):282 apply only evidence-backed identities with `speakers rename`, preserve283 ambiguous labels, and report every unresolved speaker id.284- Run `check --strict` before claiming a deliverable is ready. Exit 2 means the285 quality gate found unresolved work; exit 3 means a compatibility or worker286 handoff condition.287- Treat `source-language-mismatch`, `target-language-mismatch`,288 `translation-placeholder`, `translation-source-copy`, and289 `translation-duplicate-collapse` as hard failures. Follow the returned290 sentence-scoped fix command; do not bypass the validator or reuse an older291 task response manually.292- Re-read state after every edit. Exit 0 proves the mutation committed, not that293 its visual timing or composition is correct; use list commands and `frames`,294 `broll preview`, or `animation preview` as appropriate.295296## Capability preflight297298```bash299"$BAOCUT_SKILL_ROOT/bin/baocut" --json spec300"$BAOCUT_SKILL_ROOT/bin/baocut" doctor --quick --json301```302303Complete the mandatory startup version gate before running this preflight.304305Do not treat a `missing` ffmpeg/ffprobe in the doctor report as a blocker and306do not preinstall them. They are on-demand, task-level dependencies: common307workflows (transcription, waveforms, single continuous main-media export) run308without them, and the tasks that do need them (URL download merging, complex309timeline flattening, BCF video encoding) fail at the point of use with a clear310error — install only when such a task actually asks for it.311312In a development checkout, long local `transcribe` and `auto` commands require313an optimized CLI. When only a debug build is current, the resolver runs314`scripts/dev/prepare-bcut.sh` before continuing instead of silently accepting315roughly 2x slower inference. Weigh that against the media length: a release316build of the workspace costs many minutes, while debug inference on a clip317under about 15 minutes costs seconds to a few minutes more than release — so318for such a short clip, when only a *native* debug build is current, export319`BAOCUT_ALLOW_DEBUG_INFERENCE=1` and run it rather than compiling first. Let320the resolver prepare the release CLI for long media, and keep the flag off for321anything else. For an Agent-backed AI pipeline, pass322`--llm agent` explicitly; this prevents a stale `BCUT_LLM_DEFAULT` from323silently selecting a provider that has no usable key.324325## Right-size the run326327Decide the shape of the run from the media length *before* starting anything,328and keep the shape fixed. For a media file or URL, `yt-dlp --print329duration_string` / `ffprobe` or `project show` tells you the duration up front.330331- **Short clip (under ~15 minutes, transcript on one page — up to ~2200 source332 words):** the fast Agent-backed pipeline is a fixed serial chain of five to six333 calls — `analysis` → `polish` → `translate-brief` → `translate` →334 `align-edges`, plus `align-rewrite` only if a chunk is over the hard width;335 closing refinement is not part of the default run. Every336 call has exactly one pending item, so there is nothing to parallelize:337 answer them yourself in the orchestrating session, one after another,338 claim → read contract and payload in the same step → write → `submit339 --next`. Do not start worker subagents, do not spawn a task-tracker of340 seven pipeline steps, and do not read the fleet-sizing rules of341 [references/agent-tasks.md](references/agent-tasks.md) as instructions for342 this case — its "short-job fast path" section is what applies. Two settings343 are part of this shape, not optional tuning: export344 `BCUT_LLM_MAX_WORKERS=1` before starting `auto`, so the engine plans one345 polish page for the whole transcript instead of splitting it across the346 default three worker slots (a 1500-word clip otherwise dispatches three347 ~600-word polish pages plus a `seam-repair`, and every extra page waits in348 the queue while you answer the previous one); and watch the JSONL only for349 `"event":"(batch-dispatch|error|done)"` — a filter that also matches350 `transcribe` stage lines floods the monitor with one event per recognized351 segment. Expected wall clock on native hardware: transcription of a352 2-minute clip finishes within about 3 minutes including model checks, and353 each AI call takes about one minute of your own answering (the single354 `translate` page of an 8–10 minute clip is the largest, several minutes);355 the whole task should be over in roughly 10 minutes with under 40 tool356 calls.357- **Long media (a talk, a lecture):** follow the on-demand worker rules in358 [references/agent-tasks.md](references/agent-tasks.md) — pool size from the359 `workerPlan`, tiers per stage, `--next` chaining.360361Whatever the size, watch the JSONL event stream through one `Monitor` (or362one background tail) rather than polling, and apply a stall budget: a363`phase:"model-wait"` event is an explicit, cancellable wait for another model364download or repair, not a silent stall; keep watching until it advances or365cancel the run if that model work is no longer wanted. Otherwise, on a366short clip, no new `progress` event for 3 minutes during `transcribe` means367something is wrong — check `--json version` (`target`, `backend`, `rosetta`),368`ps` for the process's CPU time, and the project's progress file — do not369wait for a 20-minute monitor timeout. Read the JSONL's `event:"done"` (or an370`error` event) as the terminal signal: after it, do not `task claim` again;371run `check --strict`, `project show`, and the preview verification. In fast372mode, summarize `data.refineOffer[]`, state the optional refinement's benefit373and cost, and ask whether the user wants it; do not start it without a new374affirmative answer.375376When the resolver reports a version or handshake problem, follow377[references/updates.md](references/updates.md) and do not bypass the refreshed378CLI handshake.379380Use `spec` as the machine-readable source of supported commands and flags. Keep381project paths quoted and use BCP-47 language tags such as `zh-Hans`, `en`, or382`ja`. This skill requires CLI spec `>=1.31,<2.0`; if a recipe and `spec` differ,383stop and follow the compatibility error rather than guessing.