case-studies/spec-driven-petclinic/.
The current caller uses Agent Eval 0.18.0 from Maven Central. Follow
CONFIGURED-RUN.md and
the presenter runbook
for setup, commands and optional isolated reproduction. The root fundamentals reactor remains on 0.17.0.
The specification supplies the roster
The subject is the vendored PetClinic branch atfc9df4af. Preparation materializes a buildable
copy and applies its existing formatter; it does not change frozen source or recording bytes.
Fixture provenance
records that origin.
EarsRequirement.from(criteria, "petclinic:fc9df4af") reads the 52 UC6 requirements.
Module 02 selects exactly UC6-AC7 through UC6-AC12; module 03 retains all 52.
Rfc2119Requirement.from(rules, "petclinic:fc9df4af") reads all 13 architectural requirements.
The actual requirement objects carry their specification and source identity into the result.
Configure and run
Each demo exposesjury(EvalModel runtime) and constructs EarsJury or Rfc2119Jury with the
selected requirements. Calling vote() enters that generated investigative backend once for the
whole roster. It can use multiple internal model/tool calls. The recorded backend simply returns
one archived answer; it does not perform a new investigation.
Workspace and timeout are configured through JudgeBackends and AgentClient. Prepared single
Judge and structured roster alternatives are executable in the tutorial’s ConfiguredExamples.
Prepared callers supply captured evidence explicitly. Structured controls retain one execution per
item: 6, 52 or 13. The requirements guide provides a complete
credential-free example of the configured API.
An ABSTAIN child stays undecided; it does not become a FAIL. UC6-AC41 asks whether deactivating a
veterinarian preserves that veterinarian on existing appointments. EARS52 remains INCONCLUSIVE
because that answer is still open. Observations about nearby behavior add no requirements and
cannot change the conclusion. RFC failures remain investigation leads rather than automatically
proven consequences.
Retain the whole result
The demos retain the complete Verdict.RosterResults is only a display view of generated roster
answers. It does not replace the Verdict used for assertions, storage or policy.
Each roster retains actual requirement associations, its child attempts, original judgments,
native facts and invocation references. One root invocation owns the generated run; children
reference it without duplicating usage. The recording provides no original token census, so usage
remains absent. Structured runtimes retain their honest per-item invocation ownership.
Tests round-trip the complete EvaluationResult through the V6 native requirement codec and then
assert retained results without executing a backend or policy. Additional caller tests cover a
refused native original with its own Checks and lower/item invocation owners, unsupported input
preflight, malformed answers and propagated cancellation.
An explicit AssertJ gate
The migrated demonstrations useagent-judge-assertj and the actual configured demo factory:
ShouldIMerge*Demo classes are excluded from ordinary regression discovery and run separately
with the commands in CONFIGURED-RUN.md. Regression tests pass by asserting these populations.
A caller may additionally use .withPolicy(verdict -> decision) on a live AssertJ stage.
That application reliance decision is retained separately. Tests withhold reliance even on the
passing slice while keeping the PASS conclusion and complete original Verdict. Cached terminals
execute neither the backend nor the policy again.