Repository navigation
M1: GAM as the library - #2
Merged
Merged
Conversation
Find footage for a scene in GAM, including where something is said in a video, and place that moment in the scene. Either as muted b-roll under the narration, or as a clip that plays its own sound. The moment becomes the visual's trim: - padded so a cut does not clip a word; - sized by a search placeholder's `moment` when it asks for one; - kept inside the asset. Search placeholders resolve the same way. Every scene showing one gets the trim. GVC's server calls GAM as the signed-in user by forwarding their own Notes token, so GAM's ownership checks hold and there is no service account. A token is only forwarded after this app has verified it. GAM down is a 502 gam_unavailable. GAM refusing the session is gam_rejected_session, which names the JWT secret mismatch. Thumbnails and names are looked up per page load, because GAM's signed URLs expire. They load straight from GAM, so the CSP's img-src and media-src carry GAM_BASE_URL, templated like the Notes origin. A note pushed from Notes can now finish the hand-off: "Copy into GAM" moves each file the spec still points at inside the note into the user's library. Each ref is replaced under the same key, so nothing that used it changes. It saves one version. Failures stay to retry. Only /media/ paths on the configured Notes are fetched, since a pasted spec is untrusted input, and the size cap is enforced while the file streams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fiRJAt34ag62iPiuMkNhm
davior
marked this pull request as ready for review
October 16, 2026 04:36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second milestone (plan of attack, M1). GAM becomes GVC's media library.
What you can do with it
Find footage for a scene in GAM, including where something is said. Search "people talking about water" and a hit on a transcript line comes back as that moment. Matched words are highlighted, and the hit shows the time range and a preview of the clip.
Place a moment two ways:
Either way the moment becomes the visual's
trim. It's padded by 0.5 s so the cut doesn't clip a word, sized by a placeholder'smomentwhen one asks for it, and kept inside the asset.Pictures are placed whole.
Each scene shows its picture or footage: thumbnail, name, trim, or why there isn't one ("Still in the note", "No longer in the library", "To find: …").
"Footage still to find" lists the unresolved
searchplaceholders. Resolving one trims every scene that shows it."Copy into GAM" finishes a push from Notes. Every file the spec still points at inside the note moves into your library, under the same key, as one new version. Failures stay to retry.
How
CallerToken), only after verifying it, so GAM's ownership checks apply and there's no service account.gam_unavailable. GAM refusing the session gives 502gam_rejected_session, which names theJWT_SECRET_KEYmismatch.schemas_gam.py), so a field GAM renames breaks one file.POST /api/gam/assets/lookup). The browser loads them straight from GAM:img-srcandmedia-srcnow carry${GAM_BASE_URL}, templated at container start like the Notes origin, andcsp.test.tsguards it./media/paths from the configured Notes, since a pasted spec is untrusted input. The size cap (NOTE_MEDIA_MAX_MB) is enforced while the file streams./media/*without auth, so GVC fetches the files directly. That is Notes' existing behaviour; the plan doc now says so.end_time, a moment is taken as start + 5 s.New settings
GAM_TIMEOUT_SECONDS(default 30) andNOTE_MEDIA_MAX_MB(default 4096), in.env.exampleand compose.GAM_BASE_URL, for the CSP.Tests
pytest -qpasses, 61 tests. GAM and Notes are faked behind onehttpx.MockTransport(tests/fake_siblings.py). The tests cover:end_time;npm test(76 tests:momentTrim,placeHit,resolveSearch, the footage search and the visual strip) and build all pass.trim: {in: 20.5, out: 28},audio: "mute".from: "gam",pending_note_mediawent to 0, and the thumbnails show.Not in this PR
🤖 Generated with Claude Code
https://claude.ai/code/session_016fiRJAt34ag62iPiuMkNhm
Generated by Claude Code