Blog
The 5% problem
By Ted Ghose, Co-founder and CTO · Published · 11 minutes read
The short answer
Use deterministic rules for the large majority of warehouse logic, about 95% of objects at Novuz, because rules give the same output every run with no model cost. Use a language model only for the small remainder rules cannot settle, such as dynamic SQL or embedded C#, on a model you choose, with an engineer approving every proposal and the result reconciled like everything else.
There are two loud positions on AI in warehouse migration. One says a language model can now rewrite your whole estate. The other says no model should ever touch production logic. Both are wrong, and the interesting engineering is in the narrow space between them.
Can a language model convert stored procedures?
Yes, often impressively. Paste a T-SQL procedure into a capable model and ask for Spark SQL, and you will usually get something plausible, idiomatic and close.
The problem is the word "usually", and the word "close". Ask again tomorrow and you may get a different, equally plausible answer. Run it against production data and it may differ from the original in the handling of a NULL, a tie in a sort, or a rounding step, none of which shows up in a code review. Across four thousand objects, "usually close" is not a migration strategy. It is a testing backlog.
Why rules beat models for most warehouse logic
At Novuz, about 95% of objects convert by fixed, versioned rules with no model calls. That figure varies by estate, which is why the assessment measures it on your code rather than quoting ours. Using a model for this part buys nothing: it is slower, it costs tokens for work a rule does for free, and it introduces variance where there was none.
| Property | Deterministic rules | Language model |
|---|---|---|
| Same input, same output | Always | Can differ between runs |
| Cost per object | None beyond compute | Tokens on every attempt and rerun |
| Explains each change | Yes, by rule id | Can explain, cannot prove |
| Diffable between runs | Yes | Changes appear that nobody asked for |
| Handles unusual intent | No: flags it | Often well |
What a rule-based rewrite looks like
Notice the details a rule has to get right and a reviewer can check: DATEDIFF's argument order flips between dialects; GETDATE() returns a timestamp where current_date() returns a date, which matters at midnight; rounding of halves must match. A rule encodes those decisions once and applies them identically everywhere. Then reconciliation confirms it.
-- Source: T-SQL, cursor over open invoices
DECLARE c CURSOR FOR
SELECT invoice_id, amount, due_date FROM dbo.invoices WHERE status = 'OPEN';
OPEN c;
FETCH NEXT FROM c INTO @id, @amt, @due;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE dbo.invoices
SET late_fee = CASE WHEN DATEDIFF(day, @due, GETDATE()) > 30
THEN ROUND(@amt * 0.015, 2) ELSE 0 END
WHERE invoice_id = @id;
FETCH NEXT FROM c INTO @id, @amt, @due;
END
CLOSE c; DEALLOCATE c;
-- Target: Spark SQL on Delta Lake, set-based
MERGE INTO invoices AS t
USING (
SELECT invoice_id,
CASE WHEN datediff(current_date(), due_date) > 30
THEN round(amount * 0.015, 2) ELSE 0 END AS late_fee
FROM invoices
WHERE status = 'OPEN'
) AS s
ON t.invoice_id = s.invoice_id
WHEN MATCHED THEN UPDATE SET t.late_fee = s.late_fee;Where rules run out
Here a language model is genuinely useful. It can read the surrounding code, infer intent, propose a notebook equivalent of a Script Task or a parameterized rewrite of dynamic SQL, and explain its reasoning.
Useful is not the same as trusted.
- Dynamic SQL assembled at run time from table contents, so the real logic does not exist until it executes.
- A C# or VB.NET Script Task inside an SSIS package that calls an external service or parses a file format.
- A cursor whose output depends on an undocumented processing order the business relies on.
- A vendor-specific function with no equivalent on the target.
How to use a model in a migration without trusting it
Treat it as a capable junior engineer who drafts and never merges.
- It only sees what rules could not settle. The model is asked to propose a fix for one object, with the rule context and the reason the rule did not apply, not to convert the estate.
- It runs on a model you choose. A hosted model such as Claude or Gemini under your own agreement, or a local model through Ollama with no outbound connection. Configured per estate and written into the contract.
- It is cheap because it is narrow. Each resolution takes about 700 to 1,000 tokens, so cost is bounded by the size of the remainder, not the estate.
- A person approves every proposal. Your engineer approves, edits or rejects it. Nothing deploys unapproved. Proposal, approver and timestamp are recorded per object.
- The result is still reconciled. An approved proposal faces the same schema, row-count, aggregate, sample and business checks as everything else. Sounding confident earns no exemption.
Won't better models make the deterministic layer unnecessary?
The opposite. A better model writes more convincing code, which makes unverified code more dangerous, because reviewers trust it more. The value of a deterministic core with a narrow, supervised and reconciled edge is that it stays auditable however good the model at the edge becomes.
We call the edge Resolve. We do not call the engine agentic, because it is not: it is rules. The model is a tool your engineer uses, on your terms.
Key terms
- Deterministic conversion
- translation of source code by fixed, versioned rules, producing identical output for identical input.
- Resolver
- the stage that proposes conversions for objects rules cannot settle, using an approved model, with an engineer approving each proposal.
- Set-based rewrite
- replacing row-by-row procedural logic, such as a cursor, with an equivalent operation over a whole set of rows.
- Edge case (in conversion)
- a construct whose correct translation depends on intent the code does not state.
FAQ
Frequently asked questions
Sources
- Novuz Methodology: the resolver, counting rules and approval log (novuz.com/methodology)
About the author
Ted Ghose is co-founder and CTO of Novuz Inc., the deterministic data warehouse modernization company based in Danville, California. He built the Novuz conversion engine and was previously a Cisco principal engineer.
Next step
The Novuz estate assessment tells you, for your estate, how many objects convert by rule, how many go to the resolver and which constructs need a person, in three business days, for $3,000, credited against what follows.
Last reviewed: