Skip to main content
An agent implemented appointment scheduling for PetClinic. Its build and existing tests pass. This path asks whether it meets the written requirements, then investigates one failed rule. The five modules share a fixed subject and a separate Maven reactor under 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 at fc9df4af. 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 exposes jury(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 use agent-judge-assertj and the actual configured demo factory:
The full class is ShouldIMergeBehaviorDemo. EARS6 passes. EARS52 intentionally fails this gate on INCONCLUSIVE; RFC13 fails it on FAIL. The 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.

Investigate one failed rule

Module 05 takes the actual RULE-4 failed requirement result. The archived investigation connects a request-before-owner lock acquisition to an owner-first path reached by the lifecycle processor. It reports CONFIRMED / REACHABLE and refines StaffFallbackService.java:247 to :248. The H2 deadlock claim in the recording was not independently reproduced; it remains an archived claim rather than a fresh result of this migration. Investigation does not repair the subject. DRY-RUN.md preserves the historical 0.17 presenter evidence. Its old API and overall ABSTAIN display describe that revision; the current configured caller uses an INCONCLUSIVE Verdict with the ABSTAIN child intact. Module 06 remains unimplemented. Recorded replay verifies API behavior and retention, rather than model accuracy. Module 01 executes a real build. Prepare Maven and nested-build dependencies before offline execution; unset live-mode and credential variables. No live inference is needed for this path.