← All articles

Founding engineer: an AI research platform, empty repo to ten engineers

Founding Engineer / Technical Lead - Data & AI Platform Architecture

Client: Sterling Labs - an AI research platform for public-market investors
Engagement: contract, 16 months · first commit through handoff
Stack: Python · TypeScript · AWS CDK · Kafka · Airflow · document, relational and columnar stores · LLM agent tooling and evals

Sole engineer at the first commit. I set the architecture, the data contract and the review standard, then held that bar as the team grew to around ten engineers. Features I built end to end are in the product today, and the tool layer I authored became the platform's primary AI tool surface.

I worked with Sterling Labs as an independent contractor. This case study is my own account of the work and is not endorsed by Sterling Labs.


Where it started, where it ended

At the startAt handoff
Data sourcesnone - empty repository2 data streaming lanes I owned from API to contract; many scheduled ingestions: HTTP APIs, SFTP sources
Adding a data sourcea bespoke script per sourcea pattern a new hire can follow
Core architecturedid not existinfrastructure as a code: CDK app and data ingestion patterns from month one - unchanged at handoff
Engineering team1 (me)over 10 engineers
Data architecturenoneevent-driven ingestion contract feeding three production stores - document, relational, columnar; multiple data pipelines and ingestion jobs
Correctness of AI-generated artefactsdid not existdeterministic validations, re-generation with feedback, source grounding (e.g. fundamental data from company filings)

Scope: first production versions of the platform's AI research features, three of them customer-facing, plus the data and MCP tools layer the platform's AI agents run on.

The client retained me for four things: more data sources, new features, faster data onboarding, and reviewing team's work.


Three systems I owned end to end

1. Data architecture - getting the data in, and keeping it trustworthy

Every feature sits on third-party financial data. Wrong or misattributed data is worse than no data, so the ingestion contract has to ensure correctness. Late-arriving data is acceptable, but deteriorates UX - user wants to have access to all the company data as soon as it is publicly released.

What I built. The ingestion lane for the platform's fundamentals data, owned from the vendor API to the downstream contract: polling (streaming was not available at that time), company attribution, restatement handling, and a guarantee that AI workflows only fire once the data is provably durable and queryable. Event-driven, and the containment boundary is the point: vendor-shaped code stops at the ingestor, and every consumer downstream inherits one definition of ready.

vendor APIpolling ingestorKafka topic document storerelational storecolumnar store AI pipelines readiness gate fires when the data reads back out, not on write ack
Only the relational store gates the pipelines - the document and columnar stores are fed from the same topic, but nothing downstream waits on them. The gate fires on a read-back, not on a write acknowledgement.

That readiness barrier is the design decision I would defend: it fires not when the writes are acknowledged, but when the data reads back out of the store. Acknowledged-but-not-yet-visible is what lets a downstream pipeline generate confident output from a half-loaded company. For this pipeline I also planned a phased zero-downtime store migration and ran its first phases, including a full production backfill alongside live writers, with no data incident.

Proof point - a monitor with no false positives. Fixed-threshold consumer-lag alerting may scream through legitimate backfills, so I built this one on a relative measure: quiet through a backfill, loud on a writer that has genuinely fallen behind. Lag is compared between sibling consumer groups and its rolling average.

2. Auto-generated earnings diagrams - a customer-facing feature

The product renders a company's income statement as a flow diagram with written commentary - high value to buy-side users, and demanding to ship. The output is generated, so correctness has to be enforced by construction rather than caught by review.

On pace. First demo version was ready within 3 days, but making sure all types of companies get their diagram right, including loss periods was a much harder challenge.

How it stays correct. Validators block publication, including a check against the source filing. Failed check was fed back to the agent for regeneration to make sure the same mistake is not made again upon retry. The validators also included node balance (inputs equal outputs) and connectivity checks.

On cost. The commentary agent initially run with many tool calls - getting recent earnings call transcripts, slides, filing documents texts. One run wrote the commentary for a single metric - revenue, R&D spend, tax and so on - against one earnings KPI, so the unit is small and there are a great many of them (500 companies x ~15 income statement metrics x 15 backfilled periods for past 3 years = 112500 agent runs ). I rebuilt it as a single formatting call handed everything it needed upfront: the numeric work moved into pre-computed inputs, the static prompt kept in the provider's cache across a batch. Every LLM call was traced, so we could estimate the new dollar cost: roughly a tenfold drop. The model did not change. The shape of the work did.

3. Per-company KPI series - a customer-facing feature

Analysts want the handful of operating metrics that move this business - subscriber counts, units shipped, same-store sales - not a generic template, and the source taxonomy is far too large to put in front of a model.

What I built. A pipeline that discovers, defines, computes and ranks the financial and operating metrics for each company - charted in the research surface and exposed to the AI agents as a tool.

Hard part. Any change to the company data may change its KPIs ranking, so any new filing means KPIs should be re-discovered. Data vendor sometimes may push updates in chunks, so re-discovery runs should be de-duplicated per company and ensuring the data is staged and not modified in place. Staged KPIs are promoted and visible in production (to any upstream consumers) only after validation checks pass.


How the team used me

  • 245 pull-request reviews for colleagues.
  • A written quality standard for the shared AI tool layer - a cost bar per call, and how each owner should improve, debug and evaluate their own tool. The bar: could a human verify this answer correct from the raw data the tools returned?
  • The evaluation harness the team writes tool tests into. Each case declares what must appear in a correct answer; a judge model sees those criteria and not the agent's tool calls. I wrote the harness and the first suites; the team extended it well beyond what I wrote.
  • Around forty issues scoped, filed and assigned to other engineers, and delivered by them.
  • Onboarding material and work briefs for incoming engineers; four domains handed over with consumer inventories and handover notes.
  • On-call in the final phase, plus the operator dashboards and monitoring behind it.

What I review for. I verify a claim by re-deriving it against production, never by reading the diff. Now that first-pass scrutiny is largely automated, the human's job moves to what a model will not converge on unprompted: whether a change does what was actually asked rather than what the prompt drifted into and whether the design is sound - also in context of how a feature is likely to evolve.


The leverage story

The first data integrations were one bespoke Python script per source on a timer - including the ones I wrote. I initiated moving that onto Airflow, then built reusable patterns rather than one-off pipelines: consistent orchestration shapes, common conventions for logging, retries and configuration.

  • New data sources were easier and faster to onboard. Later integrations, built by other engineers, follow the shapes I established.
  • Six components I originated are now maintained by other people.
  • Repetition became a throughput argument, not a style preference. Consistent patterns are what junior engineers copy from - and what their AI coding tools copy from.

On how I work. I moved to agent-assisted development early and deliberately. When the first code draft is not yours, quality is decided by the design you aim the agent at and setting correct verifications. I am usually following spec-driven development and using agentic coding patterns such as breaking down larger tasks into smaller, parallel ones, using subagent fan-out with AI code review loop.


Judgment, including where it failed

Identity never stays cheap - I found that out late. I keyed on a vendor's symbol because it was already there and it was unique the day I looked. A symbol like that turned out to be mutable and non-unique, and a key chosen in week one propagated into everything built after it - the two days it cost to change early is not what it costs once everything downstream depends on it. I own that call. The continuous check on entity resolution that would have caught it was an afternoon's work. I now treat entity resolution as week-one work rather than a later hardening pass.

I distrust a green check. Example: task that exits successfully having written nothing, which an orchestrator reads as success. Always ask if all failure modes are observable and have proper alerting set up.

I measure before building, and cancel work that measurement proves unnecessary. A backlog of proposed fixes, adjudicated case by case rather than in aggregate - most did not need the fix proposed for them. Two pipelines descoped after one conversation rather than two weeks of code.

I find the best baseline before I build a model. Asked to evaluate a ML model that looked like a clear win, I added a stronger baseline; the apparent edge was mostly in the choice of comparison. A model that only beats a weak baseline has not been measured.