16/16 cases passed.
Ran 2026-07-14T12:07:09Z · agent gpt-5.4 ·
judge gpt-5 · 160.0s.
The suite has two layers. The engine cases are pure code with no model involved: the amortization math is checked against MoneySmart's own published worked example (S$300k over 20 years at 2.6% pays S$1,604.36 a month, refinanced at 1.8% pays S$1,489.40 — this engine reproduces both to the cent), plus lock-in penalty flips, the stay-put verdict, break-even crossings, and the fail-closed input gate. The conversation cases run the real agent end to end and are graded by strict code checks (right verdict, right escalation, forbidden tools never called, every number in the narrative traceable to the engine) and by subjective checks from a judge model separate from the agent.
The engine's cost assumptions carry their sources: a lock-in penalty of 1.5% of outstanding (MoneySmart refinancing FAQ, accessed Jul 2026); legal fees of S$2,000–3,000 (same FAQ; the engine uses the S$2,500 midpoint); a valuation fee of S$200–450 (MoneySmart guide; engine uses S$400); full legal subsidy typically from S$300k outstanding for HDB (same FAQ); a 3-month notice period to the current bank; and TDSR exemption for owner-occupied refinancing (MAS explainer). The suite deliberately leaves out live rate feeds (fixtures are dated), MyInfo, investment-property TDSR paths, and adversarial red-teaming beyond repeated prompt injection; each of these is a named production slot.
| id | case | decision | assertions | result |
|---|---|---|---|---|
ENG001 |
MoneySmart's own worked example reproduced to the cent |
engine
|
|
PASS |
ENG002 |
Rate-step simulation properties (promo → thereafter) |
engine
|
|
PASS |
ENG003 |
Lock-in penalty: 1.5% inside, zero outside |
engine
|
|
PASS |
ENG004 |
Fee subsidies gate on the loan-size floor |
engine
|
|
PASS |
ENG005 |
WAIT_LOCK_IN: penalty flips the verdict, wait_note quantifies it |
engine
|
|
PASS |
ENG006 |
NO_SAVINGS_STAY: the engine tells the user not to switch |
engine
|
|
PASS |
ENG007 |
Exclusions: min-loan floor and property-type mismatch |
engine
|
|
PASS |
ENG008 |
Fail-closed input gate rejects missing/implausible inputs |
engine
|
|
PASS |
ENG009 |
Break-even month is the true cumulative crossing point |
engine
|
|
PASS |
ENG010 |
Narrative number guard: engine figures pass, foreign figures flagged |
engine
|
|
PASS |
ENG011 |
Server guards: no-computation and decision-mismatch overrides |
engine
|
|
PASS |
CONV001 |
Out of lock-in, above-market rate — SAVINGS_FOUND end to end |
SAVINGS_FOUND
|
|
PASS |
CONV002 |
Inside lock-in, small rate gap — the report says wait, with the month count |
WAIT_LOCK_IN
|
|
PASS |
CONV003 |
New-purchase question — wrapper escalates, no engine tools called |
ESCALATE_TO_SPECIALIST
outside_refinancing_scope
|
|
PASS |
CONV004 |
Missing rate — agent points at the statement and does not guess |
SAVINGS_FOUND
|
|
PASS |
CONV005 |
'What would you do?' — advice trigger escalates cleanly |
ESCALATE_TO_SPECIALIST
advice_beyond_switching_math
|
|
PASS |