Inspiration

Small video, game and podcast teams ship releases built from dozens of borrowed pieces: a CC BY photo cropped for the poster, a field recording turned into a rain loop and layered into a storm bed, an accordion track cut down for the trailer. The licence travels with each piece through every edit, but the spreadsheet that tracks them only knows about the file that was dropped into the timeline.

What it does

credit-trail models deliverables, assets, edits, licences and creators as a graph and answers the questions that matter before release:

  • Can this trailer run as an ad? — no NonCommercial source anywhere upstream, even three edits deep.
  • Who must the credits name? — everyone whose attribution licence reaches the deliverable through any chain of edits.
  • Was a NoDerivatives source edited? — a crop is a derivative.
  • What breaks if a creator withdraws their work, or a licence turns out to be wrong? — every deliverable with a path to it.

Every answer comes with the chain of edits that causes it. The sample project, a fictional short film called Low Tide, has five planted mistakes; credit-trail check finds all five and nothing else.

What connects to what: (:Deliverable)-[:USES]->(:Asset)-[:DERIVED_FROM*]->(:Asset)-[:LICENSED_UNDER]->(:License), (:Asset)-[:BY]->(:Creator), and (:Deliverable)-[:CREDITS]->(:Creator) for what the credits actually say.

How we built it

Python on the embedded relate-db client — no server, no account. Variable-length traversals drive check, credits and impact; a full-text index with SEARCH … SCORE AS drives find, and each hit is expanded through the graph to the deliverables that use it. The import runs in one transaction with uniqueness constraints and MERGE. Every query command opens the store read-only, and relate serve --mcp stdio --read-only lets an agent ask the same graph. A self-contained HTML report draws the graph with every failing chain in red.

Relate mode: a directory store with the JSON codec. A licence review is something a team signs off on, so the graph lives in the repository and changes through pull requests: store/graph.json is deterministic and diffable, and a fresh clone opens it read-only without rebuilding.

Challenges

A fresh clone at first refused to open the committed store read-only — the store's marker files and WAL segment have to be committed with the graph. A regression test now checks that the committed store opens read-only and matches a rebuild from its manifest.

What's next

Import from editing timelines (EDL/OTIO) and asset folders, per-territory licence terms, and a CI step that fails a release branch when check finds an error.

Built with (statement)

  • Relate capabilities: embedded Python client (relate-db 1.0.1), Cypher variable-length traversal, transactions, uniqueness constraints, full-text index and SEARCH, read-only opens, directory store with the JSON snapshot codec, relate serve --mcp stdio (Relate CLI 1.0.1).
  • Third-party tools: Python, pytest; the demo video was made from HTML scenes rendered with headless Chrome and assembled with FFmpeg.
  • AI tools: Code, documentation and the demo scenes were written with the help of an AI coding assistant (Claude Code); all output was run and tested locally.

Try it

git clone https://github.com/kimdooo-a/credit-trail.git && cd credit-trail
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scriptsctivate
pip install -e ".[test]"
credit-trail demo        # then open report.html
pytest

Built With

Share this project:

Updates

Submission history