Search

Search work, writing, and fragments.

about

A little context behind the work.

I like software that is easy to use, hard to break, and still understandable after the first rush of shipping is over.

story

I study computer engineering, but most of my learning has come from projects that stopped being simple the moment someone else had to depend on them. I like that turn: when a neat idea becomes a tired student trying to find the right paper, a protocol mismatch that needs a replayable fixture, or a small kernel fix that has to survive people who know the subsystem better than I do.

The work I care about has to be clear at the surface and honest underneath. A tool should feel direct to the person using it, but the internals should leave a trail too: named failure modes, careful boundaries, and decisions that still make sense after the first rush of shipping is gone.

That is why upstream work matters to me. It removes some of the private mythology around a patch: the reasoning either survives public review, or it shows me exactly where it has to get sharper.

  • work I choose Product software, protocol tooling, and verification-heavy systems where correctness changes the result.
  • working style Start with the real use case, name the failure modes, and keep the implementation small enough to inspect.
  • looking for Developer infrastructure, product systems, and correctness-heavy software with real users and real constraints.

principles

  • Name the failure mode before decorating the solution.
  • If a system asks for trust, make the boundary inspectable.
  • Prefer small, reviewable changes over clever machinery.
  • Choose work that teaches judgment, not just speed.

What I want to work on

  • Systems where the engineering has to be solid because people actually rely on it.
  • Tools that get out of the way and make a hard workflow feel simple.
  • Environments that force me to understand the layers beneath the code I write.

recognition

Recognition belongs here only when it points back to the work: a real problem, a constrained build, and enough public evidence to inspect what happened.

PromptWars × AbhiyantriX / 2026

Top-ranked coding-round submission among 332 participants; advanced to the pitching round.

I built Orvio, a smart event management platform, for PromptWars × AbhiyantriX. My submission scored 96.98 and ranked 1st among 332 participants in the coding round, earning advancement to the pitching round. Evaluation covered code quality, security, efficiency, testing, accessibility, and alignment with the problem statement.

  • result 1st of 332, coding round
  • score 96.98
  • next round Advanced to the pitching round
  • project Orvio — smart event management platform

OrchidHackX / 2026

1st place in the Cybersecurity Track with ShallowFake.

As team Secure Bytes, we built ShallowFake, a pre-publication privacy layer that adds imperceptible adversarial noise to face photos so they remain visually unchanged to people while disrupting deepfake pipelines. The prototype combines a FastAPI protection service with a React workflow, quality reporting, metadata stripping, rate limiting, and a no-retention policy for original images.

  • result 1st place, Cybersecurity Track
  • project ShallowFake
  • team Secure Bytes
  • scope Pre-publication face-photo protection against deepfake pipelines

HackForUHC / 2026

1st place at HackForUHC 2026. Continued as NIYAM and presented at an AeHIN international webinar.

As team CLAIM∅, we won 1st place at HackForUHC 2026 (June 18-19). We were invited to present at the 10th anniversary openIMIS Community Meeting in Kathmandu (June 23-25), and after that the project kept going at the Health Informatics Lab at KU under Prof. Rabindra Bista. It turned into NIYAM: a claim validation layer that sits in front of openIMIS and catches bad claims before they reach a reviewer. On August 27, the team — Aman Karn, Laxman Acharya, and I — presented the system architecture and a live demo at the AeHIN Hour webinar.

  • result 1st place, overall hackathon
  • team CLAIM∅
  • continued as NIYAM — claim validation layer for openIMIS
  • presented AeHIN Hour webinar, August 27, 2026

JunctionX Kathmandu / 2026

JunctionX Kathmandu 2026 with Team Pikachu.

As team Pikachu, we worked on a constrained build around a local energy problem at JunctionX Kathmandu 2026. The result opened the next round of work in Finland, but what belongs here just as much is the support around it: the mentors, organizers, teammates, and KU community who made the work possible.

  • result Overall Winner + Hydropower & Sustainable Energy Track Winner
  • team Pikachu
  • next Golden Ticket to the global Junction stage in Finland

Google TMT Hackathon / 2026

1st place in the File Translation Tool Track with SANAD.

As team SPAN, a two-person team, we built SANAD for the Google TMT Hackathon 2026 under KU ILPRL's Google-supported Trilingual Machine Translation project. The product turns public-service documents into a reviewable translation workflow with protected-entity checks, scoped memory, risk flags, human review, and export-ready output.

  • result Winner, File Translation Tool Track
  • team SPAN, two-person team
  • scope English / Nepali / Tamang public-service document translation

upstream

The contributions below are small on purpose: concrete enough to inspect, strict enough to review, and real enough to affect behavior that other people depend on.

Linux / Kernel / 2026

Linux kernel contributions across Bluetooth memory safety, DRM/PCI controller fixes, KUnit, and core library paths.

The work spans 14 commits verified in mainline Linux: Bluetooth memory-safety work, an OpenVPN keepalive peer-lifetime fix, AMD XDNA debug BO sync, PowerVR userspace array stride handling, PCI/DWC/Meson teardown and error-path fixes, KUnit tooling fixes, cmdline next_arg() coverage, printf IPv6 tests, seq_buf export/KUnit coverage, and IIO DMA and PowerVR fixes tagged for stable. Related accepted upstream work includes a FUSE/io-uring request-lifetime race report.

  • scope Bluetooth memory safety / AMD XDNA debug BO sync / PowerVR userspace array stride handling / PCI controller teardown and error paths / OpenVPN peer lifetime / FUSE io_uring request lifetime / KUnit tooling / cmdline and seq_buf tests / printf IPv6 coverage / IIO DMA fix
  • through Maintainer-reviewed upstream workflow

LLVM / AArch64 backend / 2026

Fixed-point SCVTF/UCVTF scale operand validation in LLVM.

Merged in llvm/llvm-project#213490, this gives the fixed-point SCVTF/UCVTF scale operands the ParserMatchClass that fixedpoint_i32/i64 already carried. Without it, a symbolic scale could reach the encoder and hit its MO.isImm() assertion, and an out-of-range scale could alias a valid encoding instead of being rejected. The operands now use Imm1_32Operand and Imm1_64Operand, and the MC diagnostics test covers both integer source widths and the symbolic-scale case.

  • status Merged into llvm/llvm-project, approved by two AArch64 backend reviewers
  • scope TableGen operand definitions / AArch64 assembly parsing / MC layer diagnostics
  • evidence Diagnostics coverage for both integer source widths and symbolic scales

ROOT / CERN scientific computing / 2026

TFormula Hessian result sizing in ROOT.

Merged in root-project/root#22877, this fix makes TFormula::HessianPar() validate storage against the full fNpar × fNpar Hessian size instead of accepting a buffer large enough for only fNpar entries. The existing ResultUpsize regression now covers the two-parameter case that exposed the mismatch.

  • status Merged into root-project/root
  • scope C++ / TFormula / automatic differentiation / Hessian storage
  • evidence Targeted regression coverage plus maintainer approval

Indico / CERN event platform / 2026

Webpack manifest thread-safety fix in Indico.

Merged in indico/indico#7675, this fix stops a half-initialized manifest from being published to the thread-shared cache. Under uWSGI with more than one thread and a customization directory configured, a second request could read the manifest after __custom.css was added but before __custom.js, and fail until the worker warmed up. The manifest is now cached only once it is fully populated, and the regression test pins the interleaving across two threads so the race reproduces deterministically instead of by chance.

  • status Merged into indico/indico, credited in the release changelog
  • scope Python / shared cache thread safety / webpack manifest loading
  • evidence Deterministic two-thread regression test plus maintainer review
  • credit Fix implemented and tested from a maintainer-triaged report

Cilium Tetragon / eBPF / 2026

Kprobe return-path validation and schema clarification in Tetragon.

Merged in cilium/tetragon#4601, this series rejects unsupported returnArgAction values on kprobe return paths, adds regression coverage, and carries the clarified semantics through CRDs, docs, vendored schema copies, and examples. An earlier Helm template cleanup also merged in #4631.

  • status 2 merged pull requests in cilium/tetragon
  • scope Kprobe return-path validation / tracing-policy docs and CRDs / Helm packaging cleanup
  • evidence Regression coverage plus maintainer-reviewed upstream workflow

Linnix / Linux observability / Rust / 2026

Process-event lifetime and deployment handling in Linnix.

Merged in linnix-os/linnix#43, this fixes exit-event pruning that compared timestamps from two different clocks. It now uses the queue timestamp with saturating subtraction and includes a regression test. The same PR made install paths configurable and added an uninstaller that preserves the data directory.

  • status Merged into linnix-os/linnix
  • scope Rust / process-event pruning / install and uninstall lifecycle
  • evidence Regression coverage plus maintainer review

Pyrefly / Type checker / 2026

Stub descriptor semantics in Pyrefly.

Merged in facebook/pyrefly#3151, this fix makes stub and interface declarations use descriptor protocol lookup instead of exposing raw descriptor types. It closes #3045, adds regression coverage for inherited .pyi descriptors, and the mypy_primer run reported fewer real-world false positives.

  • status Merged into facebook/pyrefly
  • scope Descriptor protocol / .pyi stubs / type inference
  • evidence Regression test plus mypy_primer signal across real projects

Bitcoin Core / PSBT and descriptors / 2026

Two authored fixes merged into Bitcoin Core: the PSBT combiner and the descriptor parser.

Both merged on August 24, 2026. In bitcoin/bitcoin#36025, PSBTInput::m_tap_scripts maps a leaf script to a set of control blocks but is serialized one record per control block, keyed by the control block, while PSBTInput::Merge unioned it by the map key. Two PSBTs mapping one control block to different leaf scripts merged into an input serializing the PSBT_IN_TAP_LEAF_SCRIPT key twice, so combinepsbt returned a PSBT that decodepsbt then rejected as invalid, a defect present since v24.0. Merging per record rather than per map entry also stops the union from dropping control blocks that do not conflict. I found it by adding a "combining must round-trip" assertion to the PSBT fuzz target and reported it with a minimal pair on #35665, where another contributor reproduced it. In bitcoin/bitcoin#34697, the miniscript duplicate-key check compared two key expressions by deriving each at index 0 against an empty signing provider, so any expression with a hardened step came back empty and compared equal to any other such expression: a musig() descriptor reusing the same participants in one tapleaf was rejected as "contains duplicate public keys" as soon as one participant was a private key on a hardened path, while the all-xpub spelling of it imported fine. The check now derives against the signing provider populated during parsing and only compares expression strings when neither side resolves. A reviewer found a second bug on the same branch: OriginPubkeyProvider::GetPubKey() prefixed its origin onto whichever entry was already in the output provider, so a participant expanded by a second expression had m/86h/1h/0h come out as m/86h/1h/0h/86h/1h/0h in the input and output taproot BIP32 derivation maps of a PSBT, sending a signer that follows them to the wrong key. Both are fixed here.

  • status Both pull requests written by me and merged into bitcoin/bitcoin on August 24, 2026; #34697 is milestoned for the 32.0 release
  • scope PSBT combiner / BIP 371 taproot leaf script records / descriptor and miniscript key comparison / musig() participant key origins in PSBTs
  • evidence Three ACKs on each pull request, in both cases including the maintainer who merged it; regression tests added in rpc_psbt.py, descriptor_tests.cpp, and wallet_musig.py

Bitcoin Core / LLVM compiler-rt / 2026

TSAN and glibc fortify investigation for a Bitcoin Core timeout.

Investigated an intermittent Bitcoin Core TSAN timeout and traced the failing path to glibc fortify emitting __read_chk for TokenPipeEnd::TokenRead(), which did not go through TSAN's normal intercepted read path. The public issue thread records the diagnosis; a Bitcoin maintainer later linked the issue to an LLVM compiler-rt fix for fortified read/pread interceptors.

  • status Public upstream investigation; not counted as a merged LLVM code contribution
  • scope Bitcoin Core functional test timeout / glibc _FORTIFY_SOURCE / TSAN signal handling / compiler-rt interceptors
  • evidence Issue-thread diagnosis, maintainer follow-up, and merged LLVM PR addressing the same missing fortified read/pread interceptor path

Bitcoin Core / RPC and wallet / 2026

A review finding and a co-authored commit in Bitcoin Core.

Reviewing bitcoin/bitcoin#35946, I found that the generated OpenRPC schema described type_str arguments as number | string while all four RPCs behind that override parse the numeric form as an integer, so 0.5 validated against the published schema and was then rejected at runtime with "JSON integer out of range". A maintainer agreed with the tightening, and the pull request author made the one-line change and attributed the commit to me. On bitcoin/bitcoin#35955 I worked with the author on the commit finishing a legacy wallet cleanup and am credited with a Co-authored-by trailer: LegacyScriptPubKeyMan had been deleted earlier, but an orphaned forward declaration in wallet/rpc/util.h, the SetupLegacyScriptPubKeyMan() name, several comments, and an inactive-HD-chain log message still referred to the removed class.

  • status Both pull requests merged August 18, 2026; the code was written by their authors
  • scope OpenRPC schema generation / RPC argument parsing / legacy wallet declaration cleanup
  • evidence Review finding endorsed in-thread by a maintainer and addressed in the merged branch; Co-authored-by credit recorded on the wallet commit

Dify / Agentic workflow platform / 2026

OpenTelemetry decorator typing cleanup in Dify.

Merged in langgenius/dify#32163, this refactor tightens OpenTelemetry decorator typing in the API service while preserving runtime behavior. A separate prompt-template typing cleanup remains open and is not counted here.

  • status 1 merged pull request in langgenius/dify
  • scope Python typing / OpenTelemetry decorator ergonomics
  • evidence Merge commit verified reachable from langgenius/dify main