Skip to main content
A ruleset is a versioned collection of rules bound to a context and to a schema. Each decision request selects a context, and Specter evaluates it against the one ruleset that is ACTIVE for that context — validating the payload and resolving rule field paths against that ruleset’s bound schema.

Schema binding

Every ruleset declares the (schema, version) its rules are written against, and the binding is required when you create it:
  • The built-in transaction schema binds by name only. A custom schema binds by name and version: {"name": "refund-request", "version": 2}.
  • Rules inherit the binding — there is no per-rule schema field. A field reference the bound schema does not declare rejects at submission with 422 naming the path; on the transaction schema, $.metadata.* stays free-form.
  • schema and context are identity fields: they do not change on PATCH. To move a context to another schema or version, create a new ruleset with the new binding and activate it.
  • A binding to an unknown schema, a nonexistent version, or a deprecated version rejects at create, and a draft bound to a version deprecated since then cannot be activated. Rulesets that are already ACTIVE keep serving after their version is deprecated.
  • Backend rules are available on transaction-bound rulesets only.
Rulesets that existed before schema binding was introduced carry the transaction binding.

Lifecycle

  • Activate (POST /api/admin/rulesets/{id}/activate) transitions a DRAFT to ACTIVE and automatically moves the previous active ruleset for that context to INACTIVE.
  • Rollback (POST /api/admin/rulesets/{id}/rollback) reactivates an INACTIVE ruleset, reverting to a known-good configuration.
The single-active-per-context guarantee is enforced, so two rulesets can never be active for the same context simultaneously.

Contexts

Contexts let you run different rule strategies for different flows — for example checkout, subscription, or default. The decision request’s context field selects which active ruleset applies. If a request names a context that has no active ruleset, Specter falls back to the active ruleset for the default context. If neither exists, no rules are evaluated and the decision is ALLOW.

Editing

Because only DRAFT rulesets are editable, the safe change workflow is:
1

Create a draft

POST /api/admin/rulesets (scope admin:rulesets:create) with the schema binding and your rules. Field paths, filter types, and scope constraints are checked against the bound schema here, so a mistake surfaces as a 422 naming the rule and the operand.
2

Refine

PATCH /api/admin/rulesets/{id} (scope admin:rulesets:write) to adjust the draft.
3

Simulate

POST /api/admin/rulesets/{id}/simulate (scope admin:rulesets:simulate) with a test payload. The evaluation trace shows every rule’s outcome and the derivations behind it, with no side effects — no decision record, no counter increment, no backend call.
4

Activate

POST /api/admin/rulesets/{id}/activate to make it live. The previous active ruleset becomes inactive.
5

Roll back if needed

POST /api/admin/rulesets/{id}/rollback to reactivate the previous ruleset.

Rule engine

The rule types and evaluation model inside a ruleset.

Schemas

The built-in transaction schema and custom schemas a ruleset binds to.