# Abhishek Vulla: full portfolio context Computer Science and Design student at SUTD. This document contains the public, verified context behind the portfolio, including results, engineering decisions and system design notes. Canonical portfolio: https://abhishekvulla.com Structured JSON: https://abhishekvulla.com/portfolio.json # Projects ## 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. Primary result: 40 students, piloted across two classrooms Supporting results: S$2,000, university build funding; S$7K test waived, after redesigning the trust boundary Engineering: 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 ## What it does Course 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. ## The result The 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. ## The security decision that changed the product The 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. Citations 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. ## What changed The 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. ## What I learned The chat box was the easy part. Shipping inside a university meant authentication, privacy and least-privilege access mattered more than another model feature. ## 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. Primary result: 2 signed LOIs, from Singapore SMEs Supporting results: Top 20 of 800+, UCWS participants; US$10,000, OpenAI credits awarded at UCWS; DR 2 testbed, cited by ChatGPT Engineering: A perfect on-page score produced no rankings, so I rebuilt the system around authority, demand and inspectable search evidence. Stack: Next.js, TypeScript, Python, Search APIs, LLM evaluation ## What it does Rankr 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. ## The result Two 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. ## The experiment that changed the product We 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. That 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. ## System design 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. DataForSEO 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. ## What I learned An 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. ## 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. Primary result: 1st Runner-Up, 'Sup Build2026 · 300+ builders · S$5K+ in prizes Supporting results: Invite-only beta, running at tryproof.org; 20% faster renders, after load-testing the safe concurrency limit Engineering: Durable jobs survive redeploys, direct-to-storage uploads bypass request limits and bounded Chromium workers avoid ffmpeg memory crashes. Stack: Next.js, Remotion, Whisper, FFmpeg, Docker ## What it does Proof 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. ## The result Proof 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. ## The system boundary I built 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. Jobs 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. ## What broke Two 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. Whisper'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. ## What I learned A 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. ## 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. Primary result: 90 downloads, verified installer downloads Supporting results: Top 3, OpenAI-backed PyCon SG; S$2K+, in prizes; 431 tests, passing across the Windows app Engineering: 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 ## What it does Clicky 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. ## The result Clicky 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. ## The latency work The 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. That 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. ## What I learned Desktop software fails at the seams. The test suite grew because each release found a new one, not because test count was the goal. ## 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. Primary result: 50+ students, weekly users Supporting results: 5.0 rating, on the Chrome Web Store; Local only, no backend or student-data collection Engineering: The extension reads the LMS a student already has access to, then keeps course data in the browser instead of building another account system. Stack: TypeScript, Chrome APIs, LMS integration, Local storage ## What it does The 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. ## The result It reached 50+ weekly student users and holds a 5.0 rating on the Chrome Web Store. ## System design 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. ## What changed A 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. ## What I learned Distribution changed the engineering priorities. The product became less about collecting deadlines and more about staying trustworthy every week after release. # Engineering notes ## 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. 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. That was more than the project had raised. I 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. ## The expensive part was the trust boundary The 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. I 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.
The quoted penetration test was waived because the public website described in the first assessment no longer existed. ## Shipping less was part of the fix The 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. The 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.
The lesson was simple: a security review is product feedback. The cheapest system to secure is often the system that owns less. ## 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. Clicky could explain whatever was on my screen. It just made me sit in silence first. The obvious fix was a faster model. The actual fix was to stop making independent work wait in a queue. ## I timed the wait, not the whole request My 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. Only some of those steps depended on each other. The 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.
That moved the measured multi-sentence path from 3.7 seconds to 1.7 seconds without changing the model. ## Memory stayed inspectable I 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. ## Playback needed its own pipeline Starting speech early created a new problem. If synthesis and playback shared one buffer, every sentence boundary could produce an awkward pause. Clicky 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.
This 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. Latency work gets easier when the metric matches what the user feels. ## 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. 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. I sent one more email anyway. They let me in. Twenty-four hours later, SpillTeaLeh won Champion and S$9,500 against more than 130 participants. ## The idea needed one complete loop Everyone in the wellness track was building a habit tracker. We built a running game instead. The 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. SEA-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.
The 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. ## The ugly version won because it was playable We scoped everything around the demo. One city route. One reliable distance loop. Enough story to make the next unlock feel worth chasing.
The email got me into the room. The win came from cutting the product until the risky idea could be played, not explained. ## 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. 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. All three observations were true. Together, they showed that our score was answering the wrong question. ## Ninety-seven meant eligible, not trusted The 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. That made 97 look impressive. It did not create backlinks, brand demand or search history.
The 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. One answer is not a ranking system. It is one useful observation from one query. ## The score had to become a measurement stack We split the original number into four questions: 1. Can a crawler understand the page? 2. Does the domain have enough authority to rank? 3. Are impressions turning into clicks and clients? 4. Can an AI system extract a useful answer and cite it?
The 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. ## 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. 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. We were hours from submitting. Before 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. ## Feasible was not the same as verified The model selected 22 vessels and satisfied the route constraints. That was enough to produce a polished chart and a confident answer. It was not enough to trust the answer. I 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.
The 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. ## The verifier stayed independent We 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.
The 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. That changed the fleet strategy and helped us finish 2nd Runner-Up from 176 teams. The result mattered. The more reusable lesson was that a fast optimiser needs a boring, independent verifier beside it. ## 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. Most fire-detection demos celebrate the moment the model says yes. Ours got more interesting when a second model said no. ## Detection was the easy part SafeEdge 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. The first pass runs locally in a 6MB model. YOLO finds fire-like objects while optical flow watches for haze. That still left the expensive failure: a confident false alarm can trigger an evacuation workflow. So 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.
## A veto is a product feature During 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.
Confirmed 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. The 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. For safety systems, a model that knows when to stop can be more valuable than one that fires first. ## 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. Yoda worked on our bench. On stage, the venue WiFi stalled and the companion stopped listening. We finished Top 5 at Dell InnovateDash. The failure still bothered me because blaming the network was only half true. ## The product had no screen to hide behind Yoda 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. That 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.
## The postmortem found our own bottleneck The 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.
We 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. The 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. # More work ## 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: GitHub: https://github.com/AbhishekVulla/yoda-mcp; Watch demo: https://www.youtube.com/watch?v=fLG9y0mhrLA Visual evidence: At Dell: The three-person team with the working companion at Dell Technologies.; Top 5 finalist: Top 5 finalist at Dell InnovateDash 2026.; System demo: The demo shows the companion, eight tools and the caregiver dashboard.; Parametric CAD: The enclosure was modelled in code and exported as a watertight printable assembly.; First hardware pass: The first hardware pass exposed the camera, audio and power problems before the enclosure hid them. ## 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: GitHub: https://github.com/AbhishekVulla/DeepLearning; Watch demo: https://www.youtube.com/watch?v=u_opG6K_39I Visual evidence: System demo: The full 24-hour prototype, from detection to command-centre response.; Evacuation route: Hazard coordinates feed a route planner that steers people away from the affected area.; Command centre: The operator view tracks alerts, people in transit and verified-safe locations.; Vision veto: A second, face-blurred vision pass checks the detector before an alert escalates. ## 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: Open cockpit: https://stow-app.up.railway.app; Product site: https://stow-sg.vercel.app/ Visual evidence: Early demo: The early demo made every generated load inspectable before the current dispatcher cockpit existed.; Dispatcher cockpit: Dispatchers can compare truck loads, change constraints and override the generated plan.; Live delivery map: The live map keeps each truck route tied to the load plan in the same operating view.; Product overview: The current product turns a 45-minute planning job into a plan the dispatcher can inspect and change. # Press ## LearnLoop: reimagining the learning loop with AI URL: https://abhishekvulla.com/press/reimagine-education-learnloop Publisher: SUTD Design.AI Summary: Abhishek Vulla on building LearnLoop, moving it into real classrooms and keeping students engaged with the source material. This is a readable web version of the LearnLoop feature prepared for the March 2026 SUTD Design.AI newsletter. The questions and answers have been lightly edited for the web. The original seven-page PDF is available above. ## How did LearnLoop start? I joined Building 0 in November 2025 because I wanted to be around people who were building, not just talking about ideas. My first SUTD project was Deadline Centre, a Chrome extension that collects deadlines from eDimension and Gradescope. After I shipped it, a senior from Building 0 pushed me to look at the deeper problem. Deadlines were one symptom. Students were still digging through course folders, passively rereading PDFs and pasting questions into generic chatbots that could not show where an answer came from. That became LearnLoop. ## What does it do? LearnLoop is an AI study layer built around course material. Students can search across their slides using semantic search, ask a tutor that stays grounded in those slides and submit photos of handwritten work for feedback. The tutor does not need to be the source of truth. It keeps the relevant lecture slide beside the response so the student can check the answer. The grader looks for the step where the reasoning broke, then points back to the course material that explains it. Interactive simulations let students change a value and see the concept move. The aim is simple: use AI to keep the student thinking, not to finish the thinking for them. ## How was it built? The retrieval pipeline converts course material into embeddings stored in PostgreSQL. Each search stays inside the current course boundary, and responses carry the source reference back to the interface. Different parts of the product use different models. The tutor prioritises speed and course grounding. The handwritten grading flow needs stronger vision and reasoning. Interactive simulations use generated p5.js code to turn a concept into something the student can manipulate. The rest of the system is a TypeScript web app with a backend API, PostgreSQL, authentication and object storage. It moved to Railway after the first hosting setup became unreliable under the grading workload. ## What went wrong? The first infrastructure choice worked for a prototype but struggled in normal use. Cold starts pushed tutor responses towards 30 seconds, memory limits crashed the grading path and long-running processes could disappear. Moving the system meant transferring 1,520 files, replacing parts of the deployment setup and checking that the course material survived the migration. The harder mistake was product work. I kept adding features before enough students had used the previous version. Feedback from Building 0 changed the question from "what should I add next?" to "who can use this today?" That shift led to a real classroom pilot. LearnLoop was later used with 40 students across two classrooms, and the institutional security review changed how course files, access and instructor control were handled. ## What comes next? LearnLoop is not trying to replace SUTD's learning platform. It adds a study layer around the material and workflow students already have. The next useful test is not another feature. It is whether the tutor, grader and simulations help in a real course without getting in the lecturer's way. # Profiles Resume: https://abhishekvulla.com/resume/AbhishekVulla_Resume.pdf GitHub: https://github.com/AbhishekVulla LinkedIn: https://www.linkedin.com/in/abhishek-vulla/