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 failallowPatterns— regex allowlist; non-matching values failonFailure— REJECT throws, WARN logs and continues, SANITIZE input falls back toTextSanitizer, TRUNCATE output truncates atmaxChars, FALLBACK output returns thefallbackstring, REVIEW marker propagates through a dedicated exception subtype- Class-level guardrail inheritance —
@InputGuardrailon 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) — needsInputValidator/InputSanitizerSPIjsonSchemavalidation — needs JSON-schema validator dependencydetectInjection/moderateContent/blockCategories— needs content-moderation providermaxTokens— needs tokenizer dependency (provider-aware)maskPII/piiTypes— should plug into the PII redaction SPI tracked in #80checkHallucination— LLM-driven, multi-turnformatvalidation perOutputFormatvariantRETRYon output failure — needs a re-execution callback the enforcer doesn't have today
Failure surface
Guardrail violations propagate asGuardrailViolationException, 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)
-
ClassDescriptionThrown by
InputGuardrailEnforcerorOutputGuardrailEnforcerwhen an action's declared guardrail is breached and theonFailurepolicy requires aborting the action.Why the value was rejected.Whether the violation occurred before or after action execution.Programmatic counterpart of@InputGuardrail(TNS-561) — lets a builder-builtRole(which has no annotation to read) opt into input guardrails viaRoleBuilder.inputGuardrail(...).Fluent builder; unset fields take the@InputGuardraildefaults.Resolves the active input guardrail for an action and enforces it against the working-parameter map immediately before the action body runs.Rewrites one string-valued action parameter before dispatch.Validates one string-valued action parameter before dispatch.Programmatic counterpart of@OutputGuardrail(TNS-561) — lets a builder-builtRole(which has no annotation to read) opt into output guardrails viaRoleBuilder.outputGuardrail(...).Fluent builder; unset fields take the@OutputGuardraildefaults.Resolves the active output guardrail for an action and enforces it against the executor's return value immediately after the action body completes.