# Vishnu

> Clean code standards and efficient data fetching from APIs, databases, and LLMs. Use when writing new code, reviewing code, or fetching data from any external source (REST APIs, databases, LLM providers).

- Skill: `arjuncrevathi/vishnu` (Agent Skill)
- Install (CLI): `npx skillmds@latest add arjuncrevathi/vishnu`
- Raw SKILL.md: https://api.skillmd.com/api/skills/arjuncrevathi/vishnu/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: arjuncrevathi (https://skillmd.com/u/arjuncrevathi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/arjuncrevathi/vishnu

---


# Vishnu — The Preserver (Clean Code & Data Fetching)

Vishnu preserves order: code that stays readable and data that arrives fast, validated, and exactly once.

## Naming & structure

- Names say what, not how: `fetch_active_users`, not `get_data2` or `helper`.
- Functions ≤ 30 lines, one responsibility. If you need "and" to describe it, split it.
- Max 3–4 parameters; beyond that, pass a dataclass / options object.
- Booleans read as predicates: `is_expired`, `has_access`, `should_retry`.
- No dead code, no commented-out blocks, no `TODO` without an issue link. Delete it — git remembers.

## Python

- Type hints on every public function signature; `mypy` must pass with no `# type: ignore` unless justified inline.
- Raise specific exceptions; never bare `except:` — catch the narrowest type and either handle or re-raise with context.
- Validate all external data (API responses, request bodies, LLM output) with `pydantic` models at the boundary; internals trust typed objects.

## JS/TS

- TypeScript strict mode on (`strict: true`, `noUncheckedIndexedAccess: true`). `any` is banned; use `unknown` + narrowing.
- Validate at boundaries with `zod` (`schema.parse` on API responses, form input, LLM output).
- Errors: throw `Error` subclasses with a message and cause; never throw strings. Handle rejected promises — no floating promises (`@typescript-eslint/no-floating-promises`).

## Data fetching

- Every external call (HTTP, DB, LLM) has an explicit timeout. No unbounded waits, ever.
- Use async/await end to end: `httpx.AsyncClient` / `asyncpg` in Python, native `fetch` in TS. Never block the event loop with sync I/O.
- Retries: exponential backoff with jitter, max 3 attempts, only on retryable errors (429, 5xx, timeouts). Never retry non-idempotent writes blindly.
- Batch instead of loop: one query for N ids (`WHERE id = ANY(...)`, DataLoader on the frontend). N+1 queries are a review blocker.
- Paginate anything unbounded: cursor-based pagination for APIs, `LIMIT`/cursor for DB reads. Never `SELECT *` without a limit.
- Cache reads with an explicit TTL; prefer stale-while-revalidate (serve cached, refresh in background) for hot paths. Key caches on all inputs that affect the result.
- Deduplicate in-flight identical requests (single-flight) so a burst hits the source once.

## AI-native specifics

- LLM calls are external calls: timeout, retry with backoff on 429/5xx, and validate the parsed output with pydantic/zod before use.
- Batch embedding requests (provider batch endpoints) instead of one call per document.
- Cache LLM responses keyed on (model, prompt version, normalized input); see `garuda` for semantic caching.
- Fetch context concurrently: run independent retrieval calls with `asyncio.gather` / `Promise.all`, not sequentially.

## Before merging — checklist

- [ ] Types pass (`mypy` / `tsc --noEmit`), no `any` or unjustified ignores
- [ ] Every external call has timeout + bounded retry
- [ ] No N+1 patterns; unbounded lists are paginated
- [ ] Boundary data validated with pydantic/zod
- [ ] No dead code or commented-out blocks in the diff

