1. Why Business Data Types
Primitive types (str, int, float) tell the machine what bytes to allocate. Business Data Types tell the system what the value means and how it behaves:
| Primitive |
BDT Example 1 |
BDT Example 2 |
Difference |
str (date) |
DATE_ONLY (Date of Birth) |
ISO_DATETIME (Last Operation) |
Birth date is IMMUTABLE_IDENTITY (write-once, permanent). Last operation is OPERATIONAL_EVENT (high-velocity, overwritten). |
float |
PLN_AMOUNT |
KW_POWER |
Both are floats, but PLN_AMOUNT carries unit=PLN, min=0, max=10M. KW_POWER carries unit=kW, min=0, no upper bound. |
float |
SCORE_0_100 |
PERCENTAGE |
Same range (0-100), but Score is DERIVED_METRIC (recomputable), Percentage may be REFERENCE_CONSTANT (fixed). |
str |
USEME_JOB_ID |
POLICY_VERSION |
Both are strings with patterns, but Job ID is IMMUTABLE_IDENTITY, Policy Version is REFERENCE_CONSTANT (changes with releases). |
2. BDT Structure
Every BDT carries:
| Field |
Type |
Purpose |
name |
string |
Unique type identifier (SCREAMING_SNAKE in code, PascalCase in registry) |
python_type |
type |
Runtime type for isinstance checks (float, int, str) |
description |
string |
Domain meaning -- what this value represents in business context |
lifecycle |
LifecycleClass |
How this value changes over time (governs mutability, retention, audit) |
numeric |
NumericConstraints |
min_value, max_value, integer_only, positive_only |
string |
StringConstraints |
max_length, min_length, pattern (regex), allowed_values (enum) |
unit |
string or null |
SI / currency / measurement unit (PLN, USD, kW, MW, %, points) |
nullable |
boolean |
Whether None/null is a valid value |
3. Lifecycle Classes
| Class |
Code |
Mutability |
Audit |
Cache |
Example |
| IMMUTABLE_IDENTITY |
LC-1 |
Write-once, permanent |
Full |
Eternal |
Date of birth, Job ID, Tag format |
| MUTABLE_STATE |
LC-2 |
Event-driven change |
Full |
Short |
Account balance, Entity status |
| OPERATIONAL_EVENT |
LC-3 |
High-velocity timestamp |
Append |
None |
Last login, Latest operation time |
| DERIVED_METRIC |
LC-4 |
Recomputable from inputs |
Provenance |
Medium |
Scores, totals, KPIs |
| REFERENCE_CONSTANT |
LC-5 |
Version-pinned, policy-controlled |
Version log |
Long |
Weights, thresholds, PUE values |
3.1 Lifecycle Enforcement Rules
| Operation |
LC-1 |
LC-2 |
LC-3 |
LC-4 |
LC-5 |
| Create |
Yes |
Yes |
Yes |
Yes (auto) |
Yes (admin) |
| Read |
Yes |
Yes |
Yes |
Yes |
Yes |
| Update |
BLOCKED |
Yes (with audit) |
Yes (append) |
Yes (recompute) |
Yes (version bump) |
| Delete |
BLOCKED |
Soft delete only |
Archive after TTL |
Recomputable |
BLOCKED |
4. Complete Type Registry
4.1 Monetary Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| PLN_Amount |
PLN |
MUTABLE_STATE |
min=0, max=10,000,000 |
Polish Zloty monetary amount |
| USD_Amount |
USD |
MUTABLE_STATE |
min=0, max=1,000,000,000 |
US Dollar monetary amount |
4.2 Score and Metric Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| Score_0_100 |
% |
DERIVED_METRIC |
min=0, max=100 |
Normalised quality/opportunity score |
| Percentage |
% |
DERIVED_METRIC |
min=0, max=100 |
General-purpose percentage |
| Weight_0_1 |
-- |
REFERENCE_CONSTANT |
min=0, max=1 |
Normalised weight (must sum to 1.0 in group) |
4.3 Enumeration Types
| BDT Name |
Unit |
Lifecycle |
Allowed Values |
Description |
| FreelanceTier |
-- |
DERIVED_METRIC |
S++, S, A+, B, C, D |
Job opportunity tier |
| PersonaID |
-- |
DERIVED_METRIC |
darek, robert |
Assigned persona specialist |
| BidAction |
-- |
DERIVED_METRIC |
BID, CONSIDER, SKIP |
Recommended bidding action |
| BudgetType |
-- |
MUTABLE_STATE |
fixed, hourly, negotiable, unknown |
Client budget definition type |
| FlagSeverity |
-- |
REFERENCE_CONSTANT |
critical, high, medium, low |
Red flag severity level |
| FlagAction |
-- |
REFERENCE_CONSTANT |
auto_reject, beatrice_review, log_only |
Red flag response action |
| CoolingTechnology |
-- |
IMMUTABLE_IDENTITY |
traditional, rdhx, dlc, grc |
Data centre cooling technology |
4.4 Count Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| OfferCount |
-- |
OPERATIONAL_EVENT |
min=0, max=10,000, integer |
Competing offers on a posting |
| ContractCount |
-- |
MUTABLE_STATE |
min=0, integer |
Client completed contracts |
| WordCount |
-- |
DERIVED_METRIC |
min=0, integer |
Text field word count |
4.5 Identifier Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| UsemeJobID |
-- |
IMMUTABLE_IDENTITY |
len 1-64 |
Unique job identifier from platform |
| PolicyVersion |
-- |
REFERENCE_CONSTANT |
pattern: ^\d+\.\d+\.\d+$ |
Semantic version string |
4.6 Engineering Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| MW_Power |
MW |
REFERENCE_CONSTANT |
min=0, max=1000 |
Megawatt power rating |
| KW_Power |
kW |
MUTABLE_STATE |
min=0 |
Kilowatt power measurement |
| PUE |
-- |
REFERENCE_CONSTANT |
min=1.0, max=3.0 |
Power Usage Effectiveness ratio |
4.7 Temporal Types
| BDT Name |
Unit |
Lifecycle |
Constraints |
Description |
| ISO_DateTime |
-- |
OPERATIONAL_EVENT |
pattern: ISO 8601 |
High-velocity timestamp (last login, latest op) |
| DateOnly |
-- |
IMMUTABLE_IDENTITY |
pattern: YYYY-MM-DD |
Calendar date (birth, registration, founding) |
5. BDT in Practice
5.1 Field Declaration Example
{
"field_type_map": {
"worker.date_of_birth": "DateOnly",
"worker.last_medical_check": "ISO_DateTime",
"worker.salary": "USD_Amount",
"worker.compliance_score": "Score_0_100",
"worker.visa_type": "CoolingTechnology"
}
}
The validator enforces:
date_of_birth cannot be updated (IMMUTABLE_IDENTITY)
last_medical_check is freely updated (OPERATIONAL_EVENT)
salary must be >= 0 and <= 1,000,000,000 (USD_Amount constraints)
compliance_score must be 0-100 (Score_0_100 constraints)
5.2 Entity Class Field Mapping
Every entity class field MUST map to a registered BDT. No field may use a raw primitive type without BDT assignment. The DataValidator rejects fields without BDT mapping.
6. Adding New BDTs
New BDTs are added to wormwood/core/business_data_types.py following this process:
- Define the
BusinessDataType constant with all fields
- Add to
TYPE_REGISTRY dict
- Add entry to this document (Section 4)
- Map fields using the new BDT in
data_lifecycle_policy.json
- Run
test_business_data_types_and_validator.py
- Update BDT-1.0 version if adding a new category
7. Version History
| Version |
Date |
Changes |
| BDT-1.0 |
2026-05-02 |
Initial registry: 21 types across 7 categories, 5 lifecycle classes. |