Class ContractValidator

java.lang.Object
com.tnsai.actions.contracts.ContractValidator

public final class ContractValidator extends Object
Enforces @Contract clauses at action-dispatch time (TNS-552) — the declarative, JEXL-backed counterpart to the imperative ActionContract interface. Both run as additive safety gates around an action; this one reads expressions off the @Contract annotation.

Lifecycle around one action invocation:

  1. validatePreconditions(com.tnsai.metadata.ContractSpec, java.util.Map<java.lang.String, java.lang.Object>) — before invoke; a false precondition throws (it is a safety gate), surfacing an LLM-friendly message.
  2. snapshotOldValues(com.tnsai.metadata.ContractSpec, java.util.Map<java.lang.String, java.lang.Object>) — before invoke; captures the pre-execution value of every old(...) sub-expression used in postconditions.
  3. validatePostconditions(com.tnsai.metadata.ContractSpec, java.util.Map<java.lang.String, java.lang.Object>, java.lang.Object, java.util.Map<java.lang.String, java.lang.Object>) — after invoke; binds result and the old(...) snapshot, then checks each postcondition.
  4. validateInvariants(com.tnsai.metadata.ContractSpec, java.util.Map<java.lang.String, java.lang.Object>) — before and after; safety constraints that must hold throughout.

@Contract.validate() == false disables all enforcement (treat as documentation). strict() == false downgrades postcondition failures to a logged warning; preconditions and invariants always throw. message() overrides the default violation text.

old(expr) handling

A JEXL custom function cannot implement old(...) — JEXL would eagerly evaluate the argument against the post-execution state, defeating the purpose. Instead each old(<inner>) occurrence is parsed out, its <inner> is evaluated against the pre-execution bindings and stashed under a deterministic variable name, and the postcondition is rewritten to reference that variable. Snapshot and rewrite share oldVarName(java.lang.String) so they agree.
Since:
0.11.0
Author:
TnsAI Team
  • Constructor Details

    • ContractValidator

      public ContractValidator()
  • Method Details

    • evaluator

      public ContractEvaluator evaluator()
    • validatePreconditions

      public void validatePreconditions(ContractSpec spec, Map<String,Object> params)
      Checks preconditions before execution. A violation always throws.
    • snapshotOldValues

      public Map<String,Object> snapshotOldValues(ContractSpec spec, Map<String,Object> params)
      Captures pre-execution values for every old(...) sub-expression in the postconditions. Returns bindings keyed by oldVarName(java.lang.String), ready to merge into the postcondition context.
    • validatePostconditions

      public void validatePostconditions(ContractSpec spec, Map<String,Object> params, Object result, Map<String,Object> oldValues)
      Checks postconditions after execution. result and old(...) are bound.
    • validateInvariants

      public void validateInvariants(ContractSpec spec, Map<String,Object> bindings)
      Checks invariants (before and after execution). A violation always throws.