{"generatedAt":"2026-07-26","canonicalUrl":"https://abhishekvulla.com","person":{"@context":"https://schema.org","@type":"Person","name":"Abhishek Vulla","email":"mailto:abhishek.vulla@gmail.com","jobTitle":"Computer Science and Design student","affiliation":[{"@type":"CollegeOrUniversity","name":"SUTD"}],"sameAs":["https://github.com/AbhishekVulla","https://www.linkedin.com/in/abhishek-vulla/"]},"projects":[{"slug":"learnloop","title":"LearnLoop","url":"https://abhishekvulla.com/work/learnloop","summary":"An AI study layer inside SUTD's learning platform. It answers from approved course material and keeps the exact source slide beside every response.","primaryResult":{"value":"40 students","label":"piloted across two classrooms"},"supportingResults":[{"value":"S$2,000","label":"university build funding"},{"value":"S$7K test waived","label":"after redesigning the trust boundary"}],"engineeringHook":"Passed SUTD EduTech's first cybersecurity review by moving students behind LTI 1.3 and EASE SSO, removing public signup and reducing Blackboard access to least privilege.","systemDesign":"Passed SUTD EduTech's first cybersecurity review by moving students behind LTI 1.3 and EASE SSO, removing public signup and reducing Blackboard access to least privilege.","stack":["TypeScript","FastAPI","PostgreSQL","pgvector","RAG"],"links":[{"label":"Open LearnLoop","href":"https://learnloop.up.railway.app/"},{"label":"Watch the demo","href":"https://www.youtube.com/watch?v=5xTbykJpGWI"}],"media":[{"id":"demo","type":"video","label":"Product demo","alt":"LearnLoop tutor and handwritten grading workflow","caption":"A walkthrough of the source-grounded tutor and handwritten submission flow."},{"id":"newsletter","type":"document","label":"SUTD newsletter","alt":"March 2026 SUTD Design.AI newsletter cover featuring LearnLoop","caption":"SUTD Design.AI featured the classroom pilot in its March 2026 newsletter."},{"id":"tutor","type":"image","label":"Tutor","alt":"LearnLoop answering a course question beside the lecture slide it cites","caption":"The tutor keeps the answer and its source slide in the same view."},{"id":"simulation","type":"image","label":"Interactive lesson","alt":"Interactive LearnLoop simulation embedded beside course material","caption":"Course concepts can open into an interactive simulation without leaving the study flow."},{"id":"cohort","type":"image","label":"Cohort analytics","alt":"LearnLoop cohort analytics showing common student misconceptions","caption":"Instructors can see the concepts a cohort is struggling with instead of reading isolated chat logs."}],"caseStudyMarkdown":"## What it does\n\nCourse material at SUTD lives across slides, assignments and the LMS. LearnLoop adds an AI study layer inside that workflow. It retrieves from approved course material, answers beside the source slide and supports both Socratic tutoring and handwritten submissions.\n\n## The result\n\nThe product was piloted with 40 students across two classrooms and received S$2,000 from SUTD's Baby Shark Fund. It passed SUTD EduTech's first cybersecurity review after I redesigned who could access it and what the LMS integration was allowed to read.\n\n## The security decision that changed the product\n\nThe quoted penetration test cost more than the project's funding. I did not weaken the review. I moved students and instructors behind LTI 1.3 and the university's EASE login, removed public signup and reduced Blackboard access to least privilege. That changed the trust boundary enough for the S$7,000 test to be waived.\n\nCitations are still part of the response contract, not decoration added after generation. Retrieval never ignores the course boundary. A strong semantic match from another class is still the wrong answer.\n\n## What changed\n\nThe first version tried to do too much. The useful version became narrower: answer from the course, show the evidence and stay out of the lecturer's way. That constraint made the product easier to trust and easier to fit into the LMS.\n\n## What I learned\n\nThe chat box was the easy part. Shipping inside a university meant authentication, privacy and least-privilege access mattered more than another model feature."},{"slug":"rankr","title":"Rankr","url":"https://abhishekvulla.com/work/rankr","summary":"An AI SEO agent for Singapore SMEs that finds demand and competitor gaps, drafts from real audience questions and helps businesses show up on Google.","primaryResult":{"value":"2 signed LOIs","label":"from Singapore SMEs"},"supportingResults":[{"value":"Top 20 of 800+","label":"UCWS participants"},{"value":"US$10,000","label":"OpenAI credits awarded at UCWS"},{"value":"DR 2 testbed","label":"cited by ChatGPT"}],"engineeringHook":"A perfect on-page score produced no rankings, so I rebuilt the system around authority, demand and inspectable search evidence.","systemDesign":"I built the client pilot site, publishing layer and SEO/GEO plumbing. Differentiated titles pulled pages out of Google's \"crawled, currently not indexed\" state.\n\nDataForSEO finds the gaps. Real Reddit threads ground each angle instead of producing another keyword list. Coverage memory stops the agent from pitching the same topic twice, and nothing reaches the client site without approval.","stack":["Next.js","TypeScript","Python","Search APIs","LLM evaluation"],"links":[{"label":"Open Rankr","href":"https://rankrhq.com/"},{"label":"Try the checker","href":"https://rankrhq.com/tools/ai-visibility-checker"},{"label":"Watch the demo","href":"https://youtu.be/Q8OaSs4zndw"}],"media":[{"id":"demo","type":"video","label":"Product demo","alt":"Rankr homepage showing one AI agent moving from competitor research to human-approved publishing","caption":"Rankr researches competitor gaps, drafts the useful page and waits for approval before publishing."},{"id":"citation","type":"image","label":"ChatGPT citation","alt":"ChatGPT citing the Lullaflex SEO testbed","caption":"The low-authority Lullaflex testbed earned a real citation from ChatGPT."},{"id":"ucws","type":"image","label":"UCWS pitch","alt":"Abhishek presenting the Rankr system at the UCWS Singapore finals","caption":"Rankr reached the Top 20 from more than 800 UCWS participants."},{"id":"ucws-certificate","type":"image","label":"UCWS finalist","alt":"UCWS Singapore Top 20 finalist certificate for Rankr","caption":"Rankr reached the Top 20 from more than 800 UCWS participants."},{"id":"benchmark","type":"image","label":"SME benchmark","alt":"Rankr benchmark comparing search readiness across six Singapore SME sectors","caption":"The benchmark compares 42 responding sites by sector instead of hiding them behind one score."},{"id":"planner","type":"image","label":"Live testbed tool","alt":"Interactive Lullaflex bedroom planner built as a citable testbed asset","caption":"The live testbed included a real planner because useful tools earn links and citations that commodity articles do not."}],"caseStudyMarkdown":"## What it does\n\nRankr combines market research, site diagnostics and content planning. Each recommendation links back to the evidence that produced it, and the public checker gives a small business a useful result without a sales call.\n\n## The result\n\nTwo Singapore SMEs signed letters of intent. Rankr also reached the Top 20 from more than 800 UCWS participants. Each finalist team received US$10,000 in OpenAI credits, and the project received S$2,000 from SUTD's Baby Shark Fund.\n\n## The experiment that changed the product\n\nWe pushed a fresh test site into the nineties on our own on-page checker. It still had almost no search authority and almost no traffic. The score looked good and explained very little.\n\nThat failure forced a rebuild. The next version separated technical hygiene from authority, demand and AI visibility. One page from the DR 2 Lullaflex testbed was later cited by ChatGPT, which gave us a much better piece of evidence than another internal score.\n\n## System design\n\nI built the client pilot site, publishing layer and SEO/GEO plumbing. Differentiated titles pulled pages out of Google's \"crawled, currently not indexed\" state.\n\nDataForSEO finds the gaps. Real Reddit threads ground each angle instead of producing another keyword list. Coverage memory stops the agent from pitching the same topic twice, and nothing reaches the client site without approval.\n\n## What I learned\n\nAn SEO score is only useful if it predicts something outside the tool. The testbed made it cheap to prove our own metric was weak before a client had to."},{"slug":"proof","title":"Proof","url":"https://abhishekvulla.com/work/proof","summary":"Proof reads a GitHub repository, writes a launch script, guides the recording and renders the result into a product video.","primaryResult":{"value":"1st Runner-Up","label":"'Sup Build2026 · 300+ builders · S$5K+ in prizes"},"supportingResults":[{"value":"Invite-only beta","label":"running at tryproof.org"},{"value":"20% faster renders","label":"after load-testing the safe concurrency limit"}],"engineeringHook":"Durable jobs survive redeploys, direct-to-storage uploads bypass request limits and bounded Chromium workers avoid ffmpeg memory crashes.","systemDesign":"Rendering is the part I own end to end. I found and patched an SSRF and an IDOR in my own pipeline. The render worker now requires a token, and row-level security keeps each user's jobs separate.\n\nJobs are queued, persisted and resumed instead of living inside a browser request. Each attempt is kept so a failed render can be inspected instead of disappearing into a retry.","stack":["Next.js","Remotion","Whisper","FFmpeg","Docker"],"links":[{"label":"Open Proof beta","href":"https://www.tryproof.org/"},{"label":"Watch the walkthrough","href":"https://youtu.be/2bPF0pfeWAo"}],"media":[{"id":"output","type":"video","label":"Rendered output","alt":"Finished vertical launch video rendered by Proof","caption":"A finished 61-second output with timed captions and graphics kept clear of the face."},{"id":"walkthrough","type":"video","label":"Product walkthrough","alt":"Proof turning repository research into a scene-by-scene recording plan","caption":"The walkthrough shows repository analysis, the generated brief and the guided recording flow."},{"id":"runner-up","type":"image","label":"1st Runner-Up","alt":"Abhishek at the Sup Build2026 runner-up presentation","caption":"Proof placed 1st Runner-Up at 'Sup Build2026 among more than 300 builders."},{"id":"pipeline","type":"image","label":"Render pipeline","alt":"Proof render pipeline from repository to MP4","caption":"Repository research, recording, Whisper timing, graphics and vision review stay as inspectable stages."}],"caseStudyMarkdown":"## What it does\n\nProof turns a repository into a guided recording workflow. It drafts a script from the codebase, presents it in a teleprompter and combines the take with product visuals in a deterministic render pipeline.\n\n## The result\n\nProof placed 1st Runner-Up at 'Sup Build2026 among more than 300 builders, with S$5K+ in prizes. The product now runs as an invite-only beta at tryproof.org.\n\n## The system boundary I built\n\nRendering is the part I own end to end. I found and patched an SSRF and an IDOR in my own pipeline. The render worker now requires a token, and row-level security keeps each user's jobs separate.\n\nJobs are queued, persisted and resumed instead of living inside a browser request. Each attempt is kept so a failed render can be inspected instead of disappearing into a retry.\n\n## What broke\n\nTwo renders at once were about 20% faster because one could use the container while the other waited on Whisper or an upload. Three exhausted memory and crashed ffmpeg, so I capped it at two and queued the rest. Nothing dropped during the live demo.\n\nWhisper's word timestamps tell the renderer where to cut dead air and place each caption. The measured render time moved from 34.4 seconds to 27.6 seconds without changing the model.\n\n## What I learned\n\nA video pipeline is mostly failure handling. Browsers crash, assets arrive late and one bad page can consume the render worker. Durable jobs made those failures visible instead of turning them into another retake."},{"slug":"clicky","title":"Clicky for Windows","url":"https://abhishekvulla.com/work/clicky","summary":"Hold a shortcut and ask about anything on screen. Clicky talks you through it and draws directly over the app to show exactly where to look or click.","primaryResult":{"value":"90 downloads","label":"verified installer downloads"},"supportingResults":[{"value":"Top 3","label":"OpenAI-backed PyCon SG"},{"value":"S$2K+","label":"in prizes"},{"value":"431 tests","label":"passing across the Windows app"}],"engineeringHook":"Capture, transcription and provider setup now overlap, while the overlay stays responsive through slow devices and network calls.","systemDesign":"Capture, transcription and provider setup now overlap, while the overlay stays responsive through slow devices and network calls.","stack":["Python","PySide6","Whisper","OpenRouter","Windows APIs"],"links":[{"label":"Download for Windows","href":"https://github.com/AbhishekVulla/clicky-windows/releases/latest/download/Clicky-Windows-Setup.exe"},{"label":"View source","href":"https://github.com/AbhishekVulla/clicky-windows"},{"label":"Watch the demo","href":"https://youtu.be/ajIO6p7pR6M"}],"media":[{"id":"demo","type":"video","label":"Demo","alt":"Clicky explaining the current Windows screen in an overlay","caption":"Hold the shortcut, ask a question and get an explanation over the app already on screen."},{"id":"architecture","type":"image","label":"Architecture","alt":"Clicky capture, transcription and response architecture","caption":"Independent capture, audio and provider work overlaps before the final answer is painted."},{"id":"knowledge-map","type":"image","label":"Knowledge map","alt":"Obsidian graph showing Clicky's app-specific knowledge map","caption":"The Obsidian graph makes app-specific context visible instead of burying it in an opaque database."},{"id":"settings","type":"image","label":"Provider settings","alt":"Clicky provider and credential settings on Windows","caption":"Provider choices are explicit and API keys stay in Windows Credential Manager."},{"id":"pycon","type":"image","label":"PyCon Top 3","alt":"PyCon Singapore 2026 Hackathon prize confirmation for Clicky","caption":"Top 3 at the OpenAI-backed PyCon Singapore 2026 Hackathon, with S$2K+ in prizes."}],"caseStudyMarkdown":"## What it does\n\nClicky starts when a user holds a shortcut and asks a question about the current screen. It captures the screen, transcribes the question, talks the user through the next step and draws directly over the current app to show where to look or click.\n\n## The result\n\nClicky finished Top 3 at the OpenAI-backed PyCon Singapore 2026 Hackathon, with S$2K+ in prizes. The Windows installer reached 90 verified downloads. The app now has 431 passing tests across the parts desktop software usually breaks: global shortcuts, audio devices, installers, provider credentials and overlay state.\n\n## The latency work\n\nThe first pipeline ran capture, transcription and model setup in sequence. I timed each stage, moved independent work earlier and kept the overlay responsive while network calls were in flight.\n\nThat cut a measured multi-sentence path from 3.7 seconds to 1.7 seconds. Provider latency still varies, but the app no longer adds avoidable serial work before the request leaves the machine.\n\n## What I learned\n\nDesktop software fails at the seams. The test suite grew because each release found a new one, not because test count was the goal."},{"slug":"deadline-centre","title":"SUTD Deadline Centre","url":"https://abhishekvulla.com/work/deadline-centre","summary":"A local-first Chrome extension that pulls SUTD deadlines into one sortable list and exports them to a calendar.","primaryResult":{"value":"50+ students","label":"weekly users"},"supportingResults":[{"value":"5.0 rating","label":"on the Chrome Web Store"},{"value":"Local only","label":"no backend or student-data collection"}],"engineeringHook":"The extension reads the LMS a student already has access to, then keeps course data in the browser instead of building another account system.","systemDesign":"There is no backend. Course data stays in the browser and the extension stores only what it needs locally. That removes an entire privacy and operating-cost surface, while making browser and LMS changes the main maintenance risk.","stack":["TypeScript","Chrome APIs","LMS integration","Local storage"],"links":[{"label":"Chrome Web Store","href":"https://chromewebstore.google.com/detail/sutd-deadline-center/didnpjogdamalaggfnidojaoconlobpk"},{"label":"View source","href":"https://github.com/AbhishekVulla/sutd-deadline-center"},{"label":"Watch the demo","href":"https://www.youtube.com/shorts/wwGDO0DyrTg"}],"media":[{"id":"store","type":"external","label":"Chrome Web Store","alt":"SUTD Deadline Centre Chrome Web Store banner","caption":"The public Chrome Web Store listing is the clearest proof that students can install and use it."},{"id":"demo","type":"video","label":"Demo","alt":"Abhishek demonstrating SUTD Deadline Centre","caption":"A short walkthrough of collecting, sorting and exporting deadlines from both LMS platforms."},{"id":"main","type":"image","label":"Two LMS sources","alt":"SUTD Deadline Centre collecting deadlines over the eDimension course calendar","caption":"eDimension and Gradescope deadlines land in one sortable view without another login."},{"id":"calendar","type":"image","label":"Calendar export","alt":"SUTD Deadline Centre calendar export control","caption":"One export moves the current course deadlines into a personal calendar."},{"id":"filters","type":"image","label":"Course filters","alt":"SUTD Deadline Centre filtered by course and status","caption":"Course and status filters keep the weekly view compact."}],"caseStudyMarkdown":"## What it does\n\nThe extension reads the LMS pages a student already has access to, normalises the assignments and presents them in one list. Filters, status controls and calendar export make it useful without introducing another account.\n\n## The result\n\nIt reached 50+ weekly student users and holds a 5.0 rating on the Chrome Web Store.\n\n## System design\n\nThere is no backend. Course data stays in the browser and the extension stores only what it needs locally. That removes an entire privacy and operating-cost surface, while making browser and LMS changes the main maintenance risk.\n\n## What changed\n\nA script for one student can tolerate a brittle selector. A published extension cannot. Release work moved toward compatibility, clear failure states and a reliable update path through the Chrome Web Store.\n\n## What I learned\n\nDistribution changed the engineering priorities. The product became less about collecting deadlines and more about staying trustworthy every week after release."}],"secondaryProjects":[{"title":"Yoda","category":"Hardware + agent systems","summary":"A caregiver prototype connecting a custom ESP32 companion, eight MCP tools and a live monitoring dashboard.","result":"Top 5 at Dell InnovateDash. The build spanned firmware, a tool-calling agent, a caregiver approval layer and parametric CAD.","links":[{"label":"GitHub","href":"https://github.com/AbhishekVulla/yoda-mcp"},{"label":"Watch demo","href":"https://www.youtube.com/watch?v=fLG9y0mhrLA"}],"media":[{"id":"team","type":"image","label":"At Dell","alt":"Yoda team with the working companion prototype at Dell Technologies","caption":"The three-person team with the working companion at Dell Technologies."},{"id":"finalist","type":"image","label":"Top 5 finalist","alt":"Dell InnovateDash 2026 finalist badge","caption":"Top 5 finalist at Dell InnovateDash 2026."},{"id":"demo","type":"video","label":"System demo","alt":"Yoda hardware and caregiver dashboard demo","caption":"The demo shows the companion, eight tools and the caregiver dashboard."},{"id":"cad","type":"image","label":"Parametric CAD","alt":"Parametric CAD render of the Yoda enclosure","caption":"The enclosure was modelled in code and exported as a watertight printable assembly."},{"id":"hardware-iteration","type":"image","label":"First hardware pass","alt":"Early Yoda breadboard with camera, amplifier and speaker","caption":"The first hardware pass exposed the camera, audio and power problems before the enclosure hid them."}]},{"title":"SafeEdge","category":"Computer vision","summary":"A 24-hour lab-safety prototype joining fire detection, a privacy-preserving vision veto, evacuation routing and an operator command centre.","result":"The second vision path could stop a false alarm before the system escalated it.","links":[{"label":"GitHub","href":"https://github.com/AbhishekVulla/DeepLearning"},{"label":"Watch demo","href":"https://www.youtube.com/watch?v=u_opG6K_39I"}],"media":[{"id":"demo","type":"video","label":"System demo","alt":"SafeEdge end-to-end system demo","caption":"The full 24-hour prototype, from detection to command-centre response."},{"id":"evacuation-route","type":"image","label":"Evacuation route","alt":"SafeEdge route planner directing a user around a hazard","caption":"Hazard coordinates feed a route planner that steers people away from the affected area."},{"id":"command-centre","type":"image","label":"Command centre","alt":"SafeEdge command centre and evacuation status map","caption":"The operator view tracks alerts, people in transit and verified-safe locations."},{"id":"vision-veto","type":"image","label":"Vision veto","alt":"SafeEdge second vision pass rejecting a false fire detection","caption":"A second, face-blurred vision pass checks the detector before an alert escalates."}]},{"title":"Stow","category":"Fleet operations","summary":"A configurable 3D loading cockpit that turns a dispatcher's truck-packing workflow into a live plan they can inspect and override.","result":"Piloting with PTC Logistics after its Group CIO reviewed the working demo. Backed by the S$2,000 SUTD Baby Shark Fund.","links":[{"label":"Open cockpit","href":"https://stow-app.up.railway.app"},{"label":"Product site","href":"https://stow-sg.vercel.app/"}],"media":[{"id":"early-demo","type":"video","label":"Early demo","alt":"Early Stow demo showing a generated 3D truck load","caption":"The early demo made every generated load inspectable before the current dispatcher cockpit existed."},{"id":"cockpit","type":"image","label":"Dispatcher cockpit","alt":"Stow dispatcher cockpit with five truck loads and planning controls","caption":"Dispatchers can compare truck loads, change constraints and override the generated plan."},{"id":"live-map","type":"image","label":"Live delivery map","alt":"Stow live delivery map with five colour-coded truck routes across Singapore","caption":"The live map keeps each truck route tied to the load plan in the same operating view."},{"id":"landing","type":"image","label":"Product overview","alt":"Stow product page for Singapore logistics operators","caption":"The current product turns a 45-minute planning job into a plan the dispatcher can inspect and change."}]}],"hackathonResults":[{"title":"SpillTeaLeh","event":"Build for Impact 2026","placement":"Champion","detail":"S$9,500 prize from a field of 130+ builders.","summary":"A 3D running game that unlocks pieces of a Singapore-flavoured story as the player moves through the city."},{"title":"Floatware","event":"NUS Maritime Hackathon 2026","placement":"2nd Runner-Up","detail":"Top 3 of 176 teams, S$2,000 prize.","summary":"A fleet model that found ownership accounted for 76.5% of cost, then used 16 independent checks to catch a S$256,000 error."},{"title":"Microsoft Learn, Hack and Fun","event":"Microsoft strategy pitch","placement":"1st place","detail":"A plan for activating 20,000 new learners.","summary":"The PilotBot concept turned course discovery into a guided first session instead of another campaign landing page. I was later selected as a Microsoft Learn Student Ambassador."}],"articles":[{"slug":"learnloop-security-review","title":"How I got a S$7K security test waived","url":"https://abhishekvulla.com/writing/learnloop-security-review","summary":"I did not ask SUTD to lower the bar. I changed LearnLoop until the risky parts of the original design no longer existed.","project":"LearnLoop","editorialOrder":1,"articleMarkdown":"The first security review came with a problem. Before LearnLoop could run inside SUTD's learning platform, EduTech said the original setup would need a S$7K penetration test.\n\nThat was more than the project had raised.\n\nI could have treated the review as paperwork, or argued that a student project deserved softer rules. Neither would make the product safer. So I changed the product.\n\n## The expensive part was the trust boundary\n\nThe original design owned student accounts, exposed public signup and asked for broader LMS access than the tutor needed. Each choice added another place to test and another credential to protect.\n\nI removed public signup. Identity moved to SUTD's EASE SSO through LTI 1.3. The LMS handoff became a single-use code with a 60-second lifetime, consumed atomically with `DELETE RETURNING`. LearnLoop now requests only the course data required for the tutor.\n\n<Figure src=\"/media/articles/learnloop-trust-boundary.webp\" alt=\"LearnLoop trust boundary before and after the security redesign\" caption=\"The redesign moved identity back to SUTD, made the handoff single use and cut access to only the course material the tutor needed.\" contain />\n\nThe quoted penetration test was waived because the public website described in the first assessment no longer existed.\n\n## Shipping less was part of the fix\n\nThe AI tutor is live inside the LMS. It answers from the professor's own slides, cites the exact page and refuses to hand over a final answer when it should teach the method instead.\n\nThe grader is different. It touches assessment data, so it stays off while the DPO review is unresolved. That is not a missing toggle. It is the boundary between a useful pilot and an avoidable institutional risk.\n\n<Figure src=\"/media/learnloop/tutor.webp\" alt=\"LearnLoop answering beside the exact lecture slide it used\" caption=\"The tutor shipped behind university identity and keeps the source slide beside every response.\" contain />\n\nThe lesson was simple: a security review is product feedback. The cheapest system to secure is often the system that owns less."},{"slug":"clicky-latency","title":"I cut Clicky's wait in half without changing the model","url":"https://abhishekvulla.com/writing/clicky-latency","summary":"The speedup came from measuring the critical path, overlapping independent work and playing speech before the full answer was ready.","project":"Clicky for Windows","editorialOrder":2,"articleMarkdown":"Clicky could explain whatever was on my screen. It just made me sit in silence first.\n\nThe obvious fix was a faster model. The actual fix was to stop making independent work wait in a queue.\n\n## I timed the wait, not the whole request\n\nMy useful metric was first audible word. On the multi-sentence benchmark, the original path took about 3.7 seconds: capture the screen, transcribe the question, prepare the model, generate the answer, then synthesise all the speech.\n\nOnly some of those steps depended on each other.\n\nThe moment the hotkey is released, Clicky now starts screen capture, memory recall and provider setup together. It streams text sentence by sentence. As soon as the first sentence is complete, speech begins while the model keeps writing.\n\n<Figure src=\"/media/clicky/demo.webp\" alt=\"Clicky explaining the software already visible on screen\" caption=\"The useful metric was not total request time. It was how long the person waited before Clicky started helping.\" />\n\nThat moved the measured multi-sentence path from 3.7 seconds to 1.7 seconds without changing the model.\n\n## Memory stayed inspectable\n\nI skipped a vector database. Each app keeps plain Markdown the user can open or edit, with SQLite handling the index. It follows Karpathy's LLM-Wiki pattern and is much easier to debug.\n\n## Playback needed its own pipeline\n\nStarting speech early created a new problem. If synthesis and playback shared one buffer, every sentence boundary could produce an awkward pause.\n\nClicky uses a double buffer instead. While one sentence plays, the next is synthesised into the other buffer. Playback swaps only when the next clip is ready.\n\n<Figure src=\"/media/clicky/architecture.webp\" alt=\"Clicky's Windows capture, context, model, speech and overlay architecture\" caption=\"The Windows app starts independent work together, streams the answer and keeps the overlay on the main UI thread.\" contain />\n\nThis is not a blanket sub-two-second claim. Short single-sentence prompts can still take roughly four to six seconds because there is less work to overlap. The useful improvement is that long answers start speaking much sooner and keep speaking smoothly.\n\nLatency work gets easier when the metric matches what the user feels."},{"slug":"spilltealeh-one-email","title":"I was waitlisted. I sent one email. We won S$9,500.","url":"https://abhishekvulla.com/writing/spilltealeh-one-email","summary":"Getting into Build for Impact was the first problem. The next was shipping my first 3D game in 24 hours.","project":"SpillTeaLeh","editorialOrder":3,"articleMarkdown":"I was waitlisted for Build for Impact. The sensible move was to skip it. Term 2 started the next day, and I had never built a 3D game.\n\nI sent one more email anyway.\n\nThey let me in. Twenty-four hours later, SpillTeaLeh won Champion and S$9,500 against more than 130 participants.\n\n## The idea needed one complete loop\n\nEveryone in the wellness track was building a habit tracker. We built a running game instead.\n\nThe player moves through a Singapore-flavoured 3D city. Every 30 metres unlocks another piece of gossip and a choice that changes what appears next. The running mechanic gives the story its pacing without adding another dashboard.\n\nSEA-LION, AI Singapore's model, generated the Singlish encouragement. It landed better than another generic motivational prompt. This was my first 3D build, shipped in 24 hours.\n\n<Figure src=\"/media/hackathons/spilltealeh/product.webp\" alt=\"SpillTeaLeh running through a Singapore-flavoured 3D city\" caption=\"The game linked distance, story unlocks and player choices in one complete mobile loop.\" contain />\n\nThe city came from an imported low-poly asset pack. I focused my time on the parts that made it ours: movement, distance tracking, story state, unlock pacing and the mobile web build.\n\n## The ugly version won because it was playable\n\nWe scoped everything around the demo. One city route. One reliable distance loop. Enough story to make the next unlock feel worth chasing.\n\n<Figure src=\"/media/hackathons/spilltealeh/champion.webp\" alt=\"SpillTeaLeh team receiving the Build for Impact champion prize\" caption=\"The 24-hour build won Champion and S$9,500 against more than 130 participants.\" />\n\nThe email got me into the room. The win came from cutting the product until the risky idea could be played, not explained."},{"slug":"rankr-chatgpt-citation","title":"ChatGPT picked our mattress site. Google barely ranked it.","url":"https://abhishekvulla.com/writing/rankr-chatgpt-citation","summary":"A 97-point SEO score looked excellent. One citation from ChatGPT exposed why eligibility, authority, demand and AI retrieval should never have been one number.","project":"Rankr","editorialOrder":4,"articleMarkdown":"Our new mattress testbed scored 97 on its own SEO checker. Google barely surfaced it. ChatGPT still cited it as \"Best for Singapore\" for one query.\n\nAll three observations were true. Together, they showed that our score was answering the wrong question.\n\n## Ninety-seven meant eligible, not trusted\n\nThe checker was good at page hygiene: titles, schema, internal links and technical structure. A competitor scored 87 on the same rubric. Across 45 Singapore SME sites, 42 responded and the median score was 92.\n\nThat made 97 look impressive. It did not create backlinks, brand demand or search history.\n\n<Figure src=\"/media/rankr/benchmark-sectors.webp\" alt=\"Rankr benchmark comparing search readiness across six Singapore SME sectors\" caption=\"The benchmark showed that strong on-page scores were common and did not prove real search visibility.\" contain />\n\nThe ChatGPT result was interesting for a different reason. The page carried concrete, extractable facts about Singapore weather, room size and mattress fit. Those facts matched one answer well enough to be retrieved despite the weak domain authority.\n\nOne answer is not a ranking system. It is one useful observation from one query.\n\n## The score had to become a measurement stack\n\nWe split the original number into four questions:\n\n1. Can a crawler understand the page?\n2. Does the domain have enough authority to rank?\n3. Are impressions turning into clicks and clients?\n4. Can an AI system extract a useful answer and cite it?\n\n<Figure src=\"/media/rankr/planner.webp\" alt=\"Lullaflex bedroom planner with Singapore room presets and mattress dimensions\" caption=\"The testbed paired useful local facts with a real planning tool instead of publishing another generic mattress page.\" contain />\n\nThe practical result changed how Rankr works. The agent can still fix eligibility, but it no longer pretends that perfect metadata manufactures trust. The interesting opportunity is helping small businesses publish facts that both people and retrieval systems can use, then measuring whether that attention turns into business."},{"slug":"maritime-validation","title":"The 16 checks that found a S$256,000 mistake","url":"https://abhishekvulla.com/writing/maritime-validation","summary":"Our optimiser found a feasible fleet. A separate verifier showed that the model, report and submission did not agree.","project":"Floatware, NUS Maritime Hackathon 2026","editorialOrder":5,"articleMarkdown":"Our optimiser found a feasible fleet for moving 4.58 million tonnes of cargo. A second program found that our totals were off by S$256,000.\n\nWe were hours from submitting.\n\nBefore the optimiser could choose anything, I cleaned 13,000+ AIS records from 108 vessels and counted only real transit and manoeuvring time. The final model chose 22 ships to move 4.58 million tonnes for S$20.04 million.\n\n## Feasible was not the same as verified\n\nThe model selected 22 vessels and satisfied the route constraints. That was enough to produce a polished chart and a confident answer.\n\nIt was not enough to trust the answer.\n\nI rebuilt the total three ways: from route costs, from the selected vessels and from the report output. The numbers should have matched. They did not.\n\n<Figure src=\"/media/articles/maritime-verification-report.webp\" alt=\"Floatware verification report showing 16 checks and one submission mismatch\" caption=\"Independent totals exposed a S$256,000 mismatch that the optimiser could not catch by itself.\" contain />\n\nThe reconciliation led to stale inputs and report logic that had drifted from the model. The same release gate caught a UTF-8 encoding bug in the submission CSV before it left our hands.\n\n## The verifier stayed independent\n\nWe wrote 16 checks across data, model constraints, finance and the final report. The important part was separation. A test that repeats the optimiser's own assumptions can reproduce the same mistake and still pass.\n\n<Figure src=\"/media/hackathons/floatware/certificate-clean.webp\" alt=\"Floatware 2nd Runner-Up certificate from the NUS Maritime Hackathon\" caption=\"The verified model placed 2nd Runner-Up from 176 teams.\" contain />\n\nThe final model found that vessel ownership accounted for 76.5% of total cost, far more than fuel. Raising the minimum safety score from 3 to 4 increased cost by 5.1%, but cut CO2 by 3.9%. The safer ships also ran cleaner fuels, so the safety rule changed the emissions result.\n\nThat changed the fleet strategy and helped us finish 2nd Runner-Up from 176 teams.\n\nThe result mattered. The more reusable lesson was that a fast optimiser needs a boring, independent verifier beside it."},{"slug":"safeedge-refuses-alarm","title":"We built an AI that refuses to raise the alarm","url":"https://abhishekvulla.com/writing/safeedge-refuses-alarm","summary":"SafeEdge lets a cheap detector find possible fires, then makes a second vision pass earn the right to escalate.","project":"SafeEdge","editorialOrder":6,"articleMarkdown":"Most fire-detection demos celebrate the moment the model says yes.\n\nOurs got more interesting when a second model said no.\n\n## Detection was the easy part\n\nSafeEdge started as a 24-hour lab-safety prototype. Classical vision and YOLO watched each frame for smoke and fire. A temporal window required five of eight recent frames to agree, which removed isolated spikes.\n\nThe first pass runs locally in a 6MB model. YOLO finds fire-like objects while optical flow watches for haze.\n\nThat still left the expensive failure: a confident false alarm can trigger an evacuation workflow.\n\nSo a candidate event does not immediately escalate. The handoff is face blurred, then a second vision model reviews only the small subset of frames that survived the cheap first pass. It can confirm the event or veto it.\n\n<Figure src=\"/media/secondary/safeedge/detection.webp\" alt=\"SafeEdge detecting a possible fire in a camera frame\" caption=\"The cheap detector finds candidates. Temporal persistence filters isolated spikes before the expensive second opinion.\" contain />\n\n## A veto is a product feature\n\nDuring testing, the primary detector fired on a simulated scene. The second pass rejected it because the display showed a synthetic fire rather than the room itself.\n\n<Figure src=\"/media/secondary/safeedge/vision-veto.webp\" alt=\"SafeEdge second vision pass rejecting a false positive\" caption=\"The second model stopped a candidate alert before it reached the command centre.\" contain />\n\nConfirmed alerts are routed around the hazard to one of nine NTU assembly zones using the campus walking graph. The same event object feeds the operator view, so every escalation has location context and an inspectable trail.\n\nThe useful part was the veto. A cheap model found candidates, a temporal window filtered one-frame spikes, and the expensive vision model only saw the frames worth escalating.\n\nFor safety systems, a model that knows when to stop can be more valuable than one that fires first."},{"slug":"yoda-stage-wifi","title":"Our demo died on the venue WiFi. It probably cost us the win.","url":"https://abhishekvulla.com/writing/yoda-stage-wifi","summary":"The obvious culprit was the network. The postmortem found our own two-second polling loop starving the wake-word detector too.","project":"Yoda","editorialOrder":7,"articleMarkdown":"Yoda worked on our bench. On stage, the venue WiFi stalled and the companion stopped listening.\n\nWe finished Top 5 at Dell InnovateDash. The failure still bothered me because blaming the network was only half true.\n\n## The product had no screen to hide behind\n\nYoda was built for an elderly user who may never open an app. The interface was a small ESP32 companion with an on-device wake word. A Python MCP server exposed eight voice-callable tools, while a caregiver dashboard approved sensitive actions.\n\nThat constraint shaped the system. A request could reach community services or a family member, but the agent could not act alone. Every consequential action became a caregiver approval first.\n\n<Figure src=\"/media/secondary/yoda/hardware-iteration.webp\" alt=\"Yoda's early breadboard, camera and speaker hardware\" caption=\"The first hardware pass put the camera, audio and wake-word path on one constrained device.\" />\n\n## The postmortem found our own bottleneck\n\nThe camera relay opened a new TLS connection every two seconds. On weak WiFi, that polling loop occupied enough of the device's attention to starve the wake-word detector. The companion looked offline because it could no longer hear the user reliably.\n\n<Figure src=\"/media/articles/yoda-system.webp\" alt=\"Yoda voice request flowing from the ESP32 companion through eight MCP tools to a caregiver approval gate\" caption=\"Voice could start the request, but the agent could not complete a sensitive action without caregiver approval.\" contain />\n\nWe throttled the idle poll to 15 seconds and kept the wake-word path responsive. A production version should go further: persistent connections, explicit offline behaviour and a local queue for anything that can wait.\n\nThe stage failure was painful, but useful. Hardware demos do not fail at clean API boundaries. The network, firmware and user interaction all compete for the same small device."}],"press":[{"slug":"reimagine-education-learnloop","title":"LearnLoop: reimagining the learning loop with AI","url":"https://abhishekvulla.com/press/reimagine-education-learnloop","publisher":"SUTD Design.AI","date":"2026-03-06","summary":"Abhishek Vulla on building LearnLoop, moving it into real classrooms and keeping students engaged with the source material."}]}