Full-stack engineer with a physics-and-maths background. I ship products end to end — a tree-structured knowledge tool running on five platforms, an Obsidian plugin used by thousands, plugins that put Claude Code to work on real repositories, and the Python libraries and services underneath them.
20projects built
7of them full products
10+years writing software
01
Product engineering
One data model, every surface. Web, desktop, mobile and chat clients that stay in sync and keep working offline.
02
AI agent infrastructure
Harnesses that let coding agents work on real repositories without breaking them: isolation, review gates, and a paper trail.
03
Backends & tooling
The unglamorous half: typed APIs, schema migrations, packaging, and libraries other people install.
Languages
TypeScript / JavaScript · Python · Dart / Flutter · Go · C++ · SQL
Tree-structured notes on five surfaces, with an agent inside
Web appDesktop appMobile appTelegram Mini AppTelegram bot
→
A note-taking product where everything is a node in one tree — outlines, task breakdowns, kanban boards, structured fields. The same tree runs on the web, a Tauri desktop build, a Flutter mobile app, a Telegram Mini App and a Telegram bot, staying editable offline and reconciling when the network returns.
What to learn, and in what order — university lectures as a map
Web appPWAData pipeline
→
A free catalogue of university lecture courses on YouTube, arranged by what has to come first. Every course knows what it depends on and what it opens up, so a subject becomes a route instead of a pile of links: pick where you want to end up and the site lays out the path, prerequisite by prerequisite, with the recordings for each step. 236 courses across 39 fields, 12,500 lectures from 309 universities and channels, re-crawled every night.
A plugin marketplace that puts a coding agent to work on a real repository
Claude Code pluginCLI
→
Two published Claude Code plugins behind one marketplace command. make-better audits an existing codebase across nine topics and applies the fixes; feature builds every change in an isolated git worktree with its own port and lands it through a pull request. Both are configurable per project.
claude — /make-better
$ /make-better# picks the oldest subsystems, reviews each across nine topicsTotal: 104 findings across 5 systems. - 13 bug fixes (applied automatically) - 14 DRY refactors - 11 architecture cleanups - 13 consistency fixes - 6 efficiency wins - 16 tests added - 18 doc-sync updates - 10 completeness fixes - 3 securityeach system on its own branch, merged back with --no-ff. nothing pushed.
make-better — flags
/make-better
Smart defaults — usually the three stalest systems.
/make-better 8
Review eight systems instead.
/make-better flutter 4
Four systems whose names match "flutter".
--no-discover
Skip discovery and go straight to review.
--rebuild
Force a full re-discovery of the subsystem registry first.
--yes
Unattended — no plan mode, no prompts, runs to completion.
A live Gantt of every Claude Code session, read straight from local transcripts
CLI toolWeb dashboard
→
A browser dashboard that puts every Claude Code session on one shared time axis — when the agent was working, when the human was reading, every tool call and every subagent run. It reads the transcripts already on disk, so there are no hooks to install, no config to change and no dependencies to audit.
A guide to the social graph — paste a profile, get the structure behind it
Web appHTTP APIWorker fleet
→
A research platform that turns public social-network data into something you can navigate: it crawls a profile's connections through official APIs, works out which communities the graph splits into, and ranks the traits those communities share. Six services — a React front end, a Flask API, a domain layer, a distributed request worker, a FastAPI analysis service and a token pool — built over three years and now published as one repository.
ntrail — friend graph
the query bar
GET vk.user <id> friends
The friend list of a profile, as a set you can act on
GET vk.community <id> members
Everyone in a group, ready to intersect with another set
split clusters
Break the current set into communities by graph structure
interesting properties
Rank what the current set has in common — school, university, city, age
services
frontend
React 16 + Redux; sigma / vis for the graph, recharts for the distributions
backend
Flask API over PostgreSQL — query objects, selective execution, caching
One Config object over every place a Python project hides its settings
Python library
→
A configuration library that removes the setup step entirely. Instantiate Config() and it walks up from the current file to the project root, finds the YAML, JSON, INI, .env and Python config files along the way, folds in environment variables, and exposes the result through one typed accessor.
python
$ pip install bestconfig# app/main.py — config.yaml and .env live two levels upfrom bestconfig import Configconfig = Config("myconfig.json")# that was the entire configuration stepmode = config.logger.mode # 'WARNING'port = config.int('PORT') # 5050pw = config.get('DATABASE_PASSWORD')config.to_dict() -> every source, merged
sources it reads without being told
.yaml / .yml / .json
Parsed with native types — `port: 5050` arrives as an int.
.ini / .cfg
Standard section-based config files.
.py
Python config modules, skipped if they construct Config() themselves to avoid recursion.
.env / env_file
KEY=VALUE files, including values that parse as Python literals.
Environment variables
Existing and newly set, merged with the file sources.
dict
Plain dictionaries inserted at runtime via `config.insert(...)`.
accessors
config.name
Attribute access for the common case.
config['name']
Dict access — raises KeyError when absent.
config.get('a.b.c', default)
Dotted path to any depth, with a default instead of an exception.
config.int / float / str / list / dict
Typed getters that return None when the cast fails.
config.get_raw('key')
Opt out of type interpretation entirely.
config.assert_contains('key')
Fail loudly at startup if a required setting never loaded.
A shared global note network inside Obsidian, used by thousands of vaults
Obsidian pluginWeb service
→
An Obsidian plugin that adds a public, collaboratively edited layer to a private vault. Any note can be published to a shared network, linked by URL, found through in-editor autocomplete, and edited by anyone — with changes synchronised back to every participant's vault.
Obsidian — command palette
Create note
Publish a new note into the shared network.
Update note
Pull the latest cloud changes for the note you are in.
Upload current note
Move an existing local note into the shared layer.
Sync base
Reconcile the local mirror with the cloud.
Copy obsidian url
Produce an obsidian://netwik?id=… link anyone with the plugin can open.
Delete remote note
Remove the note network-wide, not just from this vault.
how a shared link resolves
# a link to a note this vault has never seen$ open "obsidian://netwik?id=6f2c…"plugin intercepts the URL schemefetches the note from the shared storewrites it into w/ as ordinary markdownnote opens in the editor, fully linkable