Home

How I actually work

Stark had JARVIS. I have Claude Code.

Tony Stark at a workbench with the arc reactor lit, captioned: genius is undeniable.

I have built one of these for myself, so I am not speculating about what the partnership feels like. What I want to talk about here is the other half of it — the part that is not the assistant. Anyone can hand a model a problem. Almost nobody hands it a set of rules it is not allowed to break.

Most people treat these models as a faster autocomplete. I treat mine the way Stark treated JARVIS:I decide what is true and what the rules are, and it does the part that scales.

The difference shows up in the artefacts. Anyone can say they are good at directing AI. Below is what that actually looks like in a repository, with the files.

  1. 01

    I write the constitution before the code

    Every project starts with a file the model has to obey — the invariants, the things that must be structurally impossible, and the taste rules. Sehat Saarthi's opens with a locked section marked "only Shaurya may edit; Claude must NEVER weaken these", listing seven safety rules, above a protocol that lets the agent rewrite its own tactics but never that spine.

    2 receipts
    • sehat-saarthi/CLAUDE.mdThe locked mission-and-safety section, and the rule that tactics may change but the spine may not.
    • braillix/CLAUDE.mdThe same pattern: the unforgivable failure named up front — "a silent wrong answer".
  2. 02

    Every decision gets written down, append-only, including the wrong ones

    Sifarish carries 168 numbered decisions that are never deleted. That is not documentation theatre — it is what makes the sixth session able to reason about what the second one decided, and it is why the codebase has rules dated to specific live failures rather than vague best practice.

    2 receipts
    • sifarish/DECISIONS.mdD1 through D168, append-only, plus two later series.
    • plan.ts:466A validator rule carrying the date and the exact model failure that caused it.
  3. 03

    I build adversaries, not assistants

    The useful move is not asking a model to write the thing. It is pointing a second one at the finished thing and telling it to break it — an agent starting with no memory of how the thing was built, so it cannot inherit my reasons for thinking it is fine. Aaina generates nine different people and grades the writing each of them gets. Sifarish invents thousands of its own inputs and can replay any failure exactly. Both found real defects on their first run, and both are open below.

    2 receipts
    • aaina/scripts/audit.tsNine personas generated and graded on the finished prose, two of them built to be nearly identical.
    • sifarish/tests/matrix.test.tsA test that invents thousands of its own inputs. It found two real bugs on its first run, and any failure can be replayed exactly.
  4. 04

    The machine is not allowed to be trusted

    Before any change of mine is allowed to be saved, a script scans it for eight shapes that look like a leaked password, and then runs every check the project has. The build greps its own source and fails if a banned library appears. None of that protects me from the model — it protects the product from me at 3am, and the model is simply held to the same line.

    2 receipts
  5. 05

    I read the rendered thing with my own eyes

    A green test suite proves nothing about how something looks or reads. Sifarish has that written down as a project skill — literally a file instructing the loop to open the rendered PDF and look at it. Braillix photographs every screen at phone, tablet and laptop width, every single time, and fails if anything spills sideways.

    2 receipts
    • braillix/e2e/screens.spec.tsEvery screen captured at phone, tablet and laptop width, each one checked for sideways overflow.
    • sifarishThe "read it with your eyes" verification loop codified as a reusable project skill.

The honest version of the Stark line is this: the speed is not mine and I am not going to pretend it is. What is mine is the taste to know when the output is wrong, the discipline to write down why, and the willingness to delete a working model at midnight because it lied to me. JARVIS was never the interesting half of that partnership.

NGC 1275 — the magnetic monster

These filaments should have dispersed long ago. Something invisible is holding them.

Threads of gas stretching thousands of light years, far too thin and too hot to survive on their own — held in shape by magnetic fields nobody can photograph. The structure is evidence of a force you can only infer.

NGC 1275 · NASA, ESA and the Hubble Heritage Team (STScI/AURA) · CC BY 4.0

Under the hood

Eight ideas, explained like you're a person.

Anybody can put "RAG" on a CV. Here is each one in plain words, usually with the mistake most people make alongside it, and always with the exact line of my code where I dealt with it. The precise, jargon-heavy version is one click down if you want that instead.

  1. 01

    Giving a model facts — then removing its ability to ignore them

    Everyone bolts a search onto a chatbot and calls it grounded. That only counts if the model is forbidden from saying anything the search did not return. In mine it is: a sentence with no fact behind it does not get styled red or flagged for review — the page refuses to render at all.

    The precise version

    Retrieval is only worth it if the retrieved thing is allowed to constrain the answer. In Aaina the model receives a closed evidence bundle and may write nothing outside it; in Sifarish the retrieved facts are the only things the compiler is permitted to place. Both are retrieval-augmented — but the augmentation is a hard boundary, not a hint.

    2 receipts
    • derive.ts:28One deterministic function builds the entire evidence bundle the model is allowed to see.
    • compiler.ts:284A line with no retrieved fact behind it throws rather than rendering.
  2. 02

    Grading the answer, not the fact that an answer arrived

    Most testing proves the machine replied, which is like marking an exam on whether the pen worked. So I write two people who look nearly identical on paper, run both all the way through, and fail the entire build if either one is handed a sentence that could just as easily have gone to the other.

    The precise version

    Most eval harnesses check that a call returned. Mine check whether the thing produced is any good. Aaina generates full reports for nine personas — two built to be almost identical — and fails if either gets a sentence the other could have been given. Gloaming pits a smart bot against a greedy one on identical seeded games to prove skill actually pays.

    2 receipts
    • audit.ts:21Nine personas, adversarially similar by design, graded on the finished prose.
    • PROGRESS.md:17A measured +16-point skill gap on paired seeded games.
  3. 03

    Rules a model cannot talk its way around

    If your safety rule is a sentence inside a prompt, it is a polite request to something that is very good at conversation. I would rather the bad outcome be impossible to express: Sifarish searches its own source code as it builds and refuses to compile if any file so much as imports something capable of sending an email.

    The precise version

    A guardrail written as a prompt instruction is a suggestion. I prefer ones that make the bad state unrepresentable: a thrown exception on an uncited line, a braille line that cannot exist without a human confirmation, a required disclaimer field on the response schema, a grep over the source tree that fails the build if a mail library ever appears.

    3 receipts
    • lesson.ts:21A recognised line is unrepresentable without an explicit confirmation.
    • schemas.py:21The disclaimer is a required field, not a UI convention.
    • invariants.test.ts:85The build greps its own source and fails on any send-capable library.
  4. 04

    Borrowing a trained brain instead of raising one from scratch

    Teaching a model to see from nothing takes a warehouse of pictures and a room full of GPUs. So you take one that already knows what an edge and a texture are, and teach it only the last part — the part that is actually your problem. I have done it both ways: the expensive way on 17,736 real telescope images, and the cheap way for a clinic app with no GPU anywhere in the budget.

    The precise version

    I fine-tuned a ResNet50 end-to-end on 17,736 real survey images, then ran the same experiment at four labelling budgets to find where the curve flattens. In Sehat Saarthi, with no GPU, I went the other way — froze an ImageNet backbone and trained only a class-balanced head, then exported the whole thing to a single ONNX graph so it runs on a free CPU tier.

    2 receipts
    • galaxy-morphology-transferResNet50 fine-tuned on Galaxy10-DECaLS, four label regimes, macro-F1 as the primary metric.
    • training/Frozen MobileNetV2 feature extractor plus a class-balanced logistic head, exported to ONNX.
  5. 05

    Making “80% sure” actually mean eighty per cent

    A model saying 80% does not mean it is right eight times in ten. Usually it just means it is loud. In a clinic that is the number that does the damage — worse than being wrong — because a family reads it and believes it. So every probability the app shows is put through a correction that forces it to match how often it is really right, before a human ever sees it.

    The precise version

    An uncalibrated probability on out-of-distribution input is confident nonsense, and in a clinic that is far more dangerous than being wrong. Every tabular model in Sehat Saarthi is isotonically calibrated with five-fold cross-validation, because the number a health worker reads has to mean what it says.

    1 receipt
    • training/CalibratedClassifierCV with isotonic regression, cv=5, across all five tabular modules.
  6. 06

    Choosing the right yardstick, out loud, before seeing the result

    If ninety per cent of your examples are one thing, a model that always guesses that thing scores ninety per cent and has learnt absolutely nothing. So you measure a different way — and you commit to which way in writing first, because if you pick afterwards you will pick whichever number flatters you. That is not statistics, that is marketing.

    The precise version

    Choosing macro-F1 over accuracy because the classes are imbalanced and saying why. Validating a detector by planting a known signal and measuring recovery instead of reporting a number with nothing to compare it to. Deriving composite weights from two published effect sizes rather than tuning them until the output looked nice.

    2 receipts
    • READMEMacro-F1 chosen as primary, with the reason stated and class-weighted loss.
    • dimensions.ts:23"If you disagree with a weight, you disagree with Joel 2020 or Le 2010, not with us."
  7. 07

    The whole thing running on your laptop, with the Wi-Fi switched off

    A blind student’s work is not allowed to leave the room, so there is no server to send it to. A 76 MB vision model and a complete text-reading engine live inside the browser tab instead. If even one of the eleven pieces it needs is missing or arrives truncated, the build stops — because an app that is quietly only half-offline is worse than one that admits it cannot run.

    The precise version

    Braillix runs a 76 MB vision model and a full OCR engine inside the browser, offline, because student work must never leave the room. That meant a web worker, a hand-written service worker, self-hosted weights, and a build step that refuses to ship if any of the eleven required assets is missing or truncated.

    2 receipts
  8. 08

    Getting a model to return something a program can actually use

    Ask a model for clean data and it will cheerfully hand you a paragraph with a curly bracket stuck on the front. I ran the experiment rather than guessing: one request mode failed three times out of three, another worked — so the fix was the mode, not the temperature dial everybody reaches for first. Same story with speed limits: I measured that the provider bills you for tokens you might use, then spaced the requests around that.

    The precise version

    I found out by controlled experiment that JSON-schema mode succeeded where JSON-object mode failed at any temperature — and wrote the counts into the file. Separately, Aaina fans its sections out in waves of three, thirty-five seconds apart, because Groq reserves max_tokens against the per-minute budget at request time, so three concurrent sections rate-limit before a word is generated.

    2 receipts
    • dimaag/core.ts:57The measured probe: 0/3, 0/3, then 2/3 — the mode was the variable, not temperature.
    • compose.ts:40Wave scheduling derived from measured per-request token reservation.

Also in the toolkit

Python · TypeScript · PyTorch · SQL · Hugging Face · Groq · Git · Claude Code. Also LoRA fine-tuning and local models through Ollama — I've worked with both, I haven't shipped anything public with either, and I'm telling you that rather than letting you assume otherwise. Everything above this line has a link under it. This is where the line is.

AI Mentorship Programme — LaunchED Global (IIT Kharagpur / KSHITIJ), credential LEDCC4828 · Predictive Analytics guided projects — LinkedIn Learning, via TIET

Writing

Things I've argued in public

PRANA — A Layered Framework for Sustainable AI Compute

Position paper · July 2026 · 5 pages · 24 references

The whole paper turns on one reframe: computation does not consume energy, it relocates and degrades it. A data centre turns almost all of its input electricity into low-grade heat, and the water use is a design choice — evaporative cooling — not a requirement of computing. So the problem is not consumption. It is exergy misplacement: we generate heat where it has no value, destroy it at the cost of water and capital, and burn gas somewhere else to make the identical heat.

  1. P
    Physics-aligned hardware

    Lowest joules per operation at each tier — photonic and analog in-memory accelerators, liquid cooling as the default rather than the upgrade.

  2. R
    Right-sized intelligence

    Route every query to the smallest model that clears its quality bar. Distillation, quantisation, sparsity, cascades.

  3. A
    Adaptive scheduling

    Most of the fleet is deferrable in time and movable in space. Schedule it against grid carbon, regional water stress, and demand for the exhaust heat.

  4. N
    Negative-waste symbiosis

    Plumb the building so its rejected heat has a customer — district heating, industrial pre-heat, greenhouses. Turn a compliance number into a revenue line.

  5. A
    Accountability metrics

    Retire PUE. Measure energy-reuse-per-token: the fraction of the energy behind each token that went on to serve a second human purpose.

Follow-the-Cold routing

The inversion of follow-the-sun. Heating demand is one of the most predictable loads on Earth and it is hemispherically anti-correlated — January in Finland is July in Chile. So move deferrable work toward wherever its waste heat currently displaces a fossil boiler. The round trip costs 100–200ms, which a batch job does not notice. The carbon credit then includes the boilers you switched off, which no existing scheduler models.

The Compute Boiler

A 1–50 MW facility sitting inside a district-heating network. It draws power when renewables are over-supplying, does deferrable AI work, banks the resulting 55–65 °C heat in cheap water tanks, and releases it on the evening demand peak. One asset sells three products — grid flexibility, heat, and computation — against a single energy purchase.

I argued against myself in section 3.2, because Jevons' paradox is the obvious objection and it deserves an answer rather than a silence: efficiency alone slows the demand curve without bending it down. I also killed orbital compute as a 2026 strategy in 3.4, despite it being the most exciting option in the paper, because the launch economics do not work until roughly 2035. And I said plainly in the limitations that both proposals are architectures with plausibility arguments behind them, not measured deployments.

1 receipt

Label-Efficient Transfer Learning for Galaxy Morphology

Write-up · April 2026 · 10 references, 6 of them 2024–2025

Transfer learning on 17,736 real survey images, asking how few labels you can get away with before the curve flattens. The chart and the finding are in the Data & Signal chapter above — the short version is that 5% of the labels gets you 86% of the way, and the classes worth paying to annotate are the ambiguous ones, not the rare ones.

Two things I'd flag if you read it. I ran a single seed, and said so — multi-seed with error bars is the obvious next step and I haven't done it. And I've retitled it here: the original said "semi-supervised", but the pseudo-labelling stage is future work and was never run. A title that overclaims is exactly the kind of thing the rest of this page is about not doing.

1 receipt