DEV Community

Cover image for BrandLoop HackPrinceton
Ishani Bakshi
Ishani Bakshi

Posted on AI-assisted

BrandLoop HackPrinceton

What I Built
We built Brandloop for a small business or a technical founder who has a product and no designer, no marketer and no spare hours. They can build the thing. They do not have time to keep a brand consistent, write creator briefs, or watch every video a creator sends back.

Brandloop starts by reading the brand's website and logo and writing a brand file: colors, typefaces, voice, phrases to avoid, and the claims the product cannot make. Everything else works from that file. It has three parts.

Review: The founder uploads a creator's video. Brandloop checks it against the brand file, fixes what it can, and exports a QA report listing every finding and every decision.

Create: A brief for the next creator is filled in from the brand file. A cheap open model drafts scripts from the brief, a second model scores each draft and can ask for one revision, and then the same brand rules that check videos check every line. The app also builds a brand kit with no model involved: a poster, social sizes, logo files, web tokens and print pieces, laid out from the brand file's colors and fonts.

Pulse: This collects public comments about the brand and scores each one with a local sentiment model. It finds the terms that are spiking and groups the comments into topics. It maps who replies to whom, so the commenters fall into communities, and each community gets its own sentiment and topics. Two word lists flag comments that ask whether a post is an ad and comments that dispute a product claim. Commenter names are replaced with pseudonyms before anything is stored to maintain privacy.

Pulse feeds back into the brand file. If replies to posts that use a certain phrase run more negative than usual, Pulse proposes adding it to the phrases to avoid, with the numbers behind the proposal. A rising term with positive sentiment becomes a suggested content idea. Each proposal shows up as a diff the founder accepts or rejects. An accepted one changes the brand file, so the next brief and the next review use it. Nothing changes the brand's core identity without the owner unlocking it.

The check that matters most in Review is disclosure. A paid post needs an #ad or "paid partnership" label that a viewer can see, and a founder with no legal team is the one who hears about it when the label is missing. So the rule measures visibility. The label has to be on screen within three seconds, stay for at least three, be at least 4% of the frame tall, and have a contrast ratio of at least 4.5.

As our general engineering logic, wrote one rule for the whole codebase before anything else: if something can be measured, compute it. Colors, contrast, on-screen text, the transcript, every flag and every score come from ffmpeg, Apple's on-device text reader, a local Whisper model and plain Python. A language model writes script drafts and a two-sentence description of the brand's voice. It does not decide whether a video passes.

By Saturday morning the test suite was green on synthetic videos we had generated ourselves. Then we loaded ten public videos about Poppi, the soda brand we used as a case study, and the bugs below showed up.

The badge that read as "pe#"
When a video has no disclosure, the fix is to draw an #ad badge and composite it over the first few seconds. We applied it to one video and the score did not move: 78 before, 78 after. The re-review said the badge was visible for 1.5 seconds. It was on screen for 3.5.

Here is what the text reader returned for the badge, frame by frame:

Time Text read Confidence
0.0 s #ad 100
0.5 s pe# 50
1.0 s #ad 100
1.5 to 3.0 s pe# 50

Turn #ad upside down and it looks like pe#. In those frames the creator was holding a box of cans upside down. Apple Vision picks a reading direction for each line of text, and with upside-down print elsewhere in the frame it read our upright badge the wrong way round. It did the same to the player's timestamp, which came back as 22:00/10:00.

The fix was to ask Vision for each line's corners, spot a line it had read upside down, and read that crop again on its own. Text that really is upside down still reads upside down the second time, so it is left alone. We did not loosen the three-second rule. After the change the same video scored 93.

The contrast measurement was also telling us something true. Black on the brand's pink is 4.95 to 1 on paper and 4.84 after video encoding, barely over the floor. The badge now picks the first color pair that clears the minimum by a full point, which for this brand means black on white.

The website that hid its own text
Onboarding reads a brand's site in a headless browser and pulls colors, fonts and sample copy. Run from the command line it produced a good voice description. Run from the app it said no copy was found.

Both paths ran the same code. The difference was timing. About one second after loading, the site opens a pop-up and sets aria-hidden on the whole page behind it. Our collector skipped anything under an aria-hidden parent, which is a sensible rule until the hidden element is the entire page. Reading once a second, we got 11 strings at load and none after.

The collector now ignores an aria-hidden element when it covers at least half of the page's headings and paragraphs.

Picking a script model with a blind judge
Scripts are the one place a model writes for us, so we benchmarked cheap open models before choosing one. Each model wrote three scripts for each of 12 briefs. We scored them on our deterministic brand rules, a rubric critic, and a blind pairwise judge that saw every pair in both orders and never saw model names. If the judge disagreed with itself across the two orders, the pair counted as a tie.

Model Rule pass Blind win rate Cost per 1k scripts
GLM 5.3 Flash 100% 91% $0.48
MiniMax Flash 100% 80% $2.21
Kimi K2.5 97% 78% $3.29
DS V4 Flash 100% 47% $0.20
Gemma 3 27B 100% 36% $0.20
Phi-4 94% 15% $0.17
Llama 3.1 8B 89% 2% $0.06

GLM 5.3 Flash won, at between a fifth and a seventh of the cost of the two models closest to it.

Getting that table took four starts. The first run made about 1,250 calls one at a time and was on course to take about three hours. The second, running calls in parallel, lost three models to provider errors. One of those was Gemma 3 12B, which had won our first three-model run that morning with a 98% win rate and was no longer being served by the afternoon. The third run hung for 40 minutes on a stalled connection that never timed out. Each failure left a fix behind. Calls now run in parallel, a failed call is retried, and every call has a timeout.

The limits are plain. Twelve briefs for two made-up brands is a small sample. The critic and the judge are the same model family, and we have not checked the judge against human picks. Thirty of the 504 judge calls failed when our API credit ran out near the end.

**What we would do differently
**We would load real videos on day one. Every bug in this post was invisible on synthetic fixtures, because we had built the fixtures to be readable by the same tools that read them.

Additionally, most of the code was written by coding agents working from a written spec, with a second agent reviewing each task before the next one started. One line in the spec says never to weaken a test or a threshold to make it pass. When the badge bug appeared, that line is why the three-second rule stayed and the text reader got fixed.

Demo
The demo starts from an empty app. We type the brand's name and website, drop in a logo and four product photos, and the app builds the brand file: colors ranked by how much of the page they cover, the two typefaces read from the site's own font files, and the voice description. That took 12 seconds in our dry run.

Then we drop in a folder of ten videos. All ten reviews finished in 2 minutes 37 seconds on a laptop, because the slow media steps (pulling frames, the transcript, reading on-screen text) are cached by each file's fingerprint. Every rule, finding and score still runs fresh. We open a creator video, accept the disclosure fix, and the score goes from 77 to 92. The QA report exports as a PDF with every finding, every decision and a checksum of the fixed file.

The last part builds brand materials from the same brand file with no model involved: a poster, social sizes, logo files and print pieces, 18 items in 8 seconds. The same brand file and the same text give the same files, byte for byte.

Then we open Pulse, type a YouTube search for the brand, and run it live. Comments come back in about ten seconds, and the screen fills with sentiment over time, topics, communities and the flagged comments.

The code is at github.com/Ishani-B/hackprinceton.

**Partner Technologies
**We did not build Brandloop on any of the MLH partner technologies offered at this event. The video pipeline is ffmpeg, a local Whisper model, Apple Vision for on-screen text and CLIP for image matching. The app is FastAPI and SQLite behind a React front end. Script drafts come from open models served through Hugging Face, with Claude as the critic and judge, and the agent that plans a brand's week is built on LangChain's deepagents package.

**Hackathon Experience
**We built this at HackPrinceton Fall 2026, November 13 to 15, as a team of four. The four of us are freshmen and Princeton and met largely through our introductory engineering coursework. For all of us, this was either our first or second ever hackathon, and definitely our first college hackathon, and so, one of the most enriching experiences during HackPrinceton was talking to and being mentored by the judges and companies present at the event. We got to learn about pitching, interviewing customers, vibecoding, and LLM frameworks, which was overall an incredibly exciting experience.

Top comments (0)