Skip to content
Pablo Adell

Work

I build multi-agent systems at Jupiter. Before that, Solana programs and the observability tooling around them. Here is where I've worked, and a few things I made and why I made them the way I did.

Where I've worked

  • JupiterAI Engineer2026

    Multi-agent LLM systems and evaluation harnesses at Jupiter Exchange.

  • Sanctum LabsSenior Software Engineer2025

    No-std Rust programs for liquid staking tokens (LSTs).

  • IronforgeSenior Software Engineer2024

    Solana observability and incident tooling with ClickHouse, Tinybird and Cloudflare Workers.

  • KomonSenior Software Engineer2022

    Foundational team. Rebuilt creator and community monetisation on Solana.

  • Affirm / ReturnlySoftware Engineer2020–2021

    Rails and React.

Things I've made

Solana · simulateTransaction → response

The simulation that said no

Zero compute units and an empty log: none of the instructions ran. The RPC call itself succeeded, so the failure only shows up in value.err. Anything that asks a user to sign should check that field first, not the response status.

"value": {
  "err": "BlockhashNotFound",
  "logs": [],
  "unitsConsumed": 0
}

The note behind it

Data · pipes/daily_avg.pipe

Averages you can't add

When days have different volumes, the average of daily averages is not the weekly average. Storing the aggregate state instead of the finished number lets one materialised view answer any window correctly.

-- per day: keep the state, not the number
SELECT toStartOfDay(ts) AS day, city,
       avgState(latency_ms) AS latency
FROM events
GROUP BY day, city

-- any window: merge the states
SELECT toStartOfWeek(day) AS week, city,
       avgMerge(latency) AS avg_latency
FROM daily_latency
GROUP BY week, city

The note behind it

AI · evals/gate.ts (sketch)

A prompt change is a deploy

A sketch of the rule, not production code: a prompt or model change ships only if it scores at least as well as the current one on the same eval cases. Agents usually fail without throwing, so the comparison is the test.

const baseline = await runSuite(suite, { prompt: current });
const candidate = await runSuite(suite, { prompt: next });

if (candidate.passRate < baseline.passRate) {
  throw new Error("regression: " + diff(baseline, candidate));
}

On the side

Cursor MCP Deeplink Generator (opens in new tab). Name an MCP server, add its commands, and get a deep link that imports it into Cursor, plus a URL to share. Next.js and TypeScript.

Need something like this built? I take on one consulting project at a time, or email me@pavs.dev.