We build AI systems that organisations can own.
Agentic software, data products and remote-sensing analysis — engineered to run on your infrastructure, in your language, and to show their work.
Three decisions that recur in every project
These are not stylistic preferences. Across seven codebases, all three recur — deliberately, and on the record.
You own it
On-premise deployment, read-only access, local models, role-based control and a full audit trail. An organisation that cannot send data outside its network is not served by a degraded mode.
Persian-first
Right-to-left as architecture, Jalali dates in analytical SQL, Persian normalisation treated as a correctness problem, and language corpora we built ourselves.
The work is shown
Every answer traces to the query that produced it. Decisions are recorded with the evidence that killed the alternatives. Limitations are published alongside features.
Most organisations cannot send their data somewhere else
Banking, insurance, steel, mining, healthcare — each has a serious reason data cannot leave: regulation, confidentiality, or simply a network with no outbound path.
Most AI vendors have no commercial incentive to solve this — their revenue is attached to the cloud. The result is that the organisations with the most need for analysis have the fewest options.
"Does our data leave our network?"
"Can this run with no internet at all?"
"Where did this number come from?"
Those three questions are the architecture of everything we build.
What we have built
Each solves a real organisational problem, and each page states its own limitations.
DataCopilot
Turns the question-to-answer cycle from five to seven days into minutes — and shows its working.
Read more →ZetaMine
Narrows where to look before anyone puts a drill in the ground.
Read more →Sanjaneh
Turns a 240-item sitting into a profile a person can read and an assessor can defend — with every number traceable back to the answer that produced it.
Read more →Legal Research Platform
The hard part of a legal AI is the corpus underneath it. That part is built, measured, and honest about what is still missing.
Read more →Selected work
Building a 1.8 GB Persian legal corpus
A legal corpus and platform built to the point where retrieval becomes an engineering problem instead of a guess.
Mineral explorationBuilding a clean Landsat corpus for mineral exploration
Caught an 80% duplicate rate in a supplied dataset before a single annotator hour was spent on it.
Industrial and mining softwareMigrating 29 repositories onto self-hosted CI/CD
Twenty-nine repositories and their pipelines onto infrastructure the client controls, with the two failure modes that cost the most time written down.
We publish what we learn
Writing about work we actually did — with the numbers, the code, and the places the approach stops working.
Updating model weights in an air-gapped environment without breaking the air gap
A complete, runnable air-gap model-update procedure — bundle manifest, detached signature, safetensors-only gate, Ollama blob mirroring, settings-table rollout and rollback — assembled from first principles because almost no vendor documents the steps between 'download the weights' and 'the isolated cluster is serving them'.
GPU sizing for on-premise LLMs: a worked calculation for 50, 200 and 1,000 concurrent users
A complete sizing calculation carried end to end — from concurrent users through Little's law and a Poisson tail to in-flight requests, then through exact KV-cache-per-token arithmetic and a memory-bandwidth roofline to a GPU count — with every assumption named and the non-obvious result that past a few dozen long-context streams the KV cache, not the weights, sets the hardware bill.
The no-egress checklist: every outbound call an LLM stack makes, and how to kill each one
A complete category-by-category inventory of outbound calls in a self-hosted LLM stack, including the four almost nobody lists — OCSP and CRL fetches during TLS validation, ACME certificate renewal, snap and package auto-refresh, and the application's own user-controlled URL fetches — each paired with the control that actually stops it and a network-namespace method for proving the stack still works without any of them.
ASTER, Sentinel-2, PRISMA or EnMAP: a practical decision table for alteration mapping
A single decision table covering ASTER, Sentinel-2, PRISMA, EnMAP and EMIT against the criteria that actually determine a project — spectral sampling at 2.2 micrometres, the ASTER SWIR failure of April 2008, the absence of a blue band, tasking and redistribution rights — plus the reasoning behind a real corpus-engineering decision to reject ASTER outright, and an explicit account of why published classification accuracy does not measure exploration success.