-
Notifications
You must be signed in to change notification settings - Fork 1
MAP Type System (old)
The MAP Type System is designed to support a living, evolving agent-centric ecosystem — one in which all data structures are self-describing, composable, and extensible by agents.
This page introduces the MAP Type System by walking through the foundational concepts, built-in types, and extension mechanisms that power it.
BaseTypes are the foundational, portable types in the MAP system. The BaseType determines how a given value will actually be represented in different programming language environments. (i.e., TypeScript and JSON on the client and Rust on the server-side).
pub enum BaseType {
Holon,
Collection,
Property,
Relationship,
EnumVariant,
Value(ValueType),
ValueArray(ValueType),
}
The BaseTypes layer includes types (e.g., MapInteger, MapString) and compound types (e.g., MapBytes). It also includes types defined by the Holochain hdk (e.g., ActionHash, Record). The set of BaseTypes is fixed for any given version of the MAP. Changes or additions to any of these types requires a recompile of the MAP code and an evolution of the persistent data stored using a prior version of the MAP.
- Scalar Types: Simple, atomic values such as integers, strings, and booleans.
-
Non-Scalar Types: Includes
MapBytes, which is used to represent raw binary data, such as hash digests, commonly used as identifiers in the system.
#[derive(Clone, PartialEq, Eq, new)]
pub enum BaseType {
String(MapString), // Portable string type
Integer(MapInteger), // Portable integer type
Boolean(MapBoolean), // Portable boolean type
Bytes(MapBytes), // Portable binary type (e.g., hash digest)
Enum(MapEnumValue), // Portable enum value
}In the MAP every type — from simple scalar types like strings and booleans to rich structures like relationships and holons — is described by holons. In MAP, everything is a holon, including types themselves. Holons are linked by meaningful relationships, own structured values, and participate in shared schemas that define the logic of entire domains. At the core of this system is a type architecture that supports:
- ✅ Clear, consistent structure
- ✅ Runtime introspection and validation
- ✅ Agent-driven extension
- ✅ Shared semantics without central control
Each type descriptor is composed of:
- A
TypeHeaderholon — shared metadata for all types (e.g., name, label, description) - A type-specific holon — such as
PropertyType,HolonType,RelationshipType, etc.
Together, these elements make up what we informally call a type descriptor — the complete specification for a type in MAP.
These components are linked together and stored in a Schema, which is itself a holon and can be shared, versioned, and reused.
All types are ultimately grounded in a small, portable set of Base Types and Value Types. These are defined in the MAP’s Rust core and act as the low-level building blocks for everything else.
The BaseType enum defines the broad category a type belongs to:
enum BaseType {
Holon,
Collection,
Property,
Relationship,
EnumVariant,
Value(ValueType),
ValueArray(ValueType),
}This allows the MAP to reason generically about types, e.g., “this field holds an integer value” or “this link points to a collection of holons.”
-
ValueTypedefines the kind of a scalar value:String,Integer,Boolean, orEnum -
BaseValueholds actual instances of those values, wrapped in types likeMapString,MapInteger, etc.
These types are designed to be:
- Portable across platforms (e.g., serialized to JSON)
- Easy to validate and format
- Extensible through agent-defined constraints (see below)
MAP provides a consistent mechanism for defining new types, both in system code and at runtime.
Every BaseType (except ValueType) has a corresponding definer function, such as:
define_property_typedefine_relationship_typedefine_enum_typedefine_holon_type
Each definer accepts a corresponding <BaseTypeName>Spec struct containing the fields needed to define that type — like its name, required properties, relationships, or cardinality.
Each definer creates:
- A new
TypeHeaderholon - A
<BaseTypeName>Typeholon (e.g.,PropertyType,RelationshipType) - Optionally, a linked
ValueTypeholon
This pattern applies to both core MAP types and user-defined extensions.
MAP comes with a small set of core types baked into the system. These are the building blocks for modeling schemas and behaviors. Examples include:
-
HolonType— defines the structure and semantics of a class of holons (e.g.,BookType,PersonType) -
PropertyType— defines named fields on holons -
RelationshipType— defines uni-directional links between holons -
HolonCollectionType— defines structure of relationship targets -
SchemaType— a container for related types -
HolonSpaceType— defines boundaries of ownership and federation -
DanceType— defines actions holons can perform
Each core type is:
- A holon
- Defined with a TypeHeader + TypeDetails
- Stored in a core Schema
- Usable by agent-defined extensions
The MAP Type System is built for extensibility. Agents can define new types without recompiling the MAP core, and these types behave exactly like core types:
- A new
BookTypeholon might usePropertyTypes liketitle,published_date, andsummary - A
PersonTypecould be linked via aRelationshipTypelikeAUTHORED_BYorMEMBER_OF - A custom
EnumValueTypemight define options forstatusoraffiliation
Agent-defined types:
- Use the same definer pattern (
<BaseTypeName>Spec) - Are stored in Schemas owned by that agent’s HolonSpace
- May reference types from other Schemas (via
REFERENCElinks) - Are fully introspectable, validatable, and composable
Each MAP type is made up of three core elements:
| Component | Role |
|---|---|
TypeHeader |
Shared metadata and schema links |
<BaseTypeName>Type |
Type-specific constraints and fields |
ValueType (optional) |
Scalar validation and formatting rules |
These holons are connected via:
-
HAS_ASPECT→ links from the type to each of its components -
VALUE_TYPE_FOR→ links fromValueTypetoPropertyType -
PROPERTY_OF,SOURCE_FOR, etc. → define how types relate to one another
The MAP Type System:
- 📦 Is built from holons that represent types and relationships
- 🧱 Begins with a portable set of base types and values
- 🔧 Defines new types through consistent
define_<type>functions - 🧠 Expresses all types through self-describing holons
- 🌱 Allows any agent to define, share, and evolve their own schemas
- 🔗 Makes all aspects of type definition introspectable and queryable
In MAP, types are not just code — they are living data structures, versioned and governed like any other shared knowledge.
====================== PRIOR CONTENT =====================================
- CoreTypes build upon BaseTypes to introduce semantically meaningful types required by the MAP core code. Examples, include PropertyName, RelationshipName, HolonId.
- CoreTypes are defined in terms of BaseTypes to ensure portability and consistency.
- Examples include identifiers, names, and other semantically enriched types.
-
PropertyName: WrapsMapString, representing a property name. -
HolonId: Represents a unique identifier for a Holon. -
RelationshipName: WrapsMapString, representing the name of a relationship.
CoreTypes are organized into the following groups via the CoreType enum. Numbers in parentheses indicate the current number of core types within that group:
- DanceType (TBD)
- EnumVariantType (16)
- HolonType (24)
- IndexedType (2)
- PropertyType (24)
- RelationshipType (27)
- ValueType (8)
- DescriptorTypes define metadata and constraints for the values of a given type. Each BaseType has a corresponding DescriptorType. For example, IntegerDescriptorType defines the metadata about MapIntegers. This could include min and max allowable values for instances of that type, a human-readable name and description of the type and more.
- Each BaseType has a corresponding DescriptorType.
- DescriptorTypes can specify constraints like minimum/maximum values, length restrictions, or other rules.
-
IntegerDescriptorType: Specifies min/max constraints forMapInteger. -
StringDescriptorType: Specifies length constraints forMapString.
- CoreDescriptorTypes describe the types that the MAP core code depends on. are the reserved DescriptorTypes that the MAP core code depends on.
- Each BaseType can be associated with one or more CoreDescriptorTypes.
- CoreDescriptorTypes are critical to the functioning of the MAP and are not customizable by agents.
pub enum CoreStringDescriptorType {
#[default]
MapStringType,
PropertyNameType,
RelationshipNameType,
SemanticVersionType,
}ExtensionDescriptorTypes allow agents (developers) to define custom types dynamically without requiring recompilation of the MAP core. These types provide a flexible way for agents to extend the MAP Type System for their own applications, tailoring it to specific use cases.
-
Agent-Defined:
- ExtensionDescriptorTypes are created and managed by agents to support application-specific needs.
- They are not part of the MAP core and operate independently of core system upgrades.
-
Dynamic:
- Developers can add new types without recompiling the MAP core or migrating data structures.
-
Flexibility:
- These types allow agents to define rich metadata for custom types, including validation rules, relationships, and semantics.
-
Reserved Names:
- To avoid conflicts, agents cannot use reserved CoreDescriptorType names when defining their own types.