nayan roy

Kolkata, India · IT undergraduate, 2028

Most bugs don’t crash.
They return something plausible.

I build backend systems where the interesting failure is a confident wrong answer, not an exception. Below is the one that took three attempts to get right — a nine-line detector in a satellite-imagery pipeline that was correct, then wrong, then measuring something else entirely.

Offset detector · % pixels below floor7 scenes, one tile
threshold 1%offset present — 0.00%offset absent — 3.488.17%0%2%4%6%8%

Populations separate — the threshold holds

Widening the sample from one tile to 48 scenes across 8 regions — deliberately including desert and salt flat, where dark pixels barely exist — showed the rule misclassifying 36% of offset-absent scenes. It was measuring terrain, not the offset. The replacement is one-sided: a low floor proves the offset absent, a high floor proves nothing, and where the pixels can’t decide it declines and attaches a warning. Across those 48 scenes it misclassifies none, against 17 for the rule it replaced.

Selected work

All case studies →
live

Bhoomi

Draw an area, search Sentinel-2 through STAC, run an index or a two-date change detection server-side, and get back a validated Cloud-Optimized GeoTIFF. One API request in place of a seven-step desktop GIS workflow.

A detector that returns “I don’t know” rather than a plausible wrong answer.

published

gitto

Plain-language Git and GitHub in the terminal. Save, upload and sync instead of add, commit and push — with every Git or GitHub error translated into a sentence you can act on.

One product, two interfaces: the interactive palette and the piped-stdin fallback ask identical questions.

published

sealpin

npm audit for the MCP servers your AI agent trusts. A supply-chain and prompt-injection scanner that finds which servers can read your SSH keys, which changed their tool definitions since you approved them, and which hide instructions to the model inside tool descriptions.

The lockfile, not the linter — a scan runs once, a pinned manifest defends against the rug pull forever.

built

PayHub

UPI-first payment orchestration over Razorpay and Cashfree. One unified API, decline-code-aware failover between processors, and webhook events from different providers normalized into a single internal schema.

Knowing when not to retry: a decline scoped to the customer’s own bank can never be fixed by switching processor.

built

Jewellery Billing

A mobile-first gold billing app for Indian shop owners, built around a single number: a bill in under 30 seconds. Live price breakdown, PDF invoice, WhatsApp share.

Offline-first rather than offline-tolerant — a billing app that stops when the Wi-Fi drops isn’t a billing app.

Live from GitHub

9 repos · last push 3 days ago
TypeScript · 6Python · 2JavaScript · 1

Working method

I write down what a system can’t tell you as carefully as what it can. Every repository I maintain has a limitations section, and on the geospatial one it’s longer than the feature list — because the failure that matters there isn’t a crash, it’s a raster that looks fine and is systematically biased.

The same bias shows up in the routing engine that refuses to retry a payment when the decline came from the customer’s own bank, and in the scanner that hashes a tool manifest so a later version can’t quietly change what a model is told. Narrow and honest about its edges beats broad and quietly guessing.

Get in touch · Sign the guestbook