Regulated software teams often need to turn large, ambiguous policy documents into executable business logic under severe deadlines. Tax, healthcare, insurance, lending, and government systems all share the same shape: the source material is prose, the implementation target is a specialized internal language or rules engine, and the acceptable error rate is near zero. A general coding agent can accelerate analysis, but it cannot be the trust boundary.
The pattern in Intuit’s tax-code workflow is to split the work into three layers. General-purpose LLMs summarize and reconcile long documents. Domain-aware generation tooling translates only the relevant provisions into a proprietary domain-specific language. Deterministic validation, custom test tooling, and human subject-matter review decide whether the generated artifact is shippable.
This is not ordinary prompt-to-code automation. The model is used where probabilistic language understanding is valuable, then boxed into narrow generation tasks whose outputs can be checked by deterministic systems. The training objective for engineers is to design the scaffold around the model: anchors, dependency maps, DSL constraints, test harnesses, failure localization, and approval gates.
Regulatory source material frequently arrives in multiple forms: draft bills, amended versions, agency guidance, forms, examples, and legacy references. Before code generation starts, the system must identify stable anchors such as statute sections, policy identifiers, line items, form fields, or rule IDs. The model can summarize each source, but the scaffold should preserve citations and anchor mappings so later stages know exactly which provision drove each generated rule.
A DSL narrows the generation target. Instead of asking a model to modify arbitrary application code, the workflow asks for constrained rule artifacts: eligibility predicates, calculation formulas, field mappings, validation clauses, or state transitions. This reduces the output space and gives deterministic tools something concrete to parse, lint, execute, and diff.
LLM-based evaluation can help triage generated output, but it is not the final authority in regulated workflows. The final gate should be deterministic where possible: parser checks, type checks, golden test cases, property tests, simulation runs, trace comparisons, and expert review. The important design rule is that generation is probabilistic, while release approval must be evidence-driven and reproducible.
Use LLMs to compress reading time and draft candidate rules, but place the release decision in a domain-specific harness that can explain failures, reproduce results, and map every generated artifact back to source evidence.
The first stage converts unstructured policy text into a structured change set. The model reads the source documents, identifies provisions relevant to the product, maps each provision to a stable anchor, and reconciles differences between versions. This stage should produce artifacts that humans can inspect before generation begins.
type ProvisionChange struct {
AnchorID string `json:"anchor_id"`
SourceURL string `json:"source_url"`
AppliesTo []string `json:"applies_to"`
EffectiveDate string `json:"effective_date"`
PriorRuleRefs []string `json:"prior_rule_refs"`
ChangeSummary string `json:"change_summary"`
EvidenceSpans []Span `json:"evidence_spans"`
}
func reconcileVersions(houseDoc, senateDoc Document) []ProvisionChange {
house := extractAnchoredChanges(houseDoc)
senate := extractAnchoredChanges(senateDoc)
return mergeByAnchor(house, senate)
}
The key engineering choice is to carry the source anchor forward. If the generation later fails a test, reviewers need to trace the failing rule back to the exact policy span rather than reverse-engineering why the model wrote it.
The generation prompt should not ask for arbitrary code. It should provide the DSL grammar, allowed symbols, existing rule references, examples of valid rules, and explicit output schema. A constrained target makes automatic validation meaningful.
# Generated rule artifact
rule child_credit.phaseout_2026 {
source_anchor = "SEC-110201"
effective_on = "2026-01-01"
when taxpayer.filing_status in ["single", "head_of_household"] {
threshold = money(200000)
}
when taxpayer.filing_status == "married_joint" {
threshold = money(400000)
}
reduce credit_amount by phaseout(taxpayer.modified_agi, threshold)
}
The artifact is intentionally boring. It has no network calls, no hidden side effects, and no access to application internals beyond approved symbols. That restriction is what lets downstream validation catch malformed or unsupported logic before it enters production code.
A strong harness reports more than pass or fail. It identifies the failing rule segment, the source anchor, the fixture that failed, and the expected versus actual result. The repair loop can then ask the model to revise only the narrow rule segment while preserving test intent and source mappings.
Tax preparation, benefit eligibility, and subsidy systems often encode statutory text as calculation rules. LLMs can accelerate provision extraction and dependency mapping, while deterministic fixtures check known household profiles, income ranges, phaseouts, dates, and edge cases. Human reviewers remain essential because the law may contain ambiguity that no model should silently resolve.
Clinical prior authorization, claims adjudication, and insurance coverage rules are well suited to a constrained DSL boundary. The source material is long and domain-heavy, but the runtime artifact can be a limited set of predicates, exclusions, codes, and calculation rules. The harness should include synthetic cases, historical cases, and denial/approval explanations.
Compiled AI systems use LLMs during a build phase to produce executable workflow artifacts that later run without model calls. This is valuable when runtime inference would be expensive, non-deterministic, or exposed to prompt injection. The same pattern applies to document processing, routing policies, compliance checklists, and back-office decision workflows.
Keep each phase explicit. Analysis creates structured changes. Generation creates candidate DSL artifacts. Validation produces signed evidence bundles. Mixing these phases in one chat transcript makes audit difficult and lets unverified assumptions slip into code.
type PipelineState string
const (
StateAnalyzed PipelineState = "analyzed"
StateGenerated PipelineState = "generated"
StateValidated PipelineState = "validated"
StateApproved PipelineState = "approved"
)
type RuleBundle struct {
ID string
State PipelineState
Changes []ProvisionChange
GeneratedRules []string
TestReport *ValidationReport
ExpertApproval *Approval
}
Generic pass/fail tests are too weak for regulated code generation. The harness should understand domain objects, fixture provenance, explanation fields, tolerances, and invariant classes. For a calculation engine, failures should identify the specific formula branch and input profile; for a claims engine, they should identify the predicate that changed the decision.
type RuleFailure struct {
RuleID string
AnchorID string
FixtureID string
Segment string
Expected Decimal
Actual Decimal
Explanation string
}
func ValidateBundle(bundle RuleBundle, fixtures []Fixture) ValidationReport {
report := ValidationReport{}
for _, rule := range bundle.GeneratedRules {
parsed := parseAndTypecheck(rule)
report.AddStaticChecks(parsed.Checks)
report.AddScenarioResults(runFixtures(parsed.Program, fixtures))
}
return report
}
Subject-matter experts should review source mappings, edge cases, and validation failures inside the same workflow, not in a disconnected document. Their approval should reference bundle IDs, source anchors, fixture sets, and validation report versions so the final artifact is auditable.