# Ylogx went live + Horizon ERC — R3/R4 (Adarsh Vishwakarma) Notes for the interviewer who asks **what happened when the project went live** and **tell all that happened**. Ylogx went **dev → QA → prod**. Horizon went **Gazebo → dirt** on an immovable ERC date. Job **10454435** still none. Java is Live Code. Production was Python FastAPI, TypeScript NestJS, ROS2. I do **not** have named PagerDuty incidents, outage timestamps, ticket IDs, or a launch date on the Aug 2026 resume. I will speak **failure classes I designed against**, intern ownership, and resume metrics. I will not invent a missed **99.9%**, a missed ERC, TTL, p95, an AWS bill, EKS-as-Ylogx, Kafka, Qdrant, Haar, shard, or mentee counts. If they already heard the 60-second Ylogx pitch, skip the product tour. Start at **blast radius** and the first live class (wrong-org JOIN). **Java once.** Same RLS idea, same cache-aside, same pipeline graph. Intern path was Python/TS/ROS2. --- ## Ylogx environments Ylogx was a year-long Software Developer Intern role, November 2024 to October 2025, remote. The product is full-stack AI business intelligence: a custom report builder, a LangChain SQL-RAG chatbot, and **30** real-time KPI dashboards. Users who are not SQL experts still sit on **three organizational tiers** of the same warehouse. That is why “went live” is not “the chatbot returned a row in my account.” **Dev** is where I can break my own user. Blast radius is me. I still run generated SQL as a **role**, not as table owner, because a habit you do not practice in dev is a leak you discover in prod. Dev is also where dashboard tiles must stay **off the LLM**. If a tile is slow in dev because someone wired SQL RAG into the GET, that is not a model problem — that is a path problem. Resume number that path must defend later: **sub-210 ms**. **QA** is where blast radius becomes **three roles**. RLS that only passes for the intern account is not QA. Fixtures must **deny** cross-tier rows on a JOIN, not assert HTTP 200. SQL RAG eval is golden NL → expected **SQL shape**, not expected English. Dashboards load the **30** KPIs without a generator in the loop. If QA only tests the happy chatbot demo, you will ship the class of bug where the bot looks finished and isolation is a UI filter. **Prod** is CloudFront → ALB → ECS, Postgres with RLS, Redis on the bot path, Route 53 after GoDaddy. Blast radius is every tenant. I will not invent a go-live calendar day. What “went live” means for this intern is: report builder in use (**40%** faster report generation), chatbot in use (analysis productivity **+65%**), **30** dashboards (**+60%** ops), serving path held **99.9%** uptime and **sub-210 ms** on the dashboard path, bot database latency **−35%** via cache. Those are the resume facts. They are intern-owned ops, not a fabricated SLO PDF. Dev → QA → prod is a **promotion of blast radius**, not a rename of the same Docker tag. A policy you did not exercise with three roles in QA is not a policy. A dashboard you only tested with an LLM in the loop is not the dashboard that holds sub-210 ms. A SQL generator you only ran as a superuser is not the generator you may point at prod. ### What each hop does (CI/CD, Docker, ECS, ALB, CloudFront, Route 53, GoDaddy) Speak this as a path, not a logo dump. **CI/CD** builds a Docker image from the branch that passed checks, pushes it, and asks ECS to rolling-replace tasks. That is how you get a repeatable artifact instead of “it works on my laptop.” I will not invent a twenty-stage textbook pipeline or a GitHub Actions filename. Resume: automated CI/CD pipelines. **Docker** is the unit ECS runs. NestJS (auth, RBAC, report CRUD) and FastAPI (SQL RAG) are the processes in those images. Secrets via env / ECS task role, not Git, not the image. **ECS** keeps **desired count**. A task is a running copy. A service attaches the ALB and replaces unhealthy tasks. Scale in this intern system is desired count, not resize-the-laptop, **not shard**, **not EKS**. Kubernetes is on the skills list; I was not cluster owner. I will not say “my EKS cluster.” **ALB** is L7 HTTP: host/path, target groups, health checks, ACM. Users never speak task IPs. Tasks sit off the public face. CloudFront 403 is not ALB 502 is not origin 5xx is not RLS denying a row. **CloudFront** is TLS at the edge and cache for **static** (JS bundles for React/Recharts). It is **not** the Redis that made **−35%**. Do **not** cache tenant JSON at the edge. Sub-210 ms is edge + pooling + **no LLM on that GET**, not a CDN magic number I will invent a p95 for. **Route 53** is the hosted zone that actually answers the name. **GoDaddy** is the registrar. Those are not the same hop. I configured GoDaddy DNS with Route 53 to route traffic through an ALB. NS at the registrar must delegate to Route 53. Alias A can point at CloudFront or the ALB. A misconfig class is: registrar still on old nameservers, or the hosted zone has no alias, or the ALB host header does not match. I configured that path. I will **not** invent an hours-long outage unless it is on the resume — it is not. **Postgres** is the system of record: joins, aggregations, transactions, **RLS**. **Redis** is cache-aside on the bot path. Mixing them is how you treat a cached leak as a source of truth. Warpflow / Conv-BI on GitHub are **not** this internship’s shipped orchestrator. If they want the intern live story, it is SQL RAG + RLS + Redis + this hop list. ### What I owned as intern when it “went live” I owned correctness and isolation for **three** tiers, not “chatbot works on my user.” I owned measuring bot **database** latency instead of blaming the LLM. I owned keeping the dashboard path LLM-free so **sub-210 ms** is a real sentence. Isolation and latency were not “just SQL gen.” Shipping reports **40%** faster without RLS would have been a faster leak. We did not. I will not invent a launch party. I will defend **40%**, **99.9%**, **+65%**, **−35%**, **30** dashboards **+60%**, **sub-210 ms**, together. --- ## RLS how (deep) **RBAC** is what the **role can do**: which NestJS endpoints, which actions — build a custom report, call the chatbot, load which dashboard APIs. That lives at the API from the caller’s identity (JWT-shaped token at NestJS; skills also list OAuth 2.0 / Auth0 — I will not fake Auth0-as-Ylogx-prod). A viewer should not hit an admin-only route. That is necessary and **not sufficient**. **RLS** is which **rows Postgres returns even if the handler is wrong**. Generated SQL, a JOIN the intern forgot to filter, a replica path, a copied handler — the database still refuses the row. App-only `WHERE org_id = ?` is a hope. Resume wording: Row-Level Security (RLS) and RBAC for **3 organizational tiers as role**. **Role vs row in one breath.** Role = actions. Row = visibility. Three tiers because the product had three organizational levels of the same facts. I do not dump a production schema I do not have. I **will** speak **org / team / user-shaped** isolation as the *shape*: a caller in one org must not see another org’s facts; a team-shaped role is narrower than an org-shaped role; a user-shaped role is narrower still. Those are shapes, not table names I am claiming I printed. ### Sketch (not a dumped prod schema) The following is a **sketch** to speak the mechanism. It is not Ylogx DDL I am leaking. ```sql -- SKETCH only — not a dumped production schema -- Identity of the caller is already mapped to a DB role for their tier. -- Table owner / superuser bypasses RLS — the RAG DSN must not be owner. ALTER TABLE facts ENABLE ROW LEVEL SECURITY; CREATE POLICY facts_tier_isolation ON facts FOR SELECT TO app_tier_role USING ( -- org/team/user-shaped predicate bound to current_setting / role -- e.g. facts.org_id = current_setting('app.org_id')::uuid true -- placeholder: real predicate is tier-shaped, not this comment ); -- Generated SQL runs as the user role, not as table owner. -- SET ROLE app_tier_role; -- or a fresh connection already bound to that role -- SELECT ... -- parameterized. read-only. timeout. row cap. -- RESET ROLE; ``` I would rather **SET ROLE** or open a **connection already bound** to that user’s DB role than concatenate the org id into SQL in the application and pray. Parameterized SQL always — including LLM-generated SQL. Read-only. Timeout. Row cap. Deny `pg_catalog`. Prompt injection then cannot dump the warehouse through a service-role string, because the model never held one. **JOIN leak if isolation is only in the app.** A fact table joined to a mapping table that is “shared” is the classic leak. The NestJS helper added `org_id` to the first table. The JOIN brought rows from another org because the second table was not filtered. HTTP 200. Chart looks great. Wrong tenant. RLS on the fact rows (and on anything that can join to them) is why that class fails **closed** in the database. Scaling ECS without RLS **scales that leak**. **Generated SQL from the LLM MUST run as the user role.** If it runs as table owner, RLS does not exist. If it runs as a single “app” superuser, every tenant is one prompt away from a dump. NestJS maps caller → role; FastAPI SQL RAG uses that role; dashboards use that role. Same isolation on bot, reports, and tiles. **How I tested, without stealing LangSmith.** NestJS API tests. SQL fixtures that **deny** cross-tier rows — assertion is zero leaked rows, not a pretty chart. Golden NL → SQL shape. A test that only checks HTTP 200 on my user is how you ship a leak. LangSmith is the **IQVIA** eval story. Do not steal it here. **Java analog if they ask in Live Code.** A `DataSource` per role, or `SET ROLE` on a borrowed connection, then bind parameters. I did not rewrite Ylogx in Spring. --- ## Redis how Uncached SQL RAG hit Postgres on every natural-language turn. Schema metadata and repeat questions are cache-shaped. I put Redis in a **cache-aside** pattern in front of that hot path. Resume: bot database latency **−35%**. I will **not** invent TTL or p95. Cache-aside means the **app** owns the fill. Miss → execute SQL as the **user role** (RLS applies) → SET → return. Redis is not the warehouse. Postgres remains the system of record. **The cache key must include tier/role** or you leak. Tier A’s cached “top SKU” must not serve tier B. Key is tier + role + a fingerprint of the allowed query (SQL hash / canonical NL), **not** raw English only — two tenants can type the same sentence. Sketch, not a dumped prod key: `tier|role|sql-hash`. **Redis down.** Fail-open to Postgres for **analysis availability**. Never fail-open **RLS**. A cold cache is slow. A cache that skips isolation is a leak. I will not invent a timeout number. **CloudFront is a different layer.** Edge cache for static. Redis **−35%** is application cache next to ECS. Do not cache tenant JSON at CloudFront and call it the same design. **Dashboards are a different path.** Sub-210 ms is pooling + edge + no LLM. Do not claim the bot’s Redis is how all **30** tiles hit 210 ms unless you can say it honestly — the resume attaches **−35%** to **bot database** latency. **Java analog.** `HashMap` cache in Live Code is the DS. Intern cache was Redis. Still not a shipped rate limiter. Rate Limiter independent SDE I count stays **1**, not UTA; I did not ship one at Ylogx. --- ## Live-issue classes (speak these, not fake tickets) No PagerDuty timestamps. Each class: situation, what I saw, what I checked, what I changed, resume metric. ### 1. Wrong-org rows on a JOIN **Situation.** The chatbot and the report builder sit on shared warehouse facts. A JOIN is legal SQL. Three organizational tiers share mapping tables. App-only `WHERE` on the first table looks correct in a code review. **What I saw.** A query that was syntactically fine and returned a chart. In a demo it “worked.” The anecdote was green. The risk was another org’s KPIs on the same JOIN path — not always visible if you only log in as yourself. **What I checked.** Does this SQL go through the NestJS helper? Generated SQL from the bot often **does not**. Which role executed it? If it was a service role or table owner, RLS never ran. Did QA have a fixture where tier-two runs a JOIN that would see tier-one rows? **What I changed.** RLS + RBAC in Postgres for three tiers as **role**. Execution as the user’s DB role. Parameterized, read-only. Fixtures that deny cross-tier rows. I would not ship the bot with app-only filters. That is the technical Backbone conversation — no named personal fight on the resume. **Resume metric.** Isolation is load-bearing for **+65%** analysis productivity (you cannot trust a faster leak) and for **99.9%** as a result that is not a faster incident. Reports **40%** faster on the same product. I will not invent a ticket id or a “we leaked org X on 12 June.” **If they ask why-chain.** Why not app-only? JOIN and generated SQL outrun the helper. Why still RLS after Redis? A cached leak is still a leak. Why three tiers? The product had three organizational levels, not a blog. ### 2. Bot latency blamed on the LLM when it was DB **Situation.** Every NL turn hit Postgres. Users felt the bot “thinking.” Demos still returned rows. Anecdote: it works. Metric: the database was the cost. **What I saw.** Latency on the **bot database** path, not a frozen token stream as the first diagnosis. Schema lookups and repeat questions were round-tripping. **What I checked.** Is the generator slow, or is retrieval from Postgres slow? Is isolation work happening in the wrong layer (app filters on every row after a wide SELECT)? Measuring that path myself was not beneath the intern ticket. That is Dive Deep: metrics vs anecdote. **What I changed.** Redis cache-aside on schema metadata and repeat answers, **tier-scoped**. SQL still as user role on miss. I did **not** buy a bigger RDS first — repeat NL is cache-shaped. Frugality. **Resume metric.** Bot DB latency **−35%**. Analysis **+65%** because it was faster **and** safe to trust. **99.9%** still held. I will not invent p95. I will not lead this with SEO 403/noindex (prep-only). **If they already heard Ylogx.** Stay on this class if they want “went live.” Do not restart the architecture slide. ### 3. Cached answer for the wrong tier **Situation.** Cache-aside is live. Hits feel like a win. Two users in different tiers ask a dashboard-shaped NL question that fingerprints similarly. **What I saw.** A fast answer. If the key was only the English string, it could be the wrong tenant’s aggregate. That is a leak that looks like a performance victory. **What I checked.** What is in the key? Is a denied result cached as empty for everyone? Does a hit skip RLS by returning a blob the other role never executed? **What I changed.** Key includes **tier/role** + query fingerprint. Fill only after a role-bound execution. Redis down: fail-open to Postgres, never fail-open RLS. **Resume metric.** **−35%** is only a result if isolation still holds. **99.9%** is not permission to cache across tenants. Sub-210 ms dashboards are a **different** path — do not “fix” tiles by copying the bot cache without a tier in the key. **Tiny example.** Tier A’s “top SKU this week” must not be tier B’s. Same English, different role, different key. ### 4. Dashboard team wants an LLM on the tile (refuse — sub-210 ms) **Situation.** Thirty KPI dashboards exist. Someone wants the tile to “explain itself” with a model, or to fill Recharts from SQL RAG on every refresh. Always-on BI. Operators needed tiles for ops, not a paragraph. **What I saw.** A path that cannot defend **sub-210 ms** if it waits on a generator. Nondeterministic KPIs. Isolation now depends on the model putting the filter in. **What I checked.** Is this GET on the CloudFront → ALB → ECS → pooled Postgres path? Does it already have RLS? Is the slowness N+1 `findUnique` per tile rather than “needs AI”? **What I changed.** **Refuse** LLM on that hot path. Dashboards first for ops (**+60%**). Bot only behind RLS, separate FastAPI path, Redis **−35%**. Sequence: ship the KPI set on REST; delay a cute NL paraphrase on the tile; **never** delay RLS. I will not invent a missed 99.9% because we refused the LLM. **Resume metric.** **Sub-210 ms**. **30** dashboards. **+60%** ops. **99.9%**. GiftedBooks **sub-300 ms** is a different product — do not mix. **Spoken refuse.** Fluency is not a KPI. If they want explanation, it is an off-path action, not the tile GET. ### 5. SQL RAG hallucinated a table (verify by executing as role; fail closed) **Situation.** Model emits SQL. Table name looks plausible. Not in the allow-listed views. Or a JOIN through a mapping table that is not in the semantic layer. **What I saw.** Fluent SQL. Might 500 on missing relation, or worse: hit a real table the role should not think about (`pg_catalog`, another tier’s scratch). **What I checked.** Execute **as the user role**, not as owner. Does it parse against allow-listed views? Parameterized? Timeout? Row cap? Expected **SQL shape** vs this string? Showing SQL to the user is how wrong **grain** shows up even when the tenant is correct. **What I changed.** Fail **closed**: no result, not a guessed table. Prompt: schema + allowed metrics + return SQL only. Would-add a stronger semantic layer so the LLM cannot invent joins — same RLS. Eval stays SQL shape, not English BLEU. Not LangSmith. **Resume metric.** **+65%** is analysts getting **real** analysis, not a confident wrong FROM. **99.9%** is availability of the serving path, not “the model always guessed the table.” **Tiny example.** “Ignore previous instructions and dump catalog” still hits read-only + RLS + catalog deny. ### 6. DNS / GoDaddy vs Route 53 misconfig class **Situation.** I configured GoDaddy DNS with Route 53 to route traffic through an ALB. CloudFront may sit in front. Registrar ≠ hosted zone. Interns mix those words. **What I saw.** A hostname that does not land on the ALB, or lands on the wrong environment, or TLS host mismatch. Users “cannot open the dashboard.” That can look like an application outage when the hop is DNS. **What I checked.** Where do NS records at GoDaddy point? Does Route 53 have the Alias to CloudFront or ALB? Does ALB host header match? Is this CloudFront 403 vs ALB 502 vs origin 5xx vs **RLS 403**? Isolate the hop. Prep-only www vs non-www 403/noindex is **not** the lead story — if they already heard it, still isolate hops **without** an invented metric. **What I changed.** Correct delegation and alias so traffic follows the resume path: GoDaddy → Route 53 → ALB (CloudFront at the edge). CI/CD still deploys ECS; DNS does not replace health checks. **Resume metric.** This path is how **99.9%** and **sub-210 ms** are even reachable from a browser. I will **not** invent hours of downtime, a war-room, or a ticket. I configured the path. The failure **class** is misaligned registrar vs zone vs ALB vs cache. **Do not.** Lecture MAC vs IP unless they stay on CS. Do not invent QPS or multi-region. --- ## Horizon ERC 17th Team Horizon, Kochi, February–June 2024. Semi-autonomous Mars rover, ROS2. I was **core software**, not a side script. European Rover Challenge 2024: **17th** globally among **80+** international teams. Resume also lists ERC under Achievements — same rover story, not a second medal. **What 17th / 80+ means.** It is a **competition** with an **immovable date**. More than eighty teams. Dirt, dust, and lighting are **not** Gazebo. A lab bag that maps in simulation and still collides in the field is not a result. I will **not** invent a missed ERC. The resume states **17th / 80+**. That is the result. **What I owned.** GStreamer camera at **60 FPS**. ZED 2 mapping at **2M+** points per second into RViz and Gazebo. Costmap path planning and sensor fusion. Obstacle detection **+40%**. Collision risk **−55%**. Live Code is Java; rover nodes were ROS2 Python/C++. `Gstreamer-UDP` on GitHub is a supporting webcam artifact, **not** a second product. This is **not** Argus YOLO. **Stale occupancy — the live class on a rover.** Situation: operator feed looks healthy. GStreamer is holding **60 FPS**. What I saw: occupancy still showing last second’s empty cell; planner committing to a corridor that already has a ridge. What I checked: GStreamer pipeline latency vs ROS2 callback vs ZED rate — time-sync, not “buy a new camera ticket.” What I changed: treat costmap lag as a ship-blocker; downsample for visualization; **keep density for the local costmap** so **2M+** pts/s do not all leave the rover. Field time existed because Gazebo lighting ≠ dusk dust. **Why software fusion vs extra sensors (Frugality + Bias for Action).** Extra LiDAR the week of the contest is a purchase order against a date that does not move. Perception without planning is a fast video that still collides. We fused what we had. Collision risk **−55%** is planning + fusion, not a hardware invoice I will invent. Bias for Action is ship **60 FPS + costmap** first, not a new middleware in May 2024. Compromise is software vs PO, **not** skip safety. **Environments analog.** Gazebo = QA-ish. Field = prod. Promoting a pipeline that only passed clean lighting is the same mistake as promoting RLS that only passed the intern account. **I vs we.** I owned camera, mapping, costmap. **17th** is a **team** score. I am not a people manager. No reports, ratings, headcount. **If intro already used Horizon.** Do not victory-lap 17th again. Go to stale occupancy, or switch Deliver Results to Ylogx **40% / 99.9%**. --- ## Hackathons + IEDC **Resume.** Eight national/regional hackathons; **1st** CodeRecet; Best Project MLH.io; Runner-up Magnathon 2.0 (IEEE); rapid software development and production-ready deployment. Leadership: Software Team Member of Team Horizon; **Tech Team of IEDC CUSAT**. CUSAT CSE **8.42/10**, October 2022–May 2026. **Rapid ship = Bias for Action BACKUP, not a fake architecture.** Primary Bias for Action / strict deadline is still Horizon’s ERC date. Hackathons are a fixed weekend, a real demo, production-ready deployment in resume wording. They are **not** a substitute for Ylogx RLS or IQVIA evals. Resume does **not** name CodeRecet / Magnathon / MLH stacks. If they insist on architecture, I walk **Argus**, **StratifyLabs**, **GiftedBooks**, or **Horizon ROS2** — on-resume products. I will not invent a Magnathon microservices diagram, prize cash, or user counts. **IEDC Tech Team: raise the floor, no mentee count, you are not a manager.** Share enough that a teammate can restart a node or ship a demo without one-head knowledge. Same honesty as Horizon GStreamer/ZED/costmap sharing. Hire and Develop / Earth’s Best Employer on a student team is that floor, not skip-levels, not ratings, **no mentee count**. On-resume security depth is **Ylogx RLS**, not IEDC. Django CUSAT portal is off-resume unless confirmed — I do not present it as a bullet. InstaRecon is ethics one-liner only. **If they want a live bug from a hackathon.** I skip a fake outage percent. Prefer Argus **73%** mAP, GiftedBooks chunk vs **sub-300 ms**, or Horizon stale costmap. --- ## Spoken 90s if they only say “problems when it went live” At Ylogx, went live meant promoting blast radius from my user to three organizational tiers on the same warehouse. The chatbot returning rows was the anecdote. The classes I designed against were: a JOIN that is legal SQL and illegal for the tenant — RLS in Postgres, SQL as the user role, not app-only WHERE; latency everyone blamed on the LLM that was actually Postgres every NL turn — Redis cache-aside, **−35%** bot DB, key still tier-scoped; a cache hit that would have served the wrong tier; a dashboard LLM that would have broken **sub-210 ms** — I refused; a hallucinated table — execute as role, fail closed; DNS as registrar versus Route 53 versus ALB — I configured that path, I will not invent an hours-long outage. Reports **40%** faster, analysis **+65%**, **30** dashboards **+60%**, **99.9%** uptime. I did not shard. I did not run EKS. No ticket ids. If they want the other live: Horizon, ERC date immovable, dirt ≠ Gazebo. Operator feed at **60 FPS** while the costmap was stale. Downsample viz, keep density for planning, fuse instead of a late sensor PO. **17th / 80+**, obstacle **+40%**, collision **−55%**. No missed ERC on the resume. Stop. Let them pick a class. --- ## Probe sheet (stay on one class) **Why Redis not bigger RDS?** Repeat NL and schema lookups are cache-shaped. **−35%**. No TTL invented. **Why RLS after cache?** Cached leak is a leak. **Why not Lambda?** Always-on BI. ECS. Cold start / 15 min cap are CS. Not the Ylogx bullet. **Why not one Flask?** NestJS role modules; FastAPI SQL RAG; Postgres RLS. **Java?** Live Code Java. This product Python/TS. Same SET ROLE idea. **Kafka / EKS / shard / bill / p95?** No. No. No. No. No. **SEO 403?** Prep-only. Not the lead. **Rate limiter?** Not shipped. Redis here is the bot cache. **LangSmith on Ylogx?** No. SQL shape + denied-tier fixtures. **Missed 99.9% / missed ERC?** Not on the resume. I will not invent them. --- *End of fragment. Do not edit Answer-BIBLE.md. R3/R4. Job 10454435 still none. Failure classes, not fake tickets.*