v0.19.0 — the moat and the ledger
·
23 commits
to feat/cutting-room-v0.17
since this release
Added — The Moat and the Ledger (every write is recorded, every ship is reviewed, and the shots can be found)
- Operation journal —
fcpxml/journal.py, an append-only JSON-lines
ledger under~/.fcp-mcp/journal/(dir mode 700). Every write and every
preview render passes through one seam inserver.pyand appends
ts, tool, action, args, input{path,sha256}, output{path,sha256}. Records
hold paths and hashes, never content. The project is the FOLDER: one ledger
per input directory follows the suffix chain wherever it goes.
FCP_MCP_JOURNALrelocates it, oroffdisables it. organizegroup —organize_keywords(add / remove / replace),
organize_rate(favorite / rejected / clear),organize_roles, all over a
clip selection by glob name, keyword or role, written as an_organized
copy.historyreads the ledger as a table with ages;undomoves the
last N recorded outputs to<journal>/undone/— it never deletes, and
refuses when the file's hash no longer matches the record.organize_auto— proposes keywords per clip from what the index
already holds (shot captions, transcript text) and from transcript
sidecars. It never transcribes and never captions; with nothing derivable
it says so and names thefind_indexcall that would fix that. Proposals
print the exactapply=truecall; nothing is written until it is passed.- Review gate on
deliver—export_csv,export_edl,
export_fcp7_xml,export_resolve_xml,export_role_stemsand
push_to_fcpnow refuse when the journal holds nopreview_renderwhose
input hash matches the file's current state, and name the exact
preview_rendercall that satisfies it.confirm_unreviewed=trueships
anyway and stamps the result Shipped UNREVIEWED. With the journal off the
gate refuses to certify anything and says why. findgroup —find_shotsanswers "find the shot where…" as a router
with the tier named on every hit: tier 1 transcript words, tier 2 metadata
(clip names, keywords, marker names and notes, event labels), tier 3
vision captions. Hits carry source in/out, timeline position, score and a
why. Vision is consulted whenvisual=true, when the query reads as
visual, or when the cheaper tiers came up short — never more than
MAX_LIVE_FRAMES(20) live captions per call, the rest from the cache.
find_indexwarms transcripts, scenes and (opt-in) captions for every
source and reports each as done / skipped / unavailable with the reason.
find_to_timelineassembles the hits into a_foundselects reel.- Offline shot captions —
fcpxml/vlm.pyruns an MLX vision model
(mlx-community/Qwen2-VL-2B-Instruct-4bitby default,FCP_MCP_VLM_MODEL
to change it) over the framesscenesfound.HF_HUB_OFFLINE=1and
TRANSFORMERS_OFFLINE=1are set BEFOREmlx_vlmis imported; a model
that is not in the local Hub cache is reported with the exact
hf download <id>command, never fetched. Captions are stored once in the
index (get_shots/put_shots) and invalidated with the source. [find]extra —pip install "fcp-mcp-server[find]"pullsmlx-vlm
andnumpy. Apple Silicon only; everywhere elsefindstill answers from
transcript and metadata and says vision is unavailable.- Diversity constraint —
fcpxml/diversity.py.auto_rough_cuttakes
min_source_separation(0–20, default 0): no source may recur within that
many cuts, and every assembly now reportsDiversity: 0.50 (1 of 2 cuts change source).find_to_timelinedefaults to 1 and also drops hits whose
captions are near-duplicates of the previous pick. - Writer bulk edits —
select_clips,bulk_keywords,bulk_rating,
bulk_rolesonFCPXMLModifier; new<keyword>/<rating>children go
in through_dtd_insert, so the DTD element order survives. - Env —
FCP_MCP_JOURNAL,FCP_MCP_VLM_MODEL. - Tests —
test_journal.py,test_journal_wiring.py,test_review_gate.py,
test_organize.py,test_organize_group.py,test_diversity_constraint.py,
test_find.py,test_vlm.py,test_find_group.py(the never-transcribes /
never-downloads guards, the undo hash refusal, the diversity mutation check).
Changed
- BREAKING for scripted callers — the six
deliveractions above now
refuse an unreviewed file. Render it withpreview_renderfirst, or pass
confirm_unreviewed=true. - Tool groups: 13 (was 11), dispatching into 88 operations (was 79). The
group-count guard intest_tool_groups.pymoves from 12 to 14. server.__version__0.19.0, andtest_version.pystill holds it to
pyproject.toml.
Known
- Vision captions need Apple Silicon (
mlx-vlm); there is no CPU/CUDA path. - Tier-3 similarity is lexical (Jaccard over caption words) until embeddings
land; captions are cached so a better ranker reads the same rows. - Marker
startis still written in source time byedit_markers; the
timeline-time fix is on the deferred list.