Skip to content

Assay

Validation and computation

Tier: Judge · Requirement module: Validation (cross-cutting) · Status: ✅ Prototyped

Purpose

To assay is to test a sample and report what it actually contains. Assay takes a submission document and a template version and returns two things: the computed figures the template derives, and the validation results the template's rules produce — each result carrying the directive it derives from.

Assay is called from three places and is the same engine in all three:

  1. The firm's portal, before submission, so a firm never files a return it could have fixed
  2. The write path, at submission, where failure rejects the write
  3. Re-validation, when a rule or threshold changes and the supervisor asks what would happen now

Three callers, one implementation. That is the reason it is a separate engine.

Scope

Capability Status Notes
Field-level validation Type, required, range, non-negative
Cross-field validation Period start before period end; totals reconcile
Prior-period variance Movement against the configured tolerance, explanation required above it
Derived computation Formula fields — capital surplus, early warning ratio, totals
Reference lookups 🟡 Minimum capital by licence category, FX rates by period end
Cross-return consistency R02 against R01 for the same period — see open questions
Attachment completeness Required documents present before final submission
Authorisation checks 🟡 Submitting user mandated for the firm and return
Re-validation against a version Run any submission against any template version, result labelled

Result shape

Every result is a verdict plus its provenance. A verdict with no citation is a defect.

{
  "ruleId": "V07",
  "status": "FAILED",
  "severity": "FAIL",
  "field": "R02-X08",
  "message": "Ratio 0.83 is below the 1.00 early warning threshold",
  "citation": "Directive on Capital Adequacy for Securities Market Intermediaries",
  "evaluatedAt": "2026-08-11T14:22:00Z",
  "templateVersion": "2.4"
}

Severities are deliberately three, not two:

Severity Effect
FAIL Blocks acceptance. The reviewer cannot approve while one stands.
ADVISORY Permitted but flagged. A negative capital surplus is reportable — the template allows it so a deficit can be declared — and still demands attention.
INFO Recorded for context, no gate.

The distinction matters: a platform that treats every anomaly as a failure trains reviewers to override, and an override habit is worse than no gate.

Why DMN

Validation rules and prudential formulas are the part of the system most likely to change and least appropriate for developers to own. Expressed as DMN decision tables in Kogito, they are:

  • Readable by the supervisor who wrote the directive
  • Versioned with the template, so a period is judged by the rules in force then
  • Testable in isolation with the requirement's own worked examples as fixtures
  • Executable without a deployment when a threshold moves

The alternative — rules in Java — puts every threshold change back in a release queue, which is precisely the failure the manifesto exists to prevent.

Owns

  • Validation execution and results
  • Computed figure evaluation
  • Severity classification
  • Re-validation runs and their labelling

Does not own

  • Rule definitionsReturn Studio
  • Storage of submissions — Strata
  • Whether a failure blocks approval in the UI — Bench enforces the gate
  • Risk scoring, though its results are drivers into Prism

Open questions

  • Cross-return rules. A rule spanning R01 and R02 for one period cannot evaluate until both exist. Options: defer the rule and re-run on arrival of the second return, or evaluate with a PENDING status that resolves later. Leaning toward PENDING so the reviewer can see the rule exists and is waiting, rather than not seeing it at all.
  • FX and reference-rate provenance. A USD-equivalent figure depends on which rate on which date. The rate used must be stored with the result, not looked up again at read time, or the same submission will validate differently tomorrow.