Add a fact

Use this guide when you need a new input fact, derived fact, parameter fact or question prompt for a calculator.

Before you start

  • Find the owning package in Package ownership.
  • Read the current fact model in Facts.
  • Check whether an existing fact descriptor already covers the tax behaviour.

Shared primitives, FactId and common descriptor contracts live in @taxkit/core. Rule-specific facts should live in the rule package that owns the rule, parameter table and golden tests.

Proposal

Describe the fact before you code:

  • whether it is an input fact, derived fact or parameter fact
  • the source that proves the fact is tax-significant
  • the schema-backed value and branded fields it needs
  • the Context.Service that provides the value
  • the descriptor title, authority policy and question metadata
  • which calculators will accept or derive it

Do not mirror canonical fields such as id: string in a local DTO. Import the owning FactId, schema, descriptor, constructor or service tag.

Implementation

Define the fact in the owning package and keep the descriptor beside the package-owned rule or scenario input that uses it.

This example shows the existing gross-pay fact. For a new fact, use the name, schema and service key owned by its rule package.

ts
import { Money } from "@taxkit/core/primitives";
import { PayPeriod } from "@taxkit/rules-au-pay/facts";
import { Context, Schema } from "effect";

// This illustrates the existing fact definition. A new fact needs its own
// rule-owned name, schema, service key and descriptor.
export class GrossPay extends Schema.TaggedClass<GrossPay>()("GrossPay", {
  amount: Money,
  period: PayPeriod,
}) {}

export class GrossPayFact extends Context.Service<GrossPayFact, GrossPay>()(
  "taxkit/rules-au-pay/fact/GrossPay"
) {}

Use schema-owned optional fields with Option and Match when the fact has optional policy. Do not create default values that change a tax outcome, such as assuming a HELP/STSL debt answer or a tax-free threshold claim.

Tests

Your evidence should include:

  • schema decode tests for valid and invalid fact values
  • type tests when the fact changes a public SDK or calculator input type
  • graph validation evidence showing the fact is provided and required by the expected rules
  • golden tests when the fact changes a tax calculation result
  • API compatibility tests when the fact appears in CalculatorRunRequest
  • SDK compatibility tests when SDK helpers accept the fact

Pull request evidence

Link the source citation for the fact, list the owning package, show the test commands you ran and explain compatibility impact in PR evidence checklist.