Skip to content

Test plan: Output Guardrail Engine

Expands on spec.md's Scope and Acceptance Criteria into concrete scenarios. Two of the three Open Questions are unresolved (grounding source/mechanism per app; shared vs. per-app tone/brand checks) — scenarios that depend on them are marked blocked rather than guessing at an answer. Threshold/which-checks-run configuration is owned by Feature 3 (Policy & Configuration Console) and reason-code delivery is owned by Feature 4 (Observability, Audit & Feedback Loop); scenarios here treat both as dependencies to verify against, not to re-test.

Scenarios

  1. Every response is screened before reaching the user.
  2. Given a scoped app (corehcm, superagent, edm, onb, comp, advisor, frontend) generates a response
  3. When the response is ready to send to the user
  4. Then it passes through the output-checkpoint service first, and no path exists for a generated response to reach the user without a checkpoint decision.

  5. Policy-violating content is blocked.

  6. Given a generated response contains content that violates configured policy (e.g., disallowed advice, prohibited content category)
  7. When it reaches the checkpoint
  8. Then the checkpoint decision is block, a reason code specific to the policy violated is attached, and the app shows its fallback response instead of the original.

  9. Hallucinated/ungrounded system-of-record claim is caught. (blocked on Open Question 1 — grounding source/mechanism per app)

  10. Given a response makes a factual claim about a system-of-record value (e.g., PTO balance, employment status) that contradicts or cannot be verified against the grounding source for that app
  11. When it reaches the checkpoint
  12. Then the checkpoint flags it with a hallucination reason code.
  13. Cannot be finalized until Open Question 1 defines which system-of-record facts are checkable per app at launch, per spec.md's Risks table mitigation (scope checkable facts, expand incrementally).

  14. Response with correct, grounded system-of-record claim passes.

  15. Given a response makes a factual claim about a system-of-record value that matches the grounding source
  16. When it reaches the checkpoint
  17. Then the checkpoint decision is allow — confirming the hallucination check doesn't over-fire on correct answers (negative path for scenario 3).

  18. PII or regulated data in a response is caught.

  19. Given a generated response contains PII or other regulated data (e.g., SSN, another employee's compensation) that should not be surfaced to the requesting user
  20. When it reaches the checkpoint
  21. Then the checkpoint decision is block or modify (per policy) with a PII-specific reason code, and no unredacted regulated data reaches the user.

  22. Tone/brand deviation is caught. (blocked on Open Question 2 — shared vs. per-app configurable checks)

  23. Given a generated response deviates from the configured tone/brand standard
  24. When it reaches the checkpoint
  25. Then the checkpoint decision reflects that deviation with a tone/brand reason code.
  26. Cannot be finalized until Open Question 2 resolves whether the standard is one shared check or configured per app — the scenario's precondition (which standard applies) depends on the answer.

  27. Clean response passes through unmodified.

  28. Given a generated response has no policy violation, no ungrounded claim, no PII/regulated data, and no tone/brand deviation
  29. When it reaches the checkpoint
  30. Then the checkpoint decision is allow and the original response reaches the user unchanged — confirming the engine doesn't over-block, per the Risks table's over-blocking risk.

  31. Fallback response shown per scoped app.

  32. Given a checkpoint decision of block for a given scoped app
  33. When the app receives that decision
  34. Then it shows that app's defined fallback response, not the withheld original and not a generic/no-op failure.
  35. Exact fallback copy per app is an Open Question — this scenario verifies the mechanism (block → fallback shown) works per app, not specific copy, until that's defined.

  36. Reason codes are distinct per block type.

  37. Given checkpoint decisions across all four check types (policy, hallucination, PII, tone/brand)
  38. When decisions are inspected
  39. Then each decision carries a reason code that identifies which check type triggered it, distinguishable from the others.

  40. Every checkpoint decision is available to Feature 4.

    • Given any checkpoint decision (allow, block, or modify)
    • When the decision is made
    • Then it is emitted in the format/inventory Feature 4 (Observability, Audit & Feedback Loop) defines for consumption — verify against Feature 4's inventory once defined; until then, verify only that a reason-coded decision record is produced and available for logging.
  41. Checks run per Feature 3 configuration, not hardcoded.

    • Given Feature 3's policy console configures thresholds and which checks are enabled for a given app/tenant
    • When a response from that app/tenant is screened
    • Then only the enabled checks run, at the configured thresholds — a disabled check never fires, and a threshold change (no code change) shifts detection sensitivity accordingly.
  42. Service reachable by all scoped apps under x_novaw_guardrails.

    • Given each scoped app (corehcm, superagent, edm, onb, comp, advisor, frontend)
    • When it calls the output-checkpoint service
    • Then the call succeeds and is scoped under x_novaw_guardrails — confirming no app is left uncovered.

Out of scope for this pass