ubkds
v1.1.1
Published
UBKDS v1.1 canonical registry — taxonomy data, RID generation/parsing, validation, and TypeScript types for the Universal Business Knowledge Decimal System.
Maintainers
Readme
ubkds
The UBKDS v1.1 canonical registry as a zero-dependency npm package: taxonomy data, lookup helpers, RID generation/parsing, validation functions, and TypeScript types for the Universal Business Knowledge Decimal System.
Canonical standard: https://www.ubkds.org Package version
1.1.xmaps to UBKDS standard version v1.1.
Status: v1.1.1 — published on npm as
ubkds. A documentation/metadata patch over the v1.1.0 initial public release (no code or API changes). Licensed under CC-BY-ND-4.0. 234 tests passing.
Install
npm install ubkdsWorks in Node 18+, modern browsers, ESM, and CommonJS. Zero runtime dependencies. Tree-shakable.
// ESM / TypeScript
import { generateRID, isValidReference, getSubdomain } from 'ubkds';
// CommonJS
const { generateRID, isValidReference, getSubdomain } = require('ubkds');Quick start
import {
composeReference,
generateRID,
getSubdomain,
isValidReference,
parseReference,
} from 'ubkds';
// Generate a fresh RID for a new knowledge set
const rid = generateRID(); // "0A01"
// Build a full UBKDS reference
const ref = composeReference({
subdomain: 520, // Process Design, Workflow Standards and Execution Frameworks
function: 2, // Procedures and SOPs
rid,
});
// → "520.2.0A01"
// Round-trip
parseReference(ref);
// → { subdomain: 520, function: 2, rid: "0A01" }
// Validate strings from external sources
isValidReference('520.2.0A01'); // true
isValidReference('521.2.0A01'); // false (521 not canonical)
// Lookup canonical metadata
getSubdomain(520)?.name;
// → "Process Design, Workflow Standards and Execution Frameworks"What's in the package
UBKDS separates three independent concerns. This package provides the canonical data and rules for all three.
| Layer | Concern | Exports |
| ------------------ | --------------------------- | ---------------------------------------------- |
| Classification | What the knowledge is about | domains, subdomains, functions + lookups |
| Sensitivity | Who can access it | sensitivityLabels + scope rules |
| Lifecycle | What stage it's in | lifecycleStates, lifecycleTransitions |
The RID engine (generation, parsing, composition) and validators for every layer are also exported.
The mental model
Think of UBKDS the way you think of country codes (ISO 3166), language codes (ISO 639), or currency codes (ISO 4217) — but for business knowledge. This package is the official, machine-readable copy of that standard, so anyone building software can install it and have the canonical taxonomy at their fingertips with full type safety.
The value isn't in the code being clever — it's mostly lookups and regexes. The value is in one place carrying the canonical data, one way to validate it, and one version that ships through npm so every consumer stays current automatically as the standard evolves (v1.1 → v1.2 → v2.0).
What this package does NOT do
By design, this is a data + validation library, not a runtime governance system:
- Does not track artifact inventory — RID assignment, primary/secondary RID coordination across artifacts. That's the application layer.
- Does not implement role-based access control — it defines sensitivity rules; the application enforces them.
- Does not resolve scope dimensions against organization metadata (departments, roles, locations) — it validates structure; the application resolves identities.
- Does not drive lifecycle transitions automatically — review cadence surfaces artifacts for review; it does not mutate state.
These belong in a UBKDS-compliant application built on top of this package. See the Future packages section for adjacent capabilities planned as separate packages.
Use cases
Internal knowledge management app. A wiki or SOP repository where knowledge managers create artifacts, classify them with a UBKDS sub-domain + function, get a RID via generateRID(), and stamp the artifact's metadata with composeReference(...). Lifecycle transitions are gated by isValidLifecycleTransition(). Without this package, the team would hand-build the 100 sub-domains in TypeScript and drift away from the canonical source over time.
Document permissions automation. An IT team auto-provisions access to documents based on UBKDS sensitivity labels and scope dimensions. The package validates that the metadata is well-formed (isValidSensitivityLabel, isValidScopeDimensions); the team's own code resolves scopes against an HRIS feed and writes the access list to SharePoint, Google Drive, or wherever permissions live.
AI assistant grounding (RAG). Documents in a vector store are tagged with UBKDS references. When a user asks about incident response, the retrieval layer filters chunks to subdomain: 960 (Crisis Management) before semantic search, and the chatbot displays getSubdomain(960)?.name in citations. Sensitivity filtering keeps Controlled – Confidential chunks out of unauthorized responses.
CMS / DAM plugin. A vendor selling a "UBKDS Classifier" plugin for Sanity, Strapi, or Contentful imports domains, subdomains, functions and renders cascading dropdowns. Validates on save with isValidReference(). The vendor's marketing page reads "Compatible with UBKDS v1.1 (UBKDS.org)" — the exact attribution string the LICENSE requires.
API reference
Reference format
NNN.N.XXXX
│ │ │
│ │ └─ RID (4 chars from [A-Z 0-9])
│ └──── Functional subcode (0-9)
└─────── Sub-domain (000-990, multiples of 10)Taxonomy data
| Export | Type | Description |
| ---------------------- | --------------------------------------------------- | ---------------------------------- |
| domains | readonly UBKDSDomain[] | 10 primary domains (000–900) |
| subdomains | readonly UBKDSSubdomain[] | 100 sub-domains, 10 per primary |
| functions | readonly UBKDSFunction[] | 10 functional subcodes (.0–.9) |
| sensitivityLabels | readonly SensitivityLabel[] | 6 labels across 3 tiers |
| lifecycleStates | readonly LifecycleStateDefinition[] | 4 states |
| lifecycleTransitions | Record<LifecycleState, readonly LifecycleState[]> | Map of valid transitions |
All arrays are frozen at runtime and typed as readonly.
Lookup functions
| Function | Returns |
| ------------------------------------ | ------------------------------------------------------------- |
| getDomain(code) | UBKDSDomain \| undefined |
| getSubdomain(code) | UBKDSSubdomain \| undefined |
| getSubdomainsForDomain(domainCode) | readonly UBKDSSubdomain[] (empty array if domain not found) |
| getFunction(code) | UBKDSFunction \| undefined |
| getSensitivityLabel(label) | SensitivityLabel \| undefined |
RID engine
| Function | Description |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| generateRID(existingRIDs?: ReadonlySet<string>) | Random 4-char alphanumeric RID, never the reserved default '0000'. Pass an exclusion set to avoid collisions with RIDs you already use. |
| parseReference(ref: string) | Parses "520.2.0A01" → { subdomain, function, rid }. Throws on malformed input. |
| composeReference({ subdomain, function, rid }) | Composes parts → reference string. Throws on structurally invalid parts. |
RID scope — a named RID is global. A named (non-default) RID is a global identifier across the entire taxonomy, not a per-sub-domain one. The same named RID appearing under different sub-domains or functional subcodes denotes a single knowledge set that spans them — for example 520.2.A1B2 and 730.4.A1B2 both belong to knowledge set A1B2. The RID's 36⁴ = 1,679,616-value space is therefore one global namespace, not a separate space per sub-domain.
About DEFAULT_RID ('0000'): the default RID is the single exception to the rule above. It means "no explicit named knowledge set" — the ungrouped baseline. Default-RID artifacts are not joined into one global set; instead, artifacts that carry 0000 and share a sub-domain have only an implicit natural relationship within that sub-domain (500.2.0000 relates to other 500.*.0000 artifacts in sub-domain 500, but not to 700.*.0000). A unique named RID is assigned only when you want to formally name a knowledge set — especially one that crosses sub-domains. generateRID() never returns '0000' — it's reserved.
Validators
All validators accept unknown, return boolean, and never throw.
| Function | Description |
| -------------------------------------- | ------------------------------------------------------------------------ |
| isValidDomain(code) | code matches a canonical domain |
| isValidSubdomain(code) | code matches a canonical sub-domain |
| isValidFunction(code) | code is a canonical functional subcode (0–9) |
| isValidRID(rid) | 4-char string from [A-Z 0-9] |
| isValidReference(ref) | Structurally valid AND the subdomain + function exist in the taxonomy |
| isValidSensitivityLabel(label) | label matches one of the 6 canonical labels |
| isValidScopeDimensions(dims) | Valid scope structure: 1–3 dimensions, each non-empty, all string values |
| isValidLifecycleTransition(from, to) | from → to is in the canonical transition map |
Types
| Type | Shape |
| -------------------------- | ----------------------------------------------------------------------------------------------------- |
| UBKDSDomain | { code: number; name: string; definition: string } |
| UBKDSSubdomain | { code: number; domainCode: number; name: string; definition: string; examples: readonly string[] } |
| UBKDSFunction | { code: number; name: string; definition: string } |
| SensitivityLabel | { tier: SensitivityTier; label: string; description: string; requiresScope: boolean } |
| LifecycleStateDefinition | { state: LifecycleState; mutable: boolean; authoritative: boolean; description: string } |
| UBKDSReference | { subdomain: number; function: number; rid: string } |
| SensitivityTier | 'external' \| 'internal' \| 'controlled' |
| LifecycleState | 'draft' \| 'revision-minor' \| 'revision-major' \| 'published' |
| ReviewCadence | 6 \| 12 \| 24 |
Constants
| Constant | Value |
| ----------------------- | --------------------------------------------- |
| UBKDS_VERSION | '1.1' |
| DEFAULT_RID | '0000' (reserved; never randomly generated) |
| RID_CHARSET | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' |
| RID_LENGTH | 4 |
| MAX_SCOPE_DIMENSIONS | 3 |
| VALID_REVIEW_CADENCES | [6, 12, 24] (months) |
Lifecycle transitions
┌────────────────┐
draft ──────▶ │ published │ ──┬──▶ revision-minor ──┐
│ (authoritative)│ │ │
└────────────────┘ └──▶ revision-major ──┘
▲ │
└───────────────────────────────────┘Valid: draft → published, published ↔ revision-minor, published ↔ revision-major
Invalid: every transition not shown above, including any state to itself.
Scripts
| Script | Purpose |
| ----------------------- | -------------------------------------- |
| npm run build | Produce dual ESM/CJS output in dist/ |
| npm test | Run the test suite (234 tests) |
| npm run test:coverage | Run tests with v8 coverage |
| npm run typecheck | Type-check without emitting |
| npm run lint | Lint with ESLint |
| npm run format | Format with Prettier |
Future packages (planned)
This package is intentionally narrow — canonical data and validation, nothing else. Adjacent capabilities are planned as separate packages so each can have appropriate scope, licensing, and contribution model:
| Planned package | Purpose |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ubkds-seal | Official UBKDS seal visual assets (SVG, PNG, brand kit). Trademark-licensed separately from the data. |
| ubkds-templates | Notation block templates and artifact header generators (HTML, Markdown, PDF metadata, slide footers). Takes a UBKDSReference + sensitivity + lifecycle and produces formatted output. Permissively licensed. |
| ubkds-templates-contrib | Community-contributed templates curated against a quality bar. Templates are classified by their own UBKDS reference (a template for the .5 function in a given sub-domain — eating its own dog food). |
These will be released as the standard matures. This package will never gain UI, rendering, or visual-asset concerns — install one or more adjacent packages when you need those.
License
This package is licensed under CC-BY-ND-4.0 (Creative Commons Attribution-NoDerivatives 4.0 International).
You may use it — including in commercial applications — provided you:
- Acknowledge UBKDS.org as the canonical source (suggested attribution: "Compatible with UBKDS v1.1 (UBKDS.org)").
- Do not redistribute modified versions of the canonical taxonomy data while claiming UBKDS compatibility or canonical status.
"UBKDS" is a trademark of the UBKDS Stewardship Body. See LICENSE for full terms.
