Releases: mupozg823/timecode-agent
Release list
v0.4.0
A frozen corpus thaws, procedures become skills, and cuts land on the beat.
Upgrading
The promise from v0.3.0 is delivered: legacy workspaces promote in place.
v0.3.0 made pre-revision workspaces read-only for new evidence and deferred
in-place promotion because the obvious implementation destroyed the data it
was meant to save. va rebind (ADR-0006) now backfills a frozen workspace
into revision binding: dry-run by default, apply re-probes the source and
journals the transition. When the source media is gone the tool refuses —
a rebind without re-measurement would bind evidence to nothing, so those
workspaces stay read-only by design and va audit keeps naming the split.
Understanding → skills
- Procedure knowledge layer. Recurring
task-*/tool-*tagged steps
compile into per-task procedure pages with timestamp anchors and an
explicit evidence enumeration per step (visual_verified / speech_only /
agent_estimated) — the execution-critical distinction, since transcripts
recover procedure skeletons but not exact tokens (menu paths, values,
commands). - Approval-pending skill drafts.
va skillgencompiles promoted
procedures (3+ recurring videos) into skill drafts whose execution steps
come from visually grounded checkpoints only; speech-only steps and
precision warnings land in a mandatory known-weaknesses section. Drafts
stay inactive until a human approves. - Intent-coherence gate. A task whose sources disagree on tooling does
not promote: tool tags form a strict-majority consensus, and a source
sharing nothing with it blocks the draft until retagged or split —
mixed-purpose corpora silently corrupting execution values is the failure
this closes.va skillgen --routereports, per task, which gate still
blocks promotion (draft / blocked-intent / needs-workspaces). va auditgrew matching axes: procedure maturity, evidence distribution,
visually unconfirmed exact tokens, and image-index consistency.
Editing
- Beat-quantized rhythm lane.
va beatsextracts a fixed-tempo beat
grid (beats.json: bpm, beat times, 1s energy arc) from a music track;
va beat-evalmeasures every output-timeline join of a sequence against
the nearest beat and gates at p90 |offset| <= 40 ms by exit code. Its
--snapoutput is a proposal only — applying it is a new sequence
revision, so the decision ledger remains the only writer. - The skill surface now carries the montage grammar that goes with it:
Kuleshov re-contextualizing, one-point push-ins, chapter letterboxing,
and an isolated grade layer.
Search
- Persistent BM25 index.
.tca-search-cache.dbis a
fingerprint-incremental FTS5 inverted index (word + trigram, RRF-fused)
with hybrid Korean recall; warm corpus queries drop from ~114 ms to
16–23 ms. Exact tokens are indexed, a majority-coverage fallback catches
scattered-term queries, and rank ties break understanding > screen >
transcript.
Story Map and view
- Story Map. A read-only projection of both ledgers onto one
proportional timeline: checkpoint tracks with grounding cross-highlight,
an edit lane with cut provenance back to source spans (excluded regions
stay visible), rejected alternatives, and conditional speaker ribbons. - The corpus browser renders the edit ledger (cuts, rejected alternatives,
evidence anchors), keeps human-facing Korean surfaces consistent, and
gates serverless operation, legibility and render performance with
regression tests. va askanswers its supported count intent with a canonical evidence
envelope projected to Korean/English human text or compact agent JSON —
evidence is computed once, uncertainty intervals are explicit, and
count: 0never claims "none".
Observability and integrity
- Frozen-corpus state is a first-class surface: audit names bound versus
read-only workspaces instead of letting writes fail later. - Mixed-form videos (narration + long silent stretches) are detected at
brief time, so a timelapse segment is not covered by one
transcript-shaped checkpoint. - Wiki slugs derive from labels character-escaped and injectively — two
labels can no longer race for one filename — and slug reassignment is
detected by a regression gate. - A real-corpus smoke script joins the verification procedure, observing
scale that synthetic fixtures cannot.
Install
git clone https://github.com/mupozg823/timecode-agent.git && cd timecode-agent
uv tool install --python 3.12 . # add '.[diarize]' for pyannote diarizationRequires ffmpeg/ffprobe on PATH, plus yt-dlp for URL ingest. See the
README
(한국어).
Full Changelog: v0.3.0...v0.4.0
v0.3.0
Evidence you can check, and a corpus that says what it does not know.
Upgrading
Workspaces created before v0.3.0 accept no new records. ADR-0005 binds every
record to a source/transcript/timing revision, and a workspace that predates
those bindings is read-only for new evidence. Any command that appends a durable
record — a checkpoint, an edit decision, a diarized speaker turn, captured-image
provenance — refuses there:
RevisionBindingError: legacy workspace is read-only for new evidence;
ingest into a fresh revision-bound workspace before appending records
Everything already recorded stays readable. Commands that only read or derive
(va audit, va search, va index, va view, va wiki, va status) are
unaffected, and so is the NLE handoff: va export skips the decoded-CFR proof
when a workspace carries no source revision.
This release ships no migration command. va audit now names the split
(binding_counts in --json), so a frozen corpus is visible up front instead
of surfacing later as a rejected write. To keep analyzing a frozen video,
re-ingest it to a fresh -o path; the new workspace is bound and accepts
records.
In-place promotion is deferred to 0.4.0 because the obvious implementation
destroys what it is meant to save. Manifests written before v0.3.0 mostly lack
the stream-timing block the temporal contract requires, so switching the
contract on makes every existing line fail validation, and the readers skip
invalid lines by design — a measured trial dropped every checkpoint and
sequence in the workspace to zero. Promotion must therefore re-probe sources
first and roll back on a post-condition check.
Integrity
- Revision-bound workspaces (ADR-0005). Re-ingest used to replace only
manifest.jsonandtranscript.jsonwhile keeping checkpoints, sequences and export receipts. Transcript support validated segment IDs and time overlap — not transcript content or generation — so an old claim could appear supported by unrelated new text. Ingest now seals the source bytes before transcription, publishes content-derived source/transcript/timing revisions, and binds every new record to them. A published workspace is immutable to ingest; re-transcription uses a fresh-opath. - Diarization is crash-recoverable. Rewriting canonical transcript segments takes an exclusive lease and journals the prior state; a process loss is rolled back idempotently on the next load.
Handoff
- The decoded-CFR proof is persisted. Revision-bound EDL/XML/FCPXML/OTIO requires proving the whole decoded timeline against one rational cadence. That proof lived only in memory, so every export re-enumerated every frame. It is now bound to the source content hash and timing revision: the same handoff drops from 80.71 s to 0.12 s on a 757.6 s AV1 source, with byte-identical output.
- Constant-rate video with a longer audio track is no longer blocked. Frame-count verification compared against the container duration, which is the maximum across all streams. A 30 s video carrying 33 s of audio expected 990 frames and found 900, so the handoff failed closed on perfectly regular video. Verification now uses the video stream's own length.
Observability
va auditprints both evidence axes. Declared (what a checkpoint cited) and grounded (whether that evidence resolves now) are shown side by side, and the grounded axis names unsupported terminal checkpoints — including zero. Printing only the permissive axis made a corpus read as fully grounded when 46 of 165 terminal checkpoints had no resolvable support.va wikistates what it could not carry. The wiki only admits claims whose evidence resolves; it now reports how many terminal checkpoints were left out and which workspaces they came from. An unexplained absence reads as "that never happened".- Corpus reads are recorded.
search,index,viewandwikiappend to a read ledger, so whether the knowledge is actually used is observable. Query text is never stored — only a hash, its length, and the hit count. Zero-hit reads are counted separately: they are questions the corpus could not answer. - Entity slug reassignment is gated. Slug assignment depends on the pages already on disk, so ingestion order can hand an existing filename to a different entity. The link stays valid while its target changes, which broken-link checks cannot see by construction. Regeneration now records the mapping and reports reassignment.
View
- Silent playback failure now speaks. A workspace whose source lives outside it points at a
file://path. Served over http, the browser blocks that media and the player showed a black frame with no explanation. The page detects the protocol mismatch and says what to do. - The graph shares the list filter instead of drawing every workspace while the table reads "3 of 39", and labels avoid collisions instead of overprinting each other.
Install
git clone https://github.com/mupozg823/timecode-agent.git && cd timecode-agent
uv tool install --python 3.12 . # add '.[diarize]' for pyannote diarizationRequires ffmpeg/ffprobe on PATH, plus yt-dlp for URL ingest. See the README (한국어).
Full Changelog: v0.2.0...v0.3.0
v0.2.0
Transcript-first video understanding: infer from speech, verify only the uncertain moments, and keep the evidence as a reusable index.
Understanding and evidence
- Transcript collapse is detected and repaired.
va ingestcompares transcribed duration against VAD-detected speech and records the ratio astranscript_coverage; below 0.5 with at least 60 s of speech it retries and keeps the better attempt, stampingtranscript_repair. A tail retranscribe resumes from the stall point instead of redoing the whole file. - Uploader captions come first. When the source already carries an original-language caption track, it is adopted instead of re-transcribing, which turns a 43-minute ingest into seconds.
- ASR provenance.
asr_backendrecords which backend produced the adopted transcript, with a+<backend>(tail)suffix when a tail repair contributed. It isnullon the caption path, wheretranscript_sourceidentifies the origin. - Checkpoint field flags. Build a checkpoint from
--span,--status,--hypothesis,--confidenceand friends instead of JSON. Mixing the two input paths is rejected, including an explicitly empty value.
Editing and handoff
- A separate edit ledger. Cut decisions live in
sequences.jsonland never rewrite the fact ledger. Promotion requires evidence, and terminal promotion now requires coverage of the cut body — overlap alone is not coverage. - Exports:
srt,edl,xml,fcpxml,otio,md, with--idsargument order as cut order, revision pins carried into the handoff, and a Receipt sidecar proving artifact integrity. - Boundary evaluation (
va boundary-eval) plus a join-risk metric that flags jump-cut hazards.
Corpus and reading
va viewrenders a static corpus browser and workspace player — no server, click a scene record to jump the player to its timestamp.va index/va wikibuild a markdown-first vault with entity pages, a tag index, and a relation ledger.- Search fuses per-family ranking so understanding is not buried under raw transcript matches.
Runtime
- Experimental Windows support (workspace lock falls back to
msvcrt, exercised by a CI smoke job). pyannotemoved to thediarizeextra, so the default install stays light; an MLX ASR path is available on Apple silicon.
Interface language
Documentation is bilingual, but the running tool is not uniform: most --help text is English while diagnostics, the va brief/va status summaries, and the va view UI are Korean, and there is no locale switch. Timestamps and structural fields are language-neutral; prose is not — your NLE handoff speaks whatever language the ledger does, and the agent writes those fields in the language you ask in.
Install
git clone https://github.com/mupozg823/timecode-agent.git && cd timecode-agent
uv tool install --python 3.12 . # add '.[diarize]' for pyannote diarizationRequires ffmpeg/ffprobe on PATH, plus yt-dlp for URL ingest. See the README (한국어).