Work

Everything, with the evidence attached

11 projects

Research, internship, founding-team, and personal work. Each entry leads with its result and what kind of evidence sits behind it — hover a number to see how it was measured. Open an entry for the architecture and the tradeoffs.

Measured SFU · first author

ZeroFalse

Multi-stage LLM pipeline that reduces false positives in static analysis.

best F1, OWASP Java Benchmark

How this was measured 1,974 cases across 10 CWE categories, 10 frontier LLMs from 6 model families. On real-world code — 755 CodeQL alerts from 37 Java repositories — best F1 is 0.837.

ZeroFalse pipeline: CodeQL alerts feed a stage combining related code context, dataflow extraction, and CWE-specific prompting, which an LLM then uses to identify false alerts.

Figure 1 from the paper — where the alert goes before a model ever sees it.

What I built Close

Takes raw CodeQL alerts and runs them through contextual reasoning + structured evidence validation to filter false positives. Evaluated 10 frontier LLMs across 6 model families (Gemini, GPT, Grok, Mistral, DeepSeek, Qwen) on two benchmarks: OWASP Java Benchmark (1,974 cases / 10 CWE categories) and CWE-bench, a real-world dataset of 755 CodeQL alerts across 56 project–CVE pairs from 37 open-source Java repositories. CWE-specialized prompting improved F1 by up to +0.26 on real-world code.

LLMsCodeQLPythonStatic AnalysisMulti-Stage Prompting

Null result Edinburgh · 2026

Exploit-Informed Patching — A Controlled Ablation

Tested whether showing a repair agent a working exploit produces a better patch. It does not — and the mechanism behind that null result is the finding.

no significant difference

How this was measured Sign test over 12 matched CVE pairs, win/loss/tie 6–5–1. The +3.0-point mean difference on a 0–100 scale is smaller than the harness’s own measured scoring noise (ensemble stdev 3.44), and costs ~3× as much per run.

Ablation result over 12 matched CVE pairs: exploit-informed patching scored higher on 6, alert-only scored higher on 5, 1 tie. The mean difference of +3.0 points on a 0–100 scale falls inside the harness’s own measured scoring noise of plus or minus 3.44, so there is no significant difference between the two arms. Exploit-informed better 6 Alert-only better 5 -8 -4 0 +4 +8 +3.0 Measured scoring noise ±3.44
one matched CVE pair tie noise floor, measured before the comparison

Every pair, and the mean difference against the noise floor I measured before comparing anything.

What I built Close

Research thread at the University of Edinburgh (Mitacs Globalink Research Award). The pipeline runs worktree → docker build → exploiter → patcher → post-patch exploit re-run → regression → verifier, with the exploiter required to write and validate a proof-of-vulnerability in Docker before any patch is attempted. The comparison is an ablation against itself: both arms use the same agent, the same model, and the same system prompt, and the only thing that varies is whether the exploit evidence reaches the patcher — holding prompt wording fixed deliberately, to avoid confounding "more evidence" with "differently worded prompt". Upstream alerts come from vendored third-party IRIS (ICLR 2025) over CWE-Bench-Java. The evaluation harness is a reference-anchored LLM-as-judge scoring generated patches against the real upstream fix across 8 dimensions, with K=3 ensemble medoid selection, aggregates computed in code rather than asked of the model, hard gates on vulnerability-elimination and regressions, and a noise floor measured before the harness was used to compare anything. The mechanism diagnosis: a single proof-of-vulnerability is a narrowing signal, so an evaluation gate defined on that one path rewards patches that close it rather than the bug class behind it.

LLM AgentsAblation DesignLLM-as-JudgeDockerPythonCWE-Bench-Java

Measured Farpoint · 2025–26

Fabric — Agentic IDE (Farpoint)

LLM-powered agentic IDE. I owned the multi-agent DAG orchestration, subagent system, and context-management layers.

of frontier accuracy, at 18% of frontier cost

How this was measured Aider Polyglot, 225+ exercises across 6 languages. I authored the study behind the benchmark report Fabric published in March 2026.

What I built Close

Production agentic IDE in the Cursor product space. Shipped: a six-tool subagent surface (DelegateTask / SendMessage / WaitForTask / CheckTaskOutput / StopTask / ListTasks) with headless execution, foreground/background promotion, and notification-queue injection back into LLM conversation history; a TDD-style RED→GREEN multi-agent DAG orchestrator with Mission Control dashboard; chain-of-density + KV-cache-aware summarization with unified context-budget tracking; the prepare→permission→execute tool lifecycle with path-scoped Bash/Read/Write/Edit/Glob; SWE-Bench and Aider-Polyglot evaluation infrastructure; and an MCP server exposing the test-and-break loop to AI agents. Also designed and ran a SWE-bench-with-vs-without-GraphRAG experiment over an 18,000-LoC code-knowledge-graph subsystem; the negative result (no measurable improvement) informed the team’s no-ship recommendation.

TypeScriptElectronReactLLM AgentsMCPSWE-BenchDocker

Shipped Farpoint client · BDC

BDC Market Watch — AI Strategic-Intelligence Pipeline

End-to-end news → signal pipeline shipped to the Business Development Bank of Canada in 3 weeks. Local embeddings + clustering cut LLM call volume by ~5–10× vs. a per-article baseline.

fewer LLM calls than judging every article

How this was measured Clustering before judging caps the judge at roughly 80–120 calls a day instead of one per article. Embeddings run in-process on CPU, so that layer costs nothing per call. Idea to production in 3 weeks.

What I built Close

Farpoint client engagement for BDC (Canada’s federal Crown corporation for entrepreneurs, serving the Senior Management Committee, Board, and Shareholder). End-to-end daily-cycle pipeline: multi-source poll (RSS / Atom / sitemap / JSON-feed) with a Copilot Studio Bing-search fallback agent for un-crawlable sources → deterministic noise / URL / recency filter + SHA-256 / SimHash / Jaro-Winkler dedup → in-process Xenova/all-mpnet-base-v2 ONNX embeddings (768-dim, ~15–30 ms/article CPU, cached per row) → cosine clustering against open same-category clusters at 0.65 threshold → top-K cluster selection (N=12 per category × ~7–10 BDC strategic pillars) → Microsoft Copilot Studio judge over Direct Line with strict JSON-schema validation → decision-ready Signal cards (title / summary / BDC angle / composite score). Idempotent at every stage with crash-recovery via durable per-run state in PostgreSQL.

Next.js 16TypeScriptPostgreSQLPrismaMicrosoft Copilot StudioDirect LineONNX RuntimeSentence Embeddings

Measured SFU lab

Golden Repository — Verified, Executable CVE Reproductions

LangGraph-orchestrated agentic pipeline that reproduces and patches CVEs end-to-end. 89 verified completions (61 Python + 28 Java).

CVEs reproduced end-to-end

How this was measured 61 Python and 28 Java at commit 05743f35. Each one has to clear four gates: the exploit fires on the vulnerable build, the same exploit fails on the patched build, the diff applies, and the verifier agrees — with the verdict re-read from the filesystem in a fresh context to catch the model agreeing with itself.

89 CVEs reproduced end to end: 61 in Python, shown as filled squares, and 28 in Java, shown as outlined squares. Each square is one CVE with a verified exploit, a verified patch, an applied diff, and a passing verification check.
Python · 61 Java · 28

One cell per CVE that survived all four gates.

What I built Close

SFU lab project. Eight-phase LangGraph state machine drives the full exploit-and-patch lifecycle per CVE: parallel PoC analysis across 7 sources (GitHub, GitLab, Exploit-DB, PacketStorm, Nuclei, Metasploit, vendor advisories) + advisory enrichment, 0–10 composite PoC scoring with a synthesis fallback below threshold, parallel dockerized vulnerable + patched builds, automated exploit validation that verifies EXPLOIT_SUCCESS on vuln and EXPLOIT_FAILED on patched, and a three-layer hallucination defense at validation (filesystem-grounded verdict, fresh-context re-read, persistent audit trail). Planned bolt-on: hybrid retrieval-augmented context layer (pgvector + BGE-large dense + BM25 sparse → RRF fusion → bge-reranker-v2-m3 cross-encoder) over the 89-CVE artifact corpus plus ingested public-source documents, with a Recall@10 / MRR / nDCG / p95-latency eval harness and an ablation measuring whether retrieval-augmented context improves the synthesis-fallback path.

LangGraphLangChainDockerPythonClaude Code SDK

Shipped Co-founded · 2020–23

Pabla — Crypto Social-Trading Engine

Real-time copy-trading engine for crypto markets. Iran’s leading platform in the space — ~40k users in 18 months.

users in 18 months

How this was measured Co-founded it; architected the trading engine. Smart order routing across 5+ exchanges, sub-second price fan-out, and a copy-replication state machine tracking low thousands of leader–follower pairs at peak. Funded by Finnova after a 2-month MVP.

What I built Close

Co-founded the company and architected the trading engine: smart order routing across 5+ exchanges (Binance, KuCoin, regional venues), best-execution price aggregation over a consolidated best-bid/best-ask view, per-exchange adapter pattern over a normalized internal schema, async Python + Celery, sub-second cross-exchange price-refresh fan-out via Redis Pub/Sub, idempotent copy-replication state machine (Copycat) with slippage controls and per-follower position sizing tracking low-thousands of active leader-follower pairs at peak. Shipped MVP in ~2 months; platform reached ~40k users in 18 months.

PythonDjangoPostgreSQLCeleryRedisasyncioWebSocketDockerReal-time Systems

Measured SnappFood · 2019–20

SnappFood — ETA, Churn, Fraud Models (10M+ users)

Production ML on Iran’s largest food-delivery platform: ~27% better ETA, 13% lower churn, 10% CSAT lift.

users, production ML

How this was measured Iran’s largest food-delivery platform. Adapted Uber’s DeepETA to motorbike delivery for ~27% better ETA accuracy and 24% fewer late deliveries; a churn model over 3M+ users cut monthly churn 13%; vendor-fraud detection lifted CSAT 10% and NPS from 5 to 7.

What I built Close

Customer Experience team — built the Octopus BI layer (department-specific KPI dashboards), adapted Uber’s DeepETA to motorbike delivery for ~27% ETA-accuracy improvement and 24% fewer delivery delays, shipped a churn-prediction pipeline (RFM features + logistic regression on 3M+ users) that fed reactivation campaigns dropping monthly churn by 13%, and a vendor-fraud detection system that lifted CSAT by 10% and NPS from 5 to 7.

PythonPyTorchKerasscikit-learnSQLPower BIPandas

Shipped Personal

Clarion — Voice-to-Prompt Desktop Agent

Tauri 2 macOS menu-bar agent: hotkey → Whisper → Haiku rewrite → paste. Built for bilingual developers.

What I built Close

Personal project. Tauri 2 macOS app (~2,460 LOC Rust + TypeScript/Svelte, 5 MB bundle) with global-hotkey audio capture, dual-path Whisper (OpenAI Whisper API + local whisper.cpp via whisper-rs with 5 GGML model variants), Claude Haiku prompt structuring with shallow project-context injection (CLAUDE.md / README.md / package.json), and auto-paste via osascript. Five-phase state machine: idle → recording → transcribing → structuring → pasting with live UI feedback. Planned upgrade: tree-sitter + tantivy symbol index and a two-stage grounded rewrite with deterministic Levenshtein identifier guard.

RustTauriSvelteWhisperwhisper.cppAnthropic SDK

In progress

Running, planned, or written up but not measured

3 projects

Nothing here has a headline number yet, so none of them get one.

Shipped SFU · first author

ThreatEZ — Automated Bottom-Up Threat Modeling

6-phase static-analysis-grounded multi-agent pipeline shipped as a VS Code extension; derives architecture + STRIDE threats from source code.

What I built Close

SFU CMPT 785 first-author course paper (ACM-formatted). Six-phase pipeline: static cartographer (AST/regex extraction of routes, DB ops, auth, inputs, external interfaces) → MCP context gathering (DeepWiki / Context7) → architecture inferrer → planner-driven exploration loop (Strategic Planner + Code Analyst agents refining the DFD and ThreatFindings with code-level evidence) → verifier → synthesizer with STRIDE + CWE / OWASP Top 10 enrichment. Output conforms to the OWASP Threat Model Library JSON schema v1.0.2.

LLMsSTRIDEStatic AnalysisMCPVS Code ExtensionOWASP

In progress SFU lab · ongoing

AutoSec — Fully Agentic Vulnerability Remediation

End-to-end agentic system that takes a raw codebase through detection, triage, and validated patch generation.

What I built Close

SFU lab project, ongoing. Multi-agent workflow: a detection agent that runs and interprets static analyzers (CodeQL), a triage agent that filters false positives and prioritizes findings, and a patch-generation agent that proposes and validates fixes. Agents share a structured state and hand off via machine-checkable artifacts. Research bet: multi-stage prioritization improves precision (lower false positives) and remediation coverage (higher fix rate) jointly rather than as a tradeoff.

LLMsCodeQLStatic AnalysisMulti-Agent SystemsPython

In progress Personal · planned

Preference-Tuned Small-Model Safety (DPO + LoRA)

Planned: DPO fine-tune of a small open-weight instruct model on a curated prompt-injection-resistance dataset.

What I built Close

Personal project, planned. Curated ~800 preference pairs across 5 attack categories (jailbreak / indirect prompt injection / data exfiltration / tool misuse / ambient-authority abuse), sourced from JailbreakBench, AdvBench, PromptInject-style indirect-injection cases, and custom security-domain triples authored from Golden Repository CVE descriptions. DPO fine-tune of Qwen2.5-1.5B-Instruct on a single Compute Canada H100 using HuggingFace TRL’s DPOTrainer with LoRA rank-16 adapters on a 4-bit NF4-quantized base. Eval harness measures refusal rate on held-out adversarial split + helpfulness retention on Alpaca-Eval, MMLU sample, and TruthfulQA.

HuggingFace TRLDPOLoRAPEFTbitsandbytesCompute CanadavLLM