Staging — blog preview only.
Skip to content

Compose domains from one type system

Scheduled

5 min read By NT²

A medical pack and an IT pack should not each reinvent “expiry date.” Domains grow by composing a shared semantic catalog into category templates—then enabling the packs you need.

Compose domains from one type system

Claim: domains scale by composition

Semantic columns, not form widgets put meaning in a global field registry. This essay is about growth: how NT² Vault serves many domains without forking the product into vertical apps.

The claim: new domains are composed, not invented from scratch. Field packs contribute vocabulary. Category templates arrange that vocabulary into schemas. Optional packs are enabled per vault. Row-level features—expiry, password health, share defaults—follow the active field set on an item, not a permanent if (category === "bank") switchboard.

That is why one local-first, zero-knowledge vault can hold credentials today and grow into documents, bank details, SSH keys, and medical cards without becoming a blank page or a monolith of special cases.

The constraint: slug gates explode

The naïve way to ship verticals is category branching:

if category == credential → password UI
if category == bank → IBAN UI
if category == document → expiry cron

It feels clear on day one. It fails as the catalog grows.

Packs multiply. IT alone may include API services, servers, SSH keys, VPN profiles, and certificates. Medical adds cards, providers, prescriptions. Financial adds tax documents and subscriptions. Every feature that keys only on slug needs another branch—or silently does nothing for the new pack.

Per-item extras break the illusion. A single document item may need an extra phone field for this year’s renewal. If features only understand “document template as shipped,” sparse extras are invisible to reminders, search, and share masks.

Parallel type universes appear. Each vertical team ships its own “date,” “id number,” and “secret” under private names. You lose the registry leverage the previous essay argued for.

Micro-apps look like an escape hatch. Sandboxed UI bundles are a real product surface for specialized tools. They are the wrong registration path for field types. If understanding a schema requires loading an iframe app, the vault core no longer owns the document model.

NT²’s constraint: category labels organize collections; they must not be the only way features discover meaning.

The design: packs, templates, active fields

Field packs = vocabulary

Field packs are versioned sets of semantic type definitions. A core pack covers everyday secrets and notes. Domain packs add specialized vocabulary—financial identifiers, infrastructure fields, medical card fields—while reusing shared types like dates and secrets wherever possible.

Packs are data. They merge into one registry. They do not each ship a private runtime for “what is a date?”

Category templates = schemas

A category template picks an ordered list of field types, labels, and placement options (required, share defaults, display hints). Official packs ship ready-made templates: credential and note as core builtins; bank, document, crypto, IT, medical, retail, and others as optional enablements.

Enabling a pack is closer to installing a schema pack than installing a new product. The vault stays one app. The collection list grows.

L0 / L1 / L2 without new types

Customization has tiers, still inside the registry:

TierWhat it is
L0Bundled / official templates—curated defaults
L1Custom templates that rearrange existing field types
L2Sparse per-item extra fields, still registry types only

L2 is how one row gains an extra contact field without inventing a new category or a new field type. The active field set for that row is template placements union L2 extras.

Features read the active field set

flowchart TB
  Packs[Field packs] --> Reg[Merged registry]
  Reg --> Tpl[Category template]
  Tpl --> Active[Active field set]
  L2[Per-item extras] --> Active
  Active --> Edit[Edit form]
  Active --> View[View chrome]
  Active --> Present[Present / share masks]
  Active --> Feat[Expiry, health, recipes]

Expiry reminders care that an expiryDate (or equivalent semantic) is present and populated—not that the slug string equals document. Password health cares that a password-shaped field exists on the row—even if the category is an API service template rather than classic credential. Share and present flows read placement and type defaults from the same set.

Recipes (multi-field fingerprints) compose the same way: “enough bank fields to treat this as a bank summary” is a field-set question, not a slug question.

Sync and backup stay blind to domains

Category slugs and sealed payloads sync as data. The edge does not need a medical ontology. Composition stays a client concern; zero-knowledge stays an edge concern. That split is load-bearing.

The trade-off: enable packs, do not ship vertical apps

Composition asks users (and product) to enable the domains they need. A brand-new vault is not preloaded with every industry template. Authors must reuse types instead of minting lookalikes.

What you avoid is worse: an app store of mini-vaults, each with its own export format, or a single codebase drowning in category switches.

CompositionVertical fork
One vault UIMany niche apps
Shared field meaningPrivate schemas per vertical
Features follow fieldsFeatures follow slug tables
Optional packsPermanent special cases

What we refuse

We refuse category slug as the long-term feature gate. Slugs organize lists and defaults. They are not a substitute for reading the active field set.

We refuse micro-apps as the field-registration path. Specialized UI may appear in a sandbox; semantic types still enter through the registry and template packs.

We refuse a new app per vertical. Bank, document, and SSH key are packs and templates—not separate products with separate trust stories.

We refuse growing domains by forking “password” into five private secrets. Reuse the catalog; extend it deliberately when a true new concept appears.

One catalog, many collections

Household stories on this blog talk about structure as relief: The spreadsheet on my Desktop and Already local-first, missing structure. Composition is the engineering reason that relief can span domains without turning the vault into Notion.

Next: Searchable metadata, sealed field values— how list/search stay useful while sensitive columns leave RAM as sealed indices. Then Four surfaces, one field set closes the series’ first arc.

For portable ciphertext around those fields, see CBF is how structured fields leave RAM. Try NT² Vault or read nt2.me.

Last updated 2026-11-22

Related stories