Decisions as a Service
Sign Up Now →Sign Up Now

Core concepts

Eight ideas cover everything the runtime does. Each one maps to a section of the playbook file that defines a pack and to a field on the result you get back.

About the example

This page illustrates each concept with the built-in example pack (data protection, compliance.regulatory_pii_guard.v1), so you can run everything without writing a pack first. The concepts are the same for any decision pack: eligibility, limits, routing and so on.

Pack and playbook#

A playbook is a YAML file that describes one decision. A pack is that playbook compiled and encrypted into a .hxpack file for distribution. Every pack has a stable pack_id and a version.

The runtime also carries one pack built in, the example pack (compliance.regulatory_pii_guard.v1), so HelixorEngine() works with no files at all. It decides whether text containing sensitive data may leave a system. It is there so every guide can run with no setup; it is an example of a pack, not the purpose of the runtime.

What a compiled pack executes in 0.3.1

The built-in example pack runs its codons and rules as described on this page. A pack you compile yourself runs the example pack's built-in checks plus the regex and Luhn-checksum rules you declare. The compiler rejects your own codons and hard_rules; executing them from a compiled pack is Planned; see Playbooks.

Codons and state#

A codon is a small extraction step that turns raw input into a typed fact and binds it to the decision state. A codon can add a check to its extraction, so that only valid values count.

In the example pack, the codons are pattern extractors: each one scans the text and binds a boolean such as has_ssn or has_credit_card. The card codon adds the Luhn checksum, so random 16-digit strings do not count.

- code: PII_CARD_EXTRACT
  codon_type: extract_pattern
  trigger: on_input
  checksum: luhn
  params:
    pattern: '\b(?:\d{4}[-\s]?){3}\d{4}\b'
  binds_to: has_credit_card
  remedy_template: "[REDACTED_CARD_PAN]"

Rules never look at raw text. They look at state, which keeps them short and makes the extraction step testable on its own.

Rules and severity#

A rule is a condition over state, an action to take when it holds, and a severity:

  • fatal: the payload must not proceed. Block it.
  • warning: the payload may proceed once it has been repaired.

Rules are also called invariants: properties that must hold for the payload to proceed unchanged. The first fatal invariant that fires decides the action. When none fire, invariants_passed is True.

Actions#

Every pack declares a closed list of actions and a default_action for payloads that break no rule. The runtime only ever returns one of the declared actions, so you can branch on them exhaustively. In the example pack, block actions start with block_, repairs with redact_ and passes with permit_.

Remedies#

A remedy is the smallest change that would make the payload satisfy the pack's invariants. The remedy is always computed, even for fatal results, so you can show a user what the pack found and what would fix it. In the example pack, the remedy replaces each match with its codon's remedy_template, so you can show what was found without showing the value itself.

input : Draft a follow-up to david@client.com or call (415) 555-0182.
action: redact_and_permit_contact_pii
clean : Draft a follow-up to [REDACTED_EMAIL] or call [REDACTED_PHONE].

Receipts#

Each result carries a receipt_hash: a SHA-256-derived fingerprint of the pack, the action, the outcome, the rules that fired and a hash of the input. Log it next to your own request ID so you can later show which pack decided a request and what it decided. Receipts today are unkeyed and not chained; see Receipts for exactly what they prove.

Licenses and tiers#

A license (.hxlic) is a JSON document signed with Ed25519 by the Helixor license authority. It names the licensee, the tier, which packs and solvers may run, which features are enabled and the validity window. The runtime verifies the signature and dates before it will unseal a pack.

TierYou getHow
0 · CommunityThe runtime with the built-in example pack: evaluate, stream, batch, serve.Install. Nothing else.
1 · DeveloperCustom rules and playbook editing, rate-limited.Free registration; you receive a Developer .hxlic. A one-step helixor license activate command is Planned.
2 · StudioOntology viewer and data-source binding.Portal login.
3 · ExpertYour own domains, codons and packs.Pack authoring in Studio.

Accounts and SDK downloads#

Everything you run comes in three pieces. The SDK is the same for everyone; the license and your packs are issued to your organization through your account.

DownloadWhat it isWhere fromStatus
Python SDK and CLIThe helixor-runtime package: the helixor_runtime library, the built-in example pack, and the helixor-pack commandYour account's download page and the public Python package indexAvailable as a wheel on request; Planned self-serve and on the public index
Generated OpenAPI clientsTyped HTTP clients for Python, JavaScript/TypeScript, Java, C# and RustThe API's release artifacts or package registryGeneration available; registry publication is release-specific
Embedded decision SDKsTyped in-process bindings for Python, Java, C#, Rust and CGenerated per pack; native runtime, license and sealed pack are provisioned separately where requiredGeneration available; see the capability matrix
License (.hxlic)Your signed entitlements and pack keyYour accountPlanned self-serve; issued on request today
Packs (.hxpack)Decision packs sealed to your licensehelixor-pack download-pack or compileAvailable

SDKs are generated from one published contract, so every language exposes the same operations, fields and errors. Every release is listed in a manifest on sdk.helixor.ai Planned that records each file's SHA-256 checksum and its software bill of materials; the package registries are mirrors of that manifest. Verify a download before you install it:

shasum -a 256 helixor_runtime-0.3.1-py3-none-any.whl helixor_constraint_network-1.0.1-py3-none-any.whl
# compare with the checksum published with the release

Ontology and binding layers#

For simple integrations you pass a payload to the decision core and read the result. For advanced integrations, where decisions depend on data spread across several systems, two layers sit in front of the core.

  • The ontology layer is a typed vocabulary for your domain: classes such as Customer or Policy, and the relations between them, such as placedBy and memberOf. Relations carry semantics (inverse, symmetric, transitive, sub-property, chains). A reasoner derives new edges from asserted ones and records why each derived edge exists. Incoming data is first lowered into typed assertions (entities, scalars, relations, fact-relations) and admitted against the vocabulary. In open mode unknown terms become candidates; in closed mode they are rejected.
  • The binding layer connects where data lives to what a decision needs. A view binds one source (a SQL table, a REST endpoint, a sheet) to one ontology class, maps its columns to class attributes, and applies row policies written in ontology terms. Reads can happen live against the source instead of copying it. When several sources describe the same entity, a fusion step picks one value per attribute and records why it won.
SourcesSQL, REST, sheets Viewsmapping + policy Ontologyclasses, edges Fusionvalue + lineage Decisionpack state today: your application passes the fused entity in
Views bind sources to ontology classes; fusion resolves overlapping values; the decision evaluates typed state. The last hop is made by your application today.

These layers are covered in depth under Advanced integration: Ontology, Data binding and zero-copy access, and Resolving overlapping sources.

An example ontology#

An ontology names the things a decision is about (classes), what you know about each one (attributes) and how they relate (relationships). Rules are written against it, so a rule says "the borrower's credit score", not "column 7".

The diagram shows the ontology of the rule-language example, a fictional equipment credit line. Every class, attribute, relationship and cardinality in it comes from the example's ontology file, and the highlighted parts are the ones the example's rules declare that they use.

submittedBy depends-on * 1 operatesIn classified-as * 1 partOfApplication part-of * 1 securedBy depends-on * 1..* ownsCollateral owns 1 * locatedAt located-at * 1 guaranteedBy depends-on * * assignedTo assigned-to * 0..1 collateralOwner (derived) owns * 0..1 facilityBorrower (derived) depends-on * 1 Borrower hasYearsInBusiness number hasCreditScore number hasSanctionsHit number hasRecentBankruptcy number hasCustomerYears number hasPaymentDefaults number IndustrySegment hasRiskCode string Application hasRequestedAmount number hasDebtServiceCoverage number hasAuditedFinancials number CreditFacility hasLoanToValue number Collateral hasAppraisedValue number Site hasRegion string Guarantor (no attributes) CreditOfficer (no attributes)
Generated from the ontology file of the rule example. Blue boxes, attributes and lines are the classes and predicates the rules declare in @uses_classes and @uses_predicates. Dashed lines are derived relationships. Labels at each end of a line are cardinalities. Declared in the ontology but used by no rule: classes Site; predicates hasAppraisedValue, hasRegion, submittedBy, partOfApplication, ownsCollateral, locatedAt, collateralOwner, facilityBorrower.
FromRelationshipToCardinalityKindAsserted or derivedUsed by rules
ApplicationsubmittedByBorrower* to 1depends-onasserted
BorroweroperatesInIndustrySegment* to 1classified-asassertedyes
CreditFacilitypartOfApplicationApplication* to 1part-ofasserted
CreditFacilitysecuredByCollateral* to 1..*depends-onassertedyes
BorrowerownsCollateralCollateral1 to *ownsasserted
CollaterallocatedAtSite* to 1located-atasserted
ApplicationguaranteedByGuarantor* to *depends-onassertedyes
ApplicationassignedToCreditOfficer* to 0..1assigned-toassertedyes
CollateralcollateralOwnerBorrower* to 0..1ownsderived: inverse of ownsCollateral
CreditFacilityfacilityBorrowerBorrower* to 1depends-onderived: chain partOfApplication then submittedBy

This ontology is the whole vocabulary the example's rules may use; The ontology is the vocabulary shows how its facts reach the rules.

Two kinds of relationship appear:

  • Asserted relationships (solid) are stated by your data: an application is submitted by a borrower.
  • Derived relationships (dashed) follow from others: a facility's borrower is the borrower who submitted the application the facility is part of, and a piece of collateral is owned by the borrower who owns it. The ontology declares the derivation; you never store these edges yourself.

What the ontology does and does not enforce today

The ontology file is checked when it loads: every class a relationship names must exist and derivations must be well formed. Minimum cardinality (whether a relationship is required) is recorded on each relationship but not enforced when facts arrive. Rules declare the classes and predicates they use with @uses_classes and @uses_predicates; checking those declarations against the ontology is done by the example's own test, not by the engine, and engine-side checking is Planned.

Codons, symbols and a vocabulary that changes#

Two words describe how Helixor turns input into something it can reason about:

  • A codon is an extraction step. It reads the input and writes one typed value into the decision state: has_ssn, a debt service coverage of 1.12, an intent such as "asks for a person". It can validate what it extracts, for example with a checksum.
  • A symbol is a term in the vocabulary Helixor uses to describe and solve a problem: a class or predicate in an ontology, a named fact a rule reads, an operation the reasoning engine can apply. Symbols have a namespace, a code and a version.

The path from input to action runs through both:

Codonextracts a typed value Symboldebt_service_coverage Rule or invariantreads the symbol Actionone declared action
Rules never read raw input. They read values stored under the pack's vocabulary.

How the parts are linked today

In a pack, a codon writes to a state field the pack names, and the pack's rules read that field. The field name is the pack's vocabulary. Linking pack codons to entries in Helixor's symbol registry, so that the same term means the same thing across packs, is Planned.

Why the vocabulary is not fixed#

A fixed vocabulary would freeze what Helixor can describe. New regulations add concepts, products add attributes, and some terms turn out to be duplicates or useless. So the vocabulary grows when a new concept is admitted and should shrink when a concept is retired or merged into another. What matters is that it changes under governance:

  • Proposed, never applied. A new term starts as a proposal with the evidence for it. Nothing that runs today changes because a proposal exists.
  • Reviewed by a person. A named reviewer accepts or rejects it.
  • Versioned, never edited in place. An accepted change produces a new version of the ontology or pack. The version you run is pinned, so a decision can always be traced to the exact vocabulary that produced it, and you move to the new version deliberately.
Observerepeated use Proposewith evidence Reviewa named person New versionnever in place Pin and usecodons and rules Plannedadmit to the shared registry · retire · merge
Solid steps exist today. The dashed box is planned.
StepStatusWhat happens
Observe and proposeOperator toolingThe reasoning service records candidate terms from expressions it uses repeatedly, with the evidence for each.
ReviewOperator toolingAn administrator accepts, rejects or deprecates a candidate. An accepted candidate becomes a draft proposal, not a live term.
New version of an ontologyDone by Helixor todayA proposed class or attribute produces a new ontology version for review, with the old and new fingerprints. The live version is not changed. Self-service is Planned.
Pin and useAvailablePacks and rulebooks name the version they run. Codons write values; rules read them.
Admit a reviewed term into the shared symbol registryPlannedAn accepted proposal stays a draft until this exists.
Retire a termPlannedA term that stopped earning its place would be deprecated in a new version, never deleted from old ones.
Merge two termsPlannedTwo terms found to mean the same thing would be merged in a new version.

Worked example: adding debt service coverage#

Suppose the credit example's first version knew revenue and credit score but not debt service coverage, and credit policy decides that coverage below 1.0 is grounds for decline. The change flows like this:

  1. Propose the term

    Add hasDebtServiceCoverage (a number on Application, read from the fact debt_service_coverage) to the ontology. This produces version 2 for review; version 1 keeps running.

  2. Extract it

    The intake step (a codon, or the system of record behind it) now writes debt_service_coverage into each case.

  3. Use it in a rule

    Rulebook version 2 adds RKO04: IF FILE_COMPLETE AND HAS_DEBT_SERVICE_COVERAGE < 1.0 THEN DECLINE_GROUNDS_CASHFLOW, declaring @uses_predicates [hasDebtServiceCoverage].

  4. Review and pin

    A reviewer approves both versions. The decision type moves from credit-line@v1 to credit-line@v2; every decision records which version decided it.

Each step is a reviewed change to a versioned file. Making the proposal and review steps self-service is Planned.

Putting it together#

Inputtext or dict Codonsextract, check Statehas_ssn … Rulesaction, severity Resultremedy, receipt
One evaluation. Codons fill state, rules pick the action, the remedy repairs the payload and the result is fingerprinted.