Lance Liang

AI could write the rule. Could anyone tell what it would do?

Designing how a clinical study team judges what an AI-generated rule will actually do.

Oracle Clinical One · Product design and prototyping · With product and engineering · 2026

Tap any image to open it at full size.


Engineering brought us a demo, and it was a good one. A real model, wired to the clinical study: describe the rule you need in plain language, and working rule code comes back. The pitch was hard to argue with — our users don't know how to code, so now they don't have to.

My first thought was: don't have to do what, exactly?

The code still lands on someone's screen, and someone still has to accept it. Are we expecting a person who has never written a line of JavaScript to read that and say yes?

A rule specification in study language beside the code generated from it, with the same four weights and threshold highlighted on both sides
A rule specification the study team already approved, and the code generated from it. The weights and the threshold are the same on both sides. The person who signed off on the left is the person now being asked to accept the right. Illustration, redrawn from my prototype for legibility; not a product screenshot.

The people doing this work are Study Designers. They rarely invent a rule at the keyboard — they take a specification that has already been written and reviewed, and make it run in the product.

When a rule got complex, the logic had to be written as code, usually by someone else. That dependency is why generating the code looked so valuable. It is also why generating it created a new problem.

Code that runs is not code you can trust. It still has to read the right answers, change the right form, and behave when an answer is missing. Reading the code to check is a poor option for someone who needed help writing it.

So the question I designed against was never "can AI write this rule." It was: how does the person responsible for the rule find out what it does?

What I designed · Checkpoint 1

Show what the AI understood, in words the team already uses

The assistant's reading of the specification, broken into intent, trigger, checks and actions
Before generating anything, the assistant restates the specification as behavior — when it runs, what it checks, what it changes — and each section links back to the sentence in the source document it came from. Design prototype.

The specification is the one document everyone on the study team can already read. So the assistant's first output is not code. It is the same rule, written back as behavior: when it runs, what it checks, what it changes.

If it misread the threshold, or attached the rule to the wrong event, you find that here — in a sentence you can argue with. You cannot argue with a line of JavaScript you did not write.

This is also the cheapest place to be wrong. A misunderstanding caught here costs a sentence. Caught after the rule is live, it costs a study.

What I designed · Checkpoint 2

Seven matches were right. The eighth stopped the work.

Describing a rule correctly is not the same as pointing it at the right data.

Eight terms from the specification matched to items in the study, with one flagged for review
Every term in the specification, matched to the visit, form, question or answer choice it will actually use. Seven matched cleanly. The draft cannot be created until someone settles the eighth. Design prototype.
The flagged row expanded, showing the mismatch between the source wording and the study's coded dyspnea scale
The specification says "Moderate or Severe". This study grades that question as "Grade 2 — Moderate dyspnea" and "Grade 3 — Severe dyspnea". The assistant shows what it picked, says why it is unsure, and lets a person change it in place. Design prototype.

"Moderate or Severe" is a phrase in a document. In this study it has to land on two specific answer choices, on one question, on one form. The assistant found a match that was probably right.

Probably is not something you build a study on. And it is not a doubt the model can settle by re-reading the sentence — only someone who knows this study can.

So I made the unresolved match stop the work. The draft cannot be created until a person confirms it.

That cost falls on the wrong person. It blocks someone who came here to move faster, and it trusts the assistant to flag the right matches: a false flag wastes their time, a missed one passes in silence.

I took the trade because the two failures are not equal. A blocked draft is visible and annoying. A wrong match is invisible — the rule runs, the screens look right, and the study collects the wrong thing for a year.

What I designed · Checkpoint 3

Understanding a rule is not the same as watching it run

Checking what the AI understood still tells you nothing about behavior. To see behavior you have to run the rule, so I designed two ways to run it: one the system prepares for you, one you drive yourself.

Running it used to be a project of its own. The request we kept hearing was small — let me open the visit I care about and test there. The old testing mode made you build a simulated participant and work through the earlier steps first.

Then the real work started. You had to invent the cases yourself: the obvious high-risk answer, but also the blank input, the score exactly at the threshold, the follow-up questions left unanswered. And remember what each one did.

Let the system propose the checks — and say what each one proves

Six proposed test scenarios, with the What this proves column highlighted
Six proposed checks: a blank input, a case below the threshold, the threshold exactly, a clearly high case, and the two completion cases. The middle column states what each one is meant to prove. Design prototype.

The middle column is the part I care about. A generated set of test cases is only as trustworthy as your ability to see what it left out, and inputs and expected values do not show you that. Stating what each check is for does.

It also keeps the assistant honest about its own authority. Every expected behavior in that table is the assistant's claim, not a verdict. It comes from the same reading of the specification that might have been wrong two sections ago.

One scenario after running: the simulated values, the expected behavior, and the actual result beneath it
One check, after running. The values and the expectation were written down before anything executed, so the result underneath means something — and a mismatch would show up as a difference between two sentences, not as a red badge. Design prototype.

Let people change an answer and watch

Prepared checks cannot cover the doubt someone has about their own study. The second route drops them into the real study forms, as a site user sees them, and lets them try it.

The simulated visit with a side panel listing the questions the rule reads
A simulated visit, opened straight at the visit and role you asked for. The panel points at the four questions this rule reads, so nobody has to hunt through the study to find them. Design prototype.
Detail of the form list and the rule actions panel, before and after saving high-risk answers
The same visit before and after saving high-risk answers. The Respiratory Follow-up form appears in the form list, and the rule's three actions move from Not applied to Applied. Design prototype.

Two routes is more to learn than one, and I did consider shipping only the prepared checks. I kept both because each is weak exactly where the other is strong.

The prepared set is repeatable but can never prove it is complete. The simulation can try anything but proves nothing twice and leaves no record. Someone deciding whether to trust a rule needs both.

The constraint

Then the release got smaller than the design

The direction had support. The first release did not have room for it.

Engineering capacity went to generation. The testing workspace did not make it in.

There was a harder limit underneath that. The assistant's first release could create only a narrow set of rule actions — one action per rule, and not the ones that show a form or make a question required.

That rules out the example running through this case. Show a follow-up form, make two questions required: precisely the kind of rule the first release could not yet create. Widening the range was treated as a separate feature.

So the question changed under me. Not "what is the best way to check a rule," but "with no new testing surface at all, where can a person still see and question what the assistant is doing?"

What shipped

Keeping the parts a non-programmer could still read

A cleaner idea came up in review: put everything in code. Data references, condition and actions together in one block the assistant writes end to end. It demos beautifully, and it is one surface instead of four.

Generated rule code containing variables, condition, notification recipients and message text in one block
The existing editor filled in, with action type, subject line, recipients and message as separate fields
The same specification, generated two ways. Left: one code block — including who the notification goes to and what it says. Right: the product's existing fields, with only the condition in code, and one field the assistant deliberately leaves for you. Left: the code-first direction, set aside. Right: the agreed first-release direction, approved and in development. Both screens use a notification rule, because the first release could not create the form-display rule used earlier in this case.
Detail of the generated code showing the notification recipients and message body inside the rule
Detail of the left-hand screen. Who gets notified, and what the notification says, are lines of code like any other. Set aside.

I argued against it, and the argument is in those two screens.

Selecting data, choosing an action type, naming recipients, writing the message — a Study Designer could already do and check all of that without reading code. Those are the reviewable parts of a rule.

Moving them into the code block does not make the rule simpler. It makes the only readable parts unreadable, for the exact people the assistant exists to help.

The compactness is real, and it is worth something — to people who were never blocked in the first place.

Those controls are the product's, not mine. What I contributed was the case for keeping them once an assistant started filling them in. The team settled there: the editor stays, the assistant becomes an optional way into it, and the condition is still code.

The side panel restating the rule and asking for one match to be confirmed
The side panel listing the decisions the draft will be generated from
The checkpoints that survived, folded into the side panel: the restated behavior, the one match that needs a person, and the decisions the draft will be built from — with Generate draft and Revise requirement as the only two ways forward. First-release direction, approved and in development; not a shipped screen.

The full testing workspace did not ship. The checkpoints did — smaller, folded into a panel beside the editor instead of a workspace of their own.

Reviewing a rule's configuration is not the same as verifying its behavior, and I would not claim otherwise. But it kept the moments where a person is asked to agree with something specific, instead of being asked to approve a result.

The method

When the assistant should explain itself, and when it should stay quiet

Six checkpoints the assistant passes before generating a draft, and the conditions under which it adds an explanation
The protocol I wrote for the first release: six checkpoints, each defined by what the user must be able to verify and what the assistant should not narrate. Concept diagram, drawn for this case study from an internal design document.

Designing the screens was not enough. The same screen helps or wastes your time depending on when the assistant decides to speak, so I wrote that rule down separately.

Explanation belongs inside the flow, and it exists to help someone check or correct the rule — not to expose the model's reasoning.

That gives every checkpoint a test to pass. Say more only when the assistant makes an inference that could change the result, settles an ambiguity, recommends a match, transforms data, or finds something missing. Otherwise say less.

Listing every capability it checked feels like transparency and works like noise. It buries the one sentence that actually needed a human decision.

The document also records where my own design fails that test. At the confirmation step the assistant says it will "calculate the score from four weighted inputs" — which reads fine and cannot be checked. It is written down as an open question, not a solved one.

Closing

What I take from it

I designed the experience for understanding and testing an AI-generated rule, then worked with product and engineering on what could fit in a release much smaller than the design.

The contribution I would defend is not a screen. It is that at every stage, including the smallest one, there was a specific thing a person could disagree with — a sentence, a match, a decision, a result — instead of a finished artifact to approve.

The Epic had entered development when I last worked on it. I have no adoption or outcome data to report.

The question it left me with is still open: once AI produces the work, what does the person accountable for it need in order to know what they are accepting?

What these screens are

The rule, study and data throughout are fictional examples. The existing rule editor's controls — variables, expression, action fields — are the product's, not designs I created for this project. Scope and technical decisions were owned by product and engineering.

← Back to work