An engineer and an AI build your modern data stack together, side by side on the same branch, from probing a source to a running pipeline. Ordinary code, in your repo and your cloud account, that any real engineer can maintain. The project that usually runs for a year, without the year.
An engineer and an AI build it together, start to finish.
From the first probe of a source to a pipeline running in production, an engineer and an AI work as peers on the same branch. The AI brings speed. The engineer writes code in their own editor, makes the calls and signs off. That engineer can be ours, your in-house team, or both. You decide with them at the points that matter: the plan, the review and the ship.
01
Probe
Point it at an API or your warehouse tables. Read-only, safe by construction.
AI
02
Profile
Structure, types and key candidates worked out automatically. No values kept.
AI
03
Plan
A brief and a plan: what is new, what you already have, open questions.
✋ you approve
04
Build
Integration, models, tests and docs, written on one branch by the AI and the engineer, running locally first.
AI + engineer
05
Check
Automated gates plus independent reviewers, each covering only their own area.
AI
06
Review
Independent reviewers and the engineer read every line. The engineer decides.
✋ you decide
07
Ship
Merged to your main under your rules, applied to your cloud only after review.
✋ you approve
08
Run
Scheduled, monitored and alerting. Run order and freshness gates built in.
AI + alerts
Two parties, working as peers.
Engineer
Codes, decides, signs off
Pulls the same branch into their own editor and writes code alongside the AI
Ours, your in-house team, or a contractor you bring in later
Owns the architecture and every trade-off
Reads every line that ships and is accountable for it
AI pair
Builds at machine speed
Scaffolding, models, tests, migrations
Documentation written as the code is
Picks up the engineer's commits and builds on them
Every change lands as a pull request in your repo, whether it is a pipeline, a report or a small app. The AI drafts at speed. An engineer, a real person, is no spectator: they pull the same branch, code in their own editor alongside the AI, catch what it got wrong and decide what merges. You can see who did what, line by line.
PR #12 · Add the orders source4 lines by AI · 2 by engineer
feature/orders-source
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A-@asset(group="ingest")
E+@asset(group="ingest", retry=RETRY)
A+def orders(api: OrdersApi, wh: Warehouse):
A- last = wh.max("raw.orders", "created_at")
E+ last = wh.max("raw.orders", "updated_at") - LOOKBACK
A+ rows = api.fetch("/v2/orders", since=last)
A+ wh.merge("raw.orders", rows, key="order_id")
A+ return Result(rows=len(rows))
E
Engineer pushed a fix from their editor
created_at never sees edits to old orders, so the watermark moves to updated_at with a short lookback. And a flaky API should retry, not page anyone.
A
AI picked it up and built on it
Watermark moved to updated_at with a 2 day lookback, retries added. Tests re-run, all green.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #15 · Model customer lifetime value5 lines by AI · 2 by engineer
feature/customer-ltv
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+select
A+ c.customer_id,
A- sum(o.amount) as ltv
E+ sum(o.amount - coalesce(r.amount, 0)) as ltv
A+from stg_customers c
A+join stg_orders o using (customer_id)
E+left join stg_refunds r using (order_id)
A+group by 1
E
Engineer pushed a fix from their editor
Lifetime value before refunds flatters the numbers. Net them out so finance and product see the same figure.
A
AI picked it up and built on it
Refunds netted out of ltv, with a test that it is never negative. Docs regenerated.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #19 · Run order for the daily refresh6 lines by AI · 2 by engineer
feature/daily-run-order
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+pipeline: daily_refresh
A+steps:
A+ a: ingest orders
A+ b: build customer_ltv
A+ after: a
A+ c: refresh revenue_overview
A- after: a
E+ after: b
E+ gate: orders fresh within 26h
Run ordergenerated from the file above · sample pipeline
E
Engineer pushed a fix from their editor
The report would have refreshed from a half-built model. The order is a, then b, then c, and c waits for a fresh load, so nobody reads yesterday as today.
A
AI picked it up and built on it
Dependency fixed and the freshness gate added. The run order graph rebuilds from this file.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #23 · Analyst read access2 lines by AI · 2 by engineer
feature/analyst-access
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+grant:
A+ role: analyst
A- privileges: [all]
E+ privileges: [select]
E+ schema: marts
E
Engineer pushed a fix from their editor
ALL on an analyst role is how audits go badly. Read-only, marts only. The plan is reviewed by a person before anything is applied.
A
AI picked it up and built on it
Narrowed to SELECT on MARTS. Plan attached for your review before anything applies.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #27 · Revenue overview report6 lines by AI · 2 by engineer
feature/revenue-overview
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+report: revenue_overview
A+measure:
A- revenue: sum(order_amount)
E+ net_revenue: sum(order_amount - refund_amount)
E+ description: Revenue after refunds, by order month
A+visual:
A+ type: bar
A+ x: order_month
A+ y: net_revenue
Net revenue by monthgenerated from the file above · sample data
E
Engineer pushed a fix from their editor
Revenue before refunds is not the number finance uses. The definition lives here, in code, so the report, the data dictionary and any question asked of the data all agree.
A
AI picked it up and built on it
Measure and description updated. The report rebuilds from this file.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #31 · Let people ask about revenue3 lines by AI · 2 by engineer
feature/ask-revenue
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+ask:
A+ measure: net_revenue
A+ slice_by: [region, order_month]
A- run_as: shared_account
E+ run_as: asking_user
E+ show: [definition, query]
Asksample conversation · governed measures only
Net revenue last quarter, by region?
North led last quarter at 1.42M net revenue, ahead of West (1.17M) and South (0.98M).
North1.42M
West1.17M
South0.98M
net_revenuelast quarterview query
Ask about revenue…↵
E
Engineer pushed a fix from their editor
A shared account would let everyone see every region. Run it as the person asking so their data permissions apply, and show the definition and query with every answer.
A
AI picked it up and built on it
Switched to the asking user and added the definition and query to every answer. Permission tests pass.
tests passing
docs generated
approved by a human engineer
merged to your main
PR #34 · Discount planner app6 lines by AI · 2 by engineer
feature/discount-planner
Adrafts
Epulls it, codes locally, pushes
Abuilds on it
merged by a person
A+@app(title="Discount planner")
A+def planner(user):
A+ base = read("net_revenue", ["region", "net_revenue"])
A hardcoded lift quietly goes stale. Read it from the governed elasticity table, and record who submitted each scenario.
A
AI picked it up and built on it
Lift now comes from the elasticity model and submissions are attributed. The app shows in lineage as a reader of both.
tests passing
docs generated
approved by a human engineer
merged to your main
+ And everything around the code
The pipelines are the visible part.
Around them sits the tooling that keeps your platform documented, explainable, reviewed and safe to change, and it travels with the repo.
04.1
Core feature
Local development, built in
The whole platform runs on a laptop. Identity, warehouse, reports, source APIs and the AI provider are emulated with small local servers, so any engineer can clone the repo, run the stack and test it end to end with no accounts and no spend. A local model can stand in for the AI. Infrastructure changes are planned and reviewed by a person before anything touches your cloud.
$ stack up --local
identity emulated real signed tokens
warehouse local database
reports emulated
AI scripted or a local model
source API demo server
$ test --end-to-end
every seam exercised, no accounts, no spendcloud: planned, reviewed, then applied
04.2
Documentation that writes itself and stays true
Every column carries its description and where it came from. Write it once upstream and it flows downstream, wherever the lineage is exact. A person's wording always beats a machine's, and nothing is overwritten silently. Descriptions sync into your reports as a pull request.
Unique customer id, shared across all sales channels.
04.3
Full lineage and blast radius
Column-level lineage from source to report, in one graph. Before anything changes you can see exactly what it touches: which models, which reports, which people to warn. Tickets, plans and deployments join the same graph, so the reason for a change is one click from the change.
Different work gets different treatment, declared in one reviewed file. A documentation fix needs no model time. A new mart runs assess, plan, implement. An access request goes straight to a person. Routing is deterministic, every change passes the same automated gates, and the line stops for a human where a human belongs.
Point it at an API or at tables already in your warehouse. It probes and profiles the source automatically, read-only, with structure and types sampled and values never kept. It tells you what is new, what you already ingest and what is already modelled. Then the engineer and the AI build the integration together, pipeline, tests, documentation and run order, while you approve the plan and review the result.
$ probe /v2/orders read-only
14 fields sampled, types inferred
key candidate: order_id (unique in sample)
no values kept
brief
orders new
customers already modelled read by 2 reports
refunds already a sourceplan approved by engineerbuild AI drafts ingest · tests · docs · run orderreview pull request waiting for a person
04.6
Bring your own AI
Your provider, your account, your key. Route different jobs to different models, or run a local one. Every request is capped and counted against a budget, usage is logged without ever storing a prompt or a reply, and nothing is tied to a single vendor, so switching is a config change.
ai
provider your own account, or a local model
key a reference, never in code
route planning → strong model
summaries → small model
budget capped per request and per run
log usage counted, prompts never kept
04.7
An independent review agent, with separated concerns
Each pull request is reviewed by narrow reviewers that each own certain files, carry only their own rules, and are told what is out of scope. One checks data models, one checks infrastructure and security, one checks reports. Merging is decided by scanners, code owners and checks, never by a model's comment.
Security reviewerinfra/**least privilege, no secrets
Report reviewerbi/**measures documented, no credentials
merge is decided by scanners · code owners · checks
04.8
Guardrails you control
Who can do what, how much the AI can spend, what can leave the building, and which optional capabilities are on. Roles come from your identity provider, spend has limits and a kill switch, administrative changes are audited, outbound calls are restricted, and the AI works inside a boundary you can see.