𧬠Starting Point: Types as Holons¶
In MAP, every type description is, itself, a holon.
This means that every type must:
- Be described by a TypeDescriptor
- Be owned by a HolonSpace
These aren't optional conventions β they are defining structural obligations of being a holon.
β Every type in MAP is a holon.
Therefore: every type must haveDescribedByandOwnedByrelationships.
Modeling MAP Value Types¶
π Example: MapStringValueType and PropertyNameValueType¶
Consider two value types:
MapStringValueType: A general-purpose string typePropertyNameValueType: A string type used specifically for property names
They both represent strings at the data level, but differ in usage and constraint.
Both are:
- Holons β Must be
DescribedByandOwnedBy - TypeDescriptors β Must be instances of
MetaValueType
So the following relationships apply:
MapStringValueType β[DescribedBy]β MetaValueType
PropertyNameValueType β[DescribedBy]β MetaValueType
At this point, we know these two holons are not just any holons β they are type descriptors used in the schema.
π§± Shared Constraints via Compositional Inheritance¶
Different value types require different constraints:
- Strings β min/max length, format, case convention
- Integers β min/max values
- Enums β allowed variants
- Bytes β fixed length, encoding
But many types share these constraints. For example:
MapStringValueType ββ
ββ[Extends]β StringValueConstraints
PropertyNameValueType ββ
In this pattern:
MapStringValueTypeandPropertyNameValueTypeare both holons and descriptors.StringValueConstraintsis just a constraint facet β it contributes properties likemin_length,max_length, orcase_convention.
Importantly:
StringValueConstraintsis not a type. Itβs not a descriptor.
It doesnβt have atype_name, doesnβt need to beDescribedBy, and doesnβt appear in any schema.
It just extends the value type itβs associated with, in a purely compositional way.
π§· Why Keys Matter¶
Semantic keys are foundational to the MAP architecture β not just for expressing relationships during import, but for enabling retrieval, referencing, and bootstrapping in a decentralized, descriptor-driven system.
They enable holons to be meaningfully identified and linked across the full lifecycle β from initial import to runtime introspection β even before they've been committed to the system or assigned a permanent ID.
π Staged Relationships Without IDs¶
In staged or import workflows, holons frequently reference other holons that havenβt yet been committed β and therefore lack a system-assigned ID (e.g., a Holochain ActionHash).
Keys solve this by allowing holons to be referenced using $ref: "key" rather than relying on fragile temporary identifiers or rigid load ordering.
β
Keys enable:
- Cross-file linkage between staged holons
- ID-free $ref expressions in JSON
- Relationship validation prior to commit
- Deduplication and merging of equivalent entries
π Example:
{
"type_name": "RelationshipType",
"key": "(PersonType)-[MentoredBy]->(PersonType)",
"relationships": [
{ "name": "SOURCE_FOR", "target": [{ "$ref": "PersonType" }] },
{ "name": "TARGET_FOR", "target": [{ "$ref": "PersonType" }] }
]
}
This relationship type can be referenced by other holons using its key, without requiring an ID to exist yet.
π§± Bootstrapping Descriptors Before Descriptor Logic Exists¶
Many MAP behaviors β including validation, inverse relationship population, and declarative key generation β depend on descriptors like PropertyType, RelationshipType, or HolonType.
But you canβt run logic that depends on descriptors until descriptors are present.
By requiring materialized key fields in the JSON of Keyed Holons, we can:
- Import descriptors without requiring key generation logic
- Reference them from other holons in the same import graph
- Stage and introspect schemas and data prior to persistence
This makes it possible to: - Import the MAP Meta-Schema - Import domain-specific schema extensions - Import valid data instances ...all in a single, unified process.
π Associative Retrieval in Distributed Systems¶
In distributed architectures like Holochain, data is stored in Distributed Hash Tables (DHTs) β meaning:
- You cannot βquery the whole databaseβ as you would in a centralized store
- You typically need a known hash or path to locate content efficiently
Materialized keys provide the critical link between semantic meaning and retrieval paths:
β They support:
- Associative lookup: finding content based on associated properties (e.g., type, relationship role)
- Path-based indexing: storing holons under DHT paths that reflect their keys (e.g.,
path!(("HolonType", key))) - Declarative retrieval APIs: enabling callers to say βget me the [MentoredBy] relationshipβ without knowing its ID
Without keys:
- Content is only retrievable via opaque identifiers
- Queries become tightly coupled to global indexes or full scans (inefficient or unavailable in DHTs)
- Schema introspection and semantic queries are significantly harder
π§ Summary¶
Keys are not just syntactic sugar β they are critical infrastructure for:
- Declarative, schema-linked imports
- ID-free reference resolution across files
- Bootstrapping descriptors before runtime logic is available
- Efficient, semantic-based retrieval in distributed systems
- Federated schema evolution and shared introspection
By embracing materialized, semantically meaningful keys, MAP achieves a powerful combination of:
- Structural clarity
- Introspectable relationships
- Decentralized operability
- Self-hosted schema evolution
This makes keys one of the most essential capabilities in the MAP Type System.
π Layered Inheritance: The Value Type Stack¶
MetaValueType β[Describes]β MapStringValueType β[Extends]β StringValueConstraints
This gives us three clear layers:
- Meta Descriptor Level β defines what a value type must contain
- Descriptor Level β a value type like
MapStringValueTypeorPropertyNameValueType - Constraint Layer β reusable modular constraints via
Extends
| Layer | Holon | Purpose |
|---|---|---|
| Meta | MetaValueType |
Describes value type descriptors |
| Type | MapStringValueType |
Actual TypeDescriptor |
| Constraint | StringValueConstraints |
Adds constraint properties |
π Pattern Repeats for All Primitive Types¶
Hereβs the same pattern across other type kinds:
| ValueType | DescribedBy | ExtendedBy | Constraints Provided |
|---|---|---|---|
MapStringValueType |
MetaValueType |
StringValueConstraints |
min_length, max_length, etc. |
PropertyNameValueType |
MetaValueType |
StringValueConstraints |
Custom limits, case_convention |
MapIntegerValueType |
MetaValueType |
IntegerValueConstraints |
min_value, max_value |
MapBytesValueType |
MetaValueType |
BytesValueConstraints |
length, encoding, format_hint |
MapEnumValueType |
MetaValueType |
EnumValueConstraints |
Variants relationship |
MapBooleanValueType |
MetaValueType |
(none needed) | (no constraints required) |
π§© Are Meta Types Holons Too?¶
Yes β and this is where the architectural recursion becomes elegant.
Just as MapStringValueType is a holon and needs to be DescribedBy, so too does MetaValueType.
Letβs follow the thread:
MetaValueType β[DescribedBy]β MetaTypeDescriptor
MetaIntegerValueType β[DescribedBy]β MetaValueType
So:
π Meta types themselves are holons
π They need to be described
π They participate in the same system they define
π Recursion Meets Structure: MetaTypeDescriptor Extends MetaHolonType¶
To avoid repeating the structural obligations of all holons (like needing DescribedBy and OwnedBy) across every Meta typeβ¦
We simply declare:
MetaTypeDescriptor β[Extends]β MetaHolonType
Now, every Meta type (like MetaValueType, MetaPropertyType, etc.) that is an instance of MetaTypeDescriptor inherits from MetaHolonType, which defines the baseline expectations for all holon types.
β Every Meta type becomes both a type descriptor and a holon
β DRY design:MetaHolonTypecaptures shared structural rules
β Recursive closure: the system defines itself in clean, layered cycles
π§ Summary of the Pattern¶
| Concept | Relationship | Notes |
|---|---|---|
| ValueType | DescribedBy β MetaValueType |
Marks as a valid type holon |
| ValueType | Extends β ValueConstraints |
Adds constraints modularly |
| MetaValueType | DescribedBy β MetaTypeDescriptor |
Makes it a descriptor of type descriptors |
| MetaValueType | Extends β MetaHolonType |
Inherits holon-level expectations |
| Constraints (e.g. StringValueConstraints) | (no type) | Purely compositional constraint layer |
π§° Bonus: How You Might Use This in Validation or Import¶
When validating a PropertyType that refers to a ValueType:
- Confirm the target is a holon
- Confirm itβs
DescribedByMetaValueType - Confirm it satisfies the constraints from any
Extendsfacets
This lets you:
- Reuse constraints
- Compose constraint types
- Keep descriptors clean and minimal
- Keep validation DRY and generalizable