From Demo to Product Decision: A Lab for Accepted Work Orders
A real ASP.NET and Microsoft.Extensions.AI fixture compares two proposal paths through one validator, preserves every failed revision, and makes explicit review the boundary of accepted work.
Explore the mechanism ↓
Reading tools Listen or translate
Read aloud
Uses an installed voice on your device.
Translate article
Machine translation. Code and evidence notes stay in English.
Original English text.
START WITH THE MECHANISM
Interactive companion and laboratory update: 12 November 2026. The editorial date places the topic on the timeline; this current explanation and its measured evidence retain their actual preparation and execution dates.
THE FULL INVESTIGATION
From Demo to Product Decision: A Lab for Accepted Work Orders
Dates and technology context
This is a retrospective editorial timeline. Topic context: 3 November 2026. First publicly available: 12 November 2026. Current text, visuals and laboratory revisions were prepared on 12 November 2026.
MEAI11.0.0 scripted client,18 channel-cases,20 revisions and four accepted work orders are12Nov2026 fixture evidence. Do not turn them into earlier customer success.
A convincing AI demonstration often ends at the easiest possible boundary: the system has produced something that looks like an answer. A maintenance request becomes a neatly formatted work order. The fields are populated, the language is fluent, and a green response appears in the interface. It is tempting to interpret that moment as evidence that a product has created useful work.
The receiver's problem starts later. Does the order refer to an asset that belongs to this tenant? Was it prepared from the current evidence? Is a missing observation being presented as a fact? Did anyone approve the exact revision now entering the queue? If these questions are answered elsewhere, the demonstration may have moved work rather than removed it.
This article builds an executable boundary around those questions. A structured-form path and a scripted Microsoft.Extensions.AI.IChatClient path submit proposals to the same local ASP.NET service. The service produces explicit validation states, preserves every revision, and requires a separate fixture approval before a work order becomes accepted. An independent golden file specifies expected decisions and the fields a reviewer should see.
The final run passed 155 checks across 18 channel-case executions. It recorded 20 proposal revisions in the comparison cohort and four accepted orders. These are actual functional results from synthetic fixtures. They are not evidence that an AI model is accurate, that users work faster, or that this application is ready to manage real maintenance. The provider is a local script, the reviewer is a controlled fixture, and no external work is dispatched.
The laboratory's purpose is to make a product decision possible without confusing implementation success with product value. It gives us a concrete object to inspect: the path from an initial proposal to an accepted task, including the failures and unanswered questions along the way.
Define the unit of value before implementing generation
The unit of value in this experiment is an accepted work order for one catalog asset and one evidence revision. It is not a generated paragraph, a completed HTTP exchange or a successful deserialization. The distinction determines both the code and the denominator used in the report.
Our synthetic catalog contains two assets. pump-a belongs to tenant-a and has evidence version 7, with an observation that a leak was seen at its inlet seal. pump-b belongs to tenant-b and has a different observation and version. These records are fictional domain fixtures. They are not extracted from a customer's equipment, and their version numbers do not correspond to a real maintenance history.
A proposal contains five fields: tenant identity, asset identity, evidence version, priority and summary. The requester identity is supplied separately by the host. A proposal can refer to a tenant, but it cannot establish the authority of the actor submitting it. That separation is necessary even in a local example because otherwise an attractive JSON document can quietly become its own permission grant.
The fixture defines four consequential states. Clarification means required information is missing. Rejected means the proposal conflicts with a stated constraint, such as tenant ownership or evidence freshness. ReadyForReview means the deterministic checks passed, while Accepted requires a distinct approval of the current revision. A syntactically complete proposal can therefore remain unaccepted indefinitely.
There is no claim that these four states fit every organization. A real process may need scheduling, safety review, escalation, rejection by a recipient or cancellation after acceptance. Adding those states should follow the actual receiver's obligations. The small state model here is useful because each transition has a reason that can be independently checked, rather than because four is an ideal number of workflow states.
The product hypothesis can now be stated narrowly: a drafting interface might help a requester reach an acceptable work order with less total effort. That hypothesis is not tested by the scripted provider. What we can test first is whether the proposed architecture can distinguish acceptable work from plausible output and preserve enough evidence to evaluate the larger hypothesis later.
Use one domain contract behind both interfaces
01 / See the idea
Two interfaces, one acceptance contract
The form and scripted IChatClient receive the same nine fixture cases. They differ at input acquisition, while tenant, evidence and approval checks remain shared.
Interpretation and evidence
- Two adapters use one validator.
- The provider supplies data, not authority.
- Review remains a separate transition.
The two input paths differ only in how they obtain a draft. The form path deserializes the fixture fields into the typed record and serializes that record for submission. The AI path calls an actual IChatClient implementation and submits the response text. Both then cross the same HTTP endpoint, parser, validator and revision ledger.
public sealed record Proposal(
string? TenantId,
string? AssetId,
int? EvidenceVersion,
string? Priority,
string? Summary);
public sealed record Actor(string Id, string TenantId, bool CanReview);
The project pins Microsoft.Extensions.AI 11.0.0 and executes on SDK 10.0.400 with runtime 10.0.15. The NuGet package record identifies the selected dependency. The IChatClient interface documentation describes the integration surface, while the actual compilation and run establish that the methods used here work with the pinned package. A moving documentation selector is not the version evidence for the executable.
The scripted client implements GetResponseAsync, returns one queued draft per call, and checks cancellation before consuming a draft. It does not call a model. It does not search a catalog or infer missing facts. Its lack of intelligence is an advantage for this particular experiment: the same invalid proposal can be replayed through the actual interface without uncertainty about what a remote provider might say next.
There is also a limitation worth stating early. The form path is a programmatic representation of structured input, not a browser form tested with people. The AI path is a scripted adapter, not a measurement of language understanding. Their comparison establishes consistency at the shared boundary. It cannot establish which interface people prefer, which takes less time, or which produces fewer mistakes in realistic use.
A shared validator prevents a common product failure: applying strict rules to the conventional interface while allowing the conversational interface to bypass them because its output looks natural. If the asset belongs to another tenant, the proposal is rejected regardless of whether it came from a drop-down, a generated JSON object or a hand-written HTTP request. The interface may help a person assemble the request, but it does not acquire authority to redefine the domain.
Distinguish missing information from contradictory information
02 / See the idea
Missing is different from contradictory
The missing-summary case asks a concrete question. A wrong-tenant case cannot be repaired simply by producing more fluent text.
Interpretation and evidence
- Contradictions take precedence.
- Questions remain in the history.
- Ready does not mean accepted.
Missing information and contradictory information require different recovery actions. If the summary is absent, the system can ask what observed issue the order should describe. If a proposal names another tenant, asking the requester to fill in a summary does not resolve the authority problem. The validator therefore keeps both reasons and clarifying questions visible.
The implemented rules first collect contradictions. A nonempty tenant must match the trusted requester context. A named asset must exist and belong to that tenant. A supplied evidence version must match the current catalog version. A supplied priority must be either normal or urgent, and the summary must remain within the fixture's length bound. These are explicit application rules, not behaviors delegated to the model.
Missing fields produce their own reason codes and questions. When contradictions exist, the state is Rejected; otherwise, missing information yields Clarification. Only a proposal with neither category becomes ReadyForReview. The order of those decisions matters because a partially empty but contradictory request should not be disguised as a harmless request for more detail.
if (errors.Count > 0)
return new("Rejected", errors.ToArray(), questions.ToArray());
return missing.Count > 0
? new("Clarification", missing.ToArray(), questions.ToArray())
: new("ReadyForReview", [], []);
Reason codes serve a different consumer from explanatory text. A test can compare stale-evidence exactly, while an interface can explain that the asset observation changed after the proposal was prepared. The question about a missing summary is preserved in the revision, so a later analyst can see why another interaction was required. The system does not erase that first attempt when the corrected proposal arrives.
This is not a general truth engine. A nonempty, short summary can still be false. The validator does not perform semantic entailment against the catalog observation. One fixture deliberately submits a dramatic replacement claim that the evidence does not support. It passes the structural rules and reaches review, where the independent field check withholds approval. That case is essential: it demonstrates the difference between a validator that establishes eligibility for review and one that supposedly proves the content true.
Make the parsing boundary explicit
The AI adapter supplies text, so typed deserialization is a meaningful boundary. The delivered parser accepts an object with the known fields, rejects unmapped members, and rejects duplicate property names before deserializing. Missing known fields remain nullable so the domain can ask for clarification instead of treating every omission as a transport error.
The project uses JsonUnmappedMemberHandling.Disallow, whose behavior is documented in System.Text.Json guidance on unmapped members. That setting addresses unknown fields; it is not the duplicate-property check. The latter is an explicit pass over the object names using a case-insensitive set, aligned with the serializer's web defaults.
var names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var property in doc.RootElement.EnumerateObject())
if (!names.Add(property.Name))
throw new JsonException("Duplicate member");
The distinction matters when a payload contains two tenant fields or an unexpected actor field. Ignoring an unknown actor would not, in this implementation, replace the host's trusted actor. Rejecting it still provides a clearer contract and a preserved explanation of the attempted shape. The requester context is created outside the proposal document and never deserialized from its claims.
Malformed JSON is also retained. The revision stores the raw input, a null typed proposal, and an invalid-schema reason. This makes a failed adapter response visible in the same history as domain rejections. The experiment is small and entirely synthetic, so retaining the raw input is safe within its stated scope. A real product would need data minimization, access control and retention rules before retaining arbitrary submitted text.
There is no arbitrary-input robustness claim here. The host is a bounded local fixture with small known requests, not a hardened public endpoint. Request-size limits, abuse controls, production authentication and concurrent multi-user behavior would need separate design and evidence. The useful claim is that the selected malformed, duplicate and unknown-member cases crossed the actual HTTP path and were rejected without disappearing from the ledger.
Preserve revisions instead of polishing away the failures
03 / Watch the mechanism
A correction preserves the first attempt
Static view. Play to see how the mechanism unfolds.
A missing summary produces a question, then a second draft reaches review. Motion illustrates logical progression, not measured human effort or model latency.
Interpretation and evidence
- The first failed attempt remains visible.
- Only summary changes in this case.
- Approval is a distinct event.
Each submitted draft creates a new immutable revision record containing the order identity, revision number, input channel, raw JSON, parsed fields, digest, validation result and changed field names. A correction appends another record. It does not overwrite the earlier one or replace its question with a later success message.
In the clarified fixture, the first revision lacks a summary. The validator records missing-summary and asks what observed issue should be described. The second revision supplies the inlet-seal observation. The field-difference record contains only summary. A test checks that exact change, so the example cannot quietly claim a simple clarification while also changing tenant, asset, priority or evidence version.
The scripted client receives the previous question as the next user message, but its answer is prearranged. That distinction prevents a false inference about interactive reasoning. We exercised the plumbing needed to carry a clarification into another draft. We did not establish that a model understands the question or asks an appropriate question on unfamiliar cases.
The ledger also separates proposal revisions from approval attempts. A rejected review, an old digest and a duplicate approval are events with their own reasons. This is useful because not every failed step should create a new proposed work order. Someone can attempt to approve the wrong revision without changing the proposal itself.
The implementation stores this history in memory and exports it to the result JSON before exit. It is not a durable operational ledger. A crash before export loses the history, and the application does not support restart recovery. That is an intentional boundary for a product-decision laboratory. The export makes this run inspectable; it does not make the host a production work-order system.
A durable implementation would need to define the transaction joining acceptance, its receipt and any downstream dispatch. It would also need a retention model for revisions. Those concerns matter once acceptance creates real work, but they should not obscure the earlier question of whether the proposed interaction produces a reviewable order at all. The current scope establishes that earlier contract with actual code and a finite dataset.
Bind approval to the exact fields under review
04 / See the idea
Approval refers to the exact revision
Changing priority while retaining the original digest is rejected. A catalog update from version 7 to 8 also rejects the pending approval.
Interpretation and evidence
- All five reviewed fields must match.
- A digest is not a signature.
- Evidence freshness is checked again.
Approval is separate from proposal generation. The approval request identifies a revision number, supplies its digest and includes the five fields the fixture reviewer inspected. The service compares all three with the latest proposal before accepting anything. A correct digest beside different reviewed fields does not authorize the change.
The digest is calculated from the typed proposal serialized with the laboratory's fixed options and hashed with SHA-256. The HashData API provides the hash operation. This is a local representation identity, not a signature, an authenticated human approval or a cross-language canonical JSON standard.
if (latest.Number != request.Revision
|| latest.Digest != request.Digest
|| latest.Proposal != request.ReviewedFields)
{
return Result("Rejected", "review-does-not-match-latest");
}
The reviewer must also have the fixture review capability and belong to the proposal's tenant. The code tests a requester without that capability and a reviewer from another tenant. These checks establish the behavior of the domain boundary for explicit actor objects. They do not prove real authentication: the local host supplies fixed fixture actors, and no identity provider participates.
Evidence freshness is checked again during approval. A proposal can have been ready when submitted and become stale before review completes. The test changes pump-a from evidence version 7 to 8 between submission and approval. The attempted approval is rejected with revalidation:stale-evidence, and the accepted count remains unchanged. The catalog is then restored for subsequent independent fixture checks.
Repeated approval of the same accepted order is idempotent within this process. It returns Accepted with an idempotent-approval reason and records no new effect. This is a narrow property of the in-memory acceptance dictionary. It is not an exactly-once guarantee across crashes, brokers or external maintenance systems. No such external effect occurs in this program.
The most important implication is that review refers to an object, not a vague conversation. If the draft changes, the review must refer to the new revision. If the evidence changes, the domain must reconsider eligibility. If the reviewed fields differ from the stored fields, the service must refuse the mismatch rather than assuming the reviewer meant something close enough.
Put the expected outcomes outside the generator
The repository contains two separate fixture files. cases.json supplies draft inputs. golden.json supplies independently written expected states, reason codes, questions and, where appropriate, the fields the reviewer should accept. The scripted provider receives only the draft sequence. It does not read the golden file or receive the expected terminal state in its messages.
This is independence from the implementation's calculation, not a claim of an external blinded evaluation. The fixture author designed both files, and the dataset is small. The important protection is that the test does not ask the validator what should happen and then compare the validator with itself. Expected rejection reasons and exact review fields are literal assertions in a separately inspectable artifact.
Nine cases run through each channel. A complete proposal can be reviewed immediately. A missing-summary proposal needs a second revision. Wrong tenant, stale evidence, unknown asset, invalid priority and foreign asset are rejected. Missing evidence remains a clarification. An unsupported but structurally plausible summary reaches review and is deliberately withheld.
The unsupported-summary case is especially valuable because it prevents a convenient but false conclusion: all ready proposals are correct proposals. Its golden review fields contain the actual fixture observation, while the submitted summary says that the pump exploded and needs replacement. The service's structural validator does not know that those statements conflict. The separate review comparison does, and no approval is sent.
The form and scripted paths receive the same case material. This prevents one interface from receiving only easy examples while the other gets contradictions. It also means their matching outcomes are expected by construction once both adapters preserve the inputs. The result demonstrates contract consistency, not a surprising tie in a contest between people and AI.
There are 155 assertions in the final run because each revision checks several properties: actual HTTP handling, state, reasons, questions, revision sequence and the absence of automatic acceptance. Additional assertions cover field review, approval boundaries, duplicate approvals and parsing failures. The assertion count is execution evidence, not a quality score or a statistical sample size.
Read the actual results without changing the denominator
05 / A concrete example
Keep every case in the denominator
Bar lengths encode recorded case counts, not productivity or model accuracy. The deliberately adversarial fixture distribution is not a real-world acceptance-rate estimate.
Interpretation and evidence
- Each channel retains all nine cases.
- Revisions and tasks have different counts.
- Equal scripted results do not compare model quality.
The comparison cohort contains 18 channel-case executions: nine fixtures through the structured-form path and the same nine through the scripted client. The clarified case has two proposal revisions in each channel, so the cohort contains 20 revisions. Four orders become accepted after explicit fixture review, two from each channel.
| Final comparison outcome | Form | Scripted IChatClient | Meaning |
|---|---|---|---|
| Accepted | 2 | 2 | Complete or clarified, then explicitly approved |
| Rejected | 5 | 5 | Domain contradiction remains visible |
| Clarification | 1 | 1 | Evidence version still missing |
| ReadyForReview, withheld | 1 | 1 | Summary differs from independent evidence |
| Total channel-cases | 9 | 9 | No failed or unresolved case removed |
These counts are actual outcomes from the supplied cases. They are not estimates of a real acceptance rate. The distribution was deliberately constructed to expose boundaries, so converting four accepted orders out of eighteen into a market-level success percentage would be misleading. The denominator is useful because it preserves what happened in this experiment, not because the cases represent a population.
At the revision level, the cohort has six ReadyForReview records, ten Rejected records and four Clarification records. Those counts answer a different question from final case outcomes. The two first revisions missing a summary remain in the history even though their cases eventually become accepted. Confusing revisions with tasks would make the clarification path appear to have created extra completed work.
The ledger also includes five supplemental proposal records and several approval attempts used to test boundary failures. Those are outside the 18-case comparison cohort. They test an old revision, altered reviewed fields, a wrong digest, an evidence change, invalid JSON and related conditions. The exported report preserves them, while the comparison summary keeps its declared population separate.
No throughput or latency benchmark accompanies these results. The service and provider are local, the inputs are tiny, and the central question is functional acceptance. Timing the scripted provider would not measure a hosted model or a person's review effort. The command execution receipt is retained for reproducibility, but its wall time is not promoted into a productivity claim.
Show why HTTP success is not task acceptance
The proposal endpoint returns a successful HTTP response when it has handled and classified a submitted proposal. Its JSON may still contain Rejected, Clarification or ReadyForReview. The test explicitly checks that a successful proposal response never becomes Accepted merely because the request completed.
This is a deliberate application contract. HTTP semantics describe successful handling of a request, while the domain result describes what the application decided about the proposed work. ASP.NET's minimal API response guidance describes the response mechanisms used by the fixture. Neither source defines our work-order acceptance policy.
Another API could choose different status codes for some domain failures. That design choice would not eliminate the need for an explicit business state. A client that displays a green accepted label whenever IsSuccessStatusCode is true would be wrong for this endpoint. A client that treats every non-success response as proof that no external effect occurred could be wrong for a different endpoint with an uncertain write outcome.
The related laboratory Reservation Confirmed or Work Accepted explores a neighboring distinction using real HTTP and SQLite: admission of work and confirmation of a reservation are different promises. This article applies the same discipline earlier in a workflow, separating a handled proposal from an approved work order. It does not repeat that reservation implementation or inherit its persistence evidence.
The negative check is more useful than an optimistic screenshot. A rejected wrong-tenant proposal still produces a handled HTTP response, and the test refuses to count it as accepted. That counterexample exposes the exact place where a demo can inflate its success metric. The request path works; the proposed task is not authorized for acceptance.
The same distinction belongs in telemetry. A transport-success counter can help diagnose availability, while accepted-order counts describe a domain outcome. Their difference is not necessarily an error. It may represent useful rejection, necessary clarification or a reviewer correctly withholding approval. A product team needs both views if it wants to understand where effort actually goes.
Keep the rubric open to challenge
An independent expected-output file can still encode a bad policy. If every golden answer assumes that normal priority is appropriate, the test suite will not discover that a real safety procedure requires urgent escalation for a particular observation. The fixture avoids making that operational claim: its priorities are synthetic labels, and its catalog is deliberately fictional. A production rubric needs a domain owner who can explain why each acceptance condition exists.
Consider a hypothetical change in which the receiver no longer accepts free-text summaries and instead requires an observation category plus a source reference. That is not merely a prompt adjustment. It changes the proposal type, the parser, the reviewer view, the independent expected fields and the meaning of a completed task. Keeping the old acceptance count while silently substituting the new contract would make comparisons difficult to interpret.
The same issue appears when a clarification question is technically correct but operationally unhelpful. Asking for an evidence version may be meaningless to a requester who cannot see that version. The validator can correctly identify the missing field while the product still fails to help the person resolve it. Our check of the exact question protects the selected fixture behavior; it does not establish usability. A real interface might retrieve a permitted current version for explicit confirmation instead of asking the person to type a number.
These examples suggest a practical review discipline. Keep the proposed task, its evidence and the reason for each required field beside the rubric. When a rule changes, record whether the change corrects an implementation defect or changes the product's definition of acceptable work. Those are different events. The first should restore behavior already promised; the second may require new examples, communication and a fresh comparison boundary.
This discipline also prevents tests from becoming a convenient argument for preserving an unnecessary feature. Passing the rubric means that the implementation satisfies the selected contract. It does not mean that the contract addresses an important user problem, that automation is the best intervention, or that the cost of operating the feature is justified. Those questions remain available to challenge precisely because the technical evidence is stated narrowly.
Design the next human study without inventing its result
The technical harness makes a later product study more credible because it defines what counts as a completed task and preserves the path to it. It does not replace that study. No participant was interviewed, timed or asked to rate the interfaces during this work. No claim about reviewer satisfaction, trust or productivity is supported by the functional run.
A proposed study should compare the complete tasks presented to participants, not just the time needed to produce a first draft. The receiver may spend effort checking asset identity, correcting a summary, finding current evidence or rejecting a confident invention. If that effort is omitted, a drafting feature can appear faster while increasing the work required to reach acceptance.
The study protocol should record the submitted fields, revisions, questions, review decisions and unresolved tasks, with appropriate consent and data handling for real participants. Time should be measured only when the task boundaries are agreed and actual people perform the work. The laboratory already supplies event categories, but it does not supply meaningful human durations for them.
Order effects also deserve attention. A participant who completes the same case once may remember its answer when trying another interface. A future protocol could assign comparable case sets and vary interface order, while preserving a predefined rubric for correctness. This is a proposal to be reviewed before execution, not a report of a study that has already happened or a statistical guarantee about its design.
The unsupported-summary case suggests a particularly important observation: whether fluent output makes a reviewer less likely to inspect evidence. Our deterministic field comparison catches the mismatch because its expected string is explicit. People may behave differently, and a live model may generate subtler distortions. Those possibilities motivate research questions; they do not authorize fabricated answers about trust or automation bias.
Any real model evaluation would also need its own versioned run manifest, model settings, prompts, inputs and failure accounting. The current IChatClient script contains no model identity because no model was called. Adding a provider later should not retroactively turn this fixture's acceptance counts into that provider's quality results.
Make a product decision that can reject the feature
The laboratory supports a limited engineering decision now: both adapters can reach the same validation and review boundary, and the selected failures remain visible. It does not yet support the commercial claim that a conversational interface improves the work-order process. That distinction allows the next decision to be evidence-seeking rather than promotional.
One plausible outcome is to keep the structured form as the primary interface and use drafting only for summaries that a requester can easily verify. Another is to narrow the AI feature to clarification assistance while keeping asset selection, evidence version and priority as explicit controls. A third is to remove the drafting feature if its corrections and review burden outweigh any benefit. These are conditional product options, not conclusions established by this scripted run.
The strongest counterargument is that such a small laboratory is too artificial to inform product strategy. It is artificial, and its numerical outcomes should not be generalized. Its value is instead architectural: it demonstrates whether the system can represent the observations that a serious product decision would require. If the implementation cannot retain rejected drafts or distinguish acceptance from response delivery, a later study will struggle to recover those facts reliably.
There is also a danger of overbuilding. A team can spend months constructing a universal evaluation platform before learning whether a simple form solves the problem. This repository deliberately stops at a typed service, a finite fixture set, two adapters and an inspectable report. It is enough to expose the acceptance boundary and prepare a focused next experiment without pretending to be a complete product.
The implementation should remain replaceable. If the organization changes its definition of acceptable work, the rubric and validator must be reviewed together rather than silently changing expected outputs until tests pass. If a provider changes, the adapter should be tested against the existing domain contract before its new language is treated as authority. If the receiver no longer needs the proposed automation, the feature should be removable without losing the core work-order process.
That is the difference between a demonstration that merely impresses and an experiment that can change a decision. The latter preserves unwelcome results, names its unknowns and makes it possible to conclude that a smaller feature, or no AI feature, is the better product.
Reproduce the accepted-work boundary
The download contains the project, package lockfile, pinned SDK configuration, domain service, scripted provider and the two fixture files. Run the command from the lab directory with SDK 10.0.400 and runtime 10.0.15 available:
dotnet run -c Release -- ../check-results.json
The executable starts its own ASP.NET application on an ephemeral loopback port, sends actual HTTP requests, executes the direct actor-boundary checks, exports the report and stops the server. Clients and provider instances are disposed. There is no deployed service, cloud resource, account query, real interview or external work dispatch.
The final recorded run completed with exit code zero, 155 passing checks and no skipped checks. The report includes every comparison revision, its validation reasons and clarifying questions, the field differences, all approval attempts and the final accepted identities. Supplemental negative cases are retained separately from the comparison cohort rather than being discarded after they prove a point.
Inspect the golden file before trusting the result. It states which cases should be accepted, which remain incomplete and which fields the fixture reviewer expects. Then inspect the raw revisions for the unsupported summary and the first incomplete draft. Those records are the most important antidote to a polished demonstration: they show exactly what the system failed to establish and why acceptance was withheld.
The useful endpoint is not that the application generated a plausible order. It is that a particular revision, for the right tenant and current evidence, crossed an explicit review boundary while the rejected and unresolved alternatives remained visible. Once that contract exists, a team can investigate whether AI makes the path better. Before it exists, a faster demonstration may simply be a faster way to create work for someone else.
Source code and execution evidence
Download the complete lab, source record and raw execution results. This package supports the specific execution claims in this article. It is not a production certification.