Package com.tnsai.guardrails


package com.tnsai.guardrails
Runtime enforcement of InputGuardrail and OutputGuardrail annotations declared on @ActionSpec methods or their declaring Role classes.

Before this package landed (issue #171), guardrail annotations were decorative — declared on actions, never enforced at runtime. The InputGuardrailEnforcer and OutputGuardrailEnforcer entry points are called by ActionExecutor immediately before the action's working parameters are dispatched to its TypedActionExecutor (input side) and immediately after the executor returns (output side).

Phase 1 scope

Implements the literal bounds-checking knobs that don't require SPI extension hooks or external services:
  • maxLength / minLength (input) / maxChars / minChars (output) — character-count bounds on each parameter (input) or the return value (output)
  • blockPatterns — regex denylist; matching values fail
  • allowPatterns — regex allowlist; non-matching values fail
  • onFailure — REJECT throws, WARN logs and continues, SANITIZE input falls back to TextSanitizer, TRUNCATE output truncates at maxChars, FALLBACK output returns the fallback string, REVIEW marker propagates through a dedicated exception subtype
  • Class-level guardrail inheritance — @InputGuardrail on the Role class applies to every action whose method doesn't declare its own (overrides are method-wins)

Phase 2+ deferred

The following knobs require additional SPI design or external services and are deliberately deferred to subsequent PRs so this one stays scoped:
  • validators / sanitizers (custom Class[] references) — needs InputValidator / InputSanitizer SPI
  • jsonSchema validation — needs JSON-schema validator dependency
  • detectInjection / moderateContent / blockCategories — needs content-moderation provider
  • maxTokens — needs tokenizer dependency (provider-aware)
  • maskPII / piiTypes — should plug into the PII redaction SPI tracked in #80
  • checkHallucination — LLM-driven, multi-turn
  • format validation per OutputFormat variant
  • RETRY on output failure — needs a re-execution callback the enforcer doesn't have today

Failure surface

Guardrail violations propagate as GuardrailViolationException, which ActionExecutor catches and re-throws as an ActionExecutionException of category ActionExecutionException.ErrorCategory.VALIDATION — same surface consumers already handle for ActionValidator.validateParameters failures.
Since:
0.5.4 (issue #171, Phase 1 — declarative guardrail enforcement)