Context
0134 classifies every field as one of six classes and derives the handling from the class. A legal product holds attorney-client material, a medical product holds clinical notes, and neither fitspii, secret or regulated: the data is often not personal, it is privileged, and the
handling it needs is specific (no AI audience unless the tenant allows it, never visible under support access, no
search snippet outside the team, exported only with its label). The owner locked the legal product’s plan on
2026-10-24 with this need. A closed set that only Stackra can extend would make every such product wait for a
framework release.
Decision
-
A product may declare a class. A product declares a data class in the
access/group of the module whose fields carry it (several modules may each declare their own), in a<name>.data-class.tsfile, as a class that extendsDataClass({ key })(0294 decision 13 as amended the same day), with the four effects below as typed options.DataClass, the four effects and the@Classifyunion live in@stackra/model, the package that owns@Classify; gen adds each declared class to that union for its product, so a field can carry it like a built-in class. A class is a framework-level concept with a product-level instance; a tenant never declares one. -
The effects a class sets. Each class states, for its fields:
ai(never,tenantOptInorallowed: whether the fields may enter an agent’s context, 0245),support(hiddenorvisibleunder support access),search(noSnippetoutside the record’s own team, orsnippet), andexport(labelled: every export carries the class label beside the value). The built-in classes of 0134 keep their handling; their values in these four effects are set in the change that shipsDataClass, andsupportis a new effect that then applies to every class. -
privilegedis a built-in class. Stackra shipsprivilegedbeside the six classes of 0134:ai: tenantOptIn,support: hidden,search: noSnippet,export: labelled. A legal or medical product uses it without declaring its own; a product that needs a finer class declares one. - The handling is derived, as in 0134. The AI context builder, support access, the search indexer and the export writer read the class and apply its effects. No product writes a check for a class by hand.
- Classes travel with the data. An export, an integration event and an archive carry the class of each field, so a consumer applies the same effects. A class name is a machine code, snake_case (0231).
Consequences
- A product adds a class in its own code and gets the handling everywhere a class is read, without a framework release.
privilegedexists once, with one meaning, for every product that holds protected professional material.- An agent sees privileged data only when the tenant turned it on, and a support engineer never does.
Enforcement
- planned — gen (STA-340): a
@Classifyvalue outside the built-in set and the product’s declared classes fails; a declared class missing one of the four effects fails. - planned — tests in the AI context builder, support access, the search indexer and the export writer, each against a fixture field of every class, built-in and declared.