MAP Graph Query Engine v1.1¶
Changelog¶
v1.1¶
- sharpens the seam between
Command,Dance, andQuery - treats query execution as a
QueryDance, invoked throughDanceInvocation - makes the
QueryDanceRequesta fixed-shape holon rather than a projection-shaped payload - makes
QueryGraphthe symbolic query plan andExecutionInstancethe runtime execution state - makes
HolonCollectionthe primary runtime query operand and result substrate - simplifies
QueryStepso normal step input flows throughStepDependsOn - reserves explicit input binding use for root steps through
UsesInitialBinding - replaces string-expression placeholders for filter and ordering with structural rule holons
- replaces free-form projection-expression placeholders with
PropertyNameList - incorporates the distributed retrieval model from
dist-query-concept.md - aligns the design more closely with
query-algebra-design-spec.md - folds in the remaining algebra-spec invariants around descriptor-governed semantics, relationship normalization, projection boundaries, and non-foundational result views
- adds a companion Rust wrapper-layer design grounded in typed holon wrappers
v1.0¶
- framed the graph query engine primarily as a coarse-grained dancer executing a
QueryGraph - treated step input/output binding structure more generically
- allowed broader result-shape drift away from the
HolonCollection -> Operation -> HolonCollectionalgebra
Purpose¶
This document is the v1.1 design-spec narrative for MAP's graph query engine.
It captures the intended architecture of query execution in MAP, using the authoritative schema names currently grounded in the generated core-schema and the intended semantics grounded in the query algebra design.
The companion precise schema artifact is:
That DSL is the precise type-and-relationship companion to this narrative spec. This document is the more readable architectural explanation.
The distributed-retrieval concept note that informs the distributed execution section is:
That concept document is exploratory and forward-looking. It is the current home where fuller multi-space query-execution design is being worked through. This v1.1 spec remains focused on the stable query-model seam needed for Commands, Dances, and near-term single-space query execution.
Core Position¶
The key design rule is:
Command = ingress envelope and lifecycle policy.
Dance = descriptor-afforded executable behavior.
Query = request payload supplied to a Query Dance.
This is the seam that v1.1 is meant to sharpen.
A query is not itself a command.
A query is not itself a dance.
A query is the structured payload carried by a query dance invocation.
Query Engine as Dance¶
MAP provides graph query execution as a dance.
That means the graph query engine is not modeled as a standalone, magical
runtime subsystem floating outside MAP's normal type-and-affordance model. It is
modeled as a concrete dance implementation of a QueryDance.
In the general dance model, any holon instance may serve as the affording holon
for a DanceInvocation, so long as that instance's type affords the dance
being invoked.
Conceptually:
SomeHolonType
Affords -> QueryDance.DanceType
QueryDance.DanceType
HasImplementation -> GraphQueryEngine.DanceImplementation
This preserves MAP's extensibility requirement. Different spaces may eventually afford different query dances or different implementations with different optimizers, capabilities, and execution strategies.
In the current distributed query design, HolonSpace is the ordinary affording
holon for query execution. That is an important deployment convention, but it
should not be encoded as a narrowing of the base DanceInvocation schema.
Canonical Execution Path¶
The canonical v1.1 execution path is:
Transaction.HolonType
AffordsCommand -> Dance.CommandType
Dance.CommandType
payload -> DanceInvocation.HolonType
DanceInvocation.HolonType
InvokesDance -> QueryDance.DanceType
AffordingHolon -> HolonType
Request -> QueryDanceRequest.HolonType
QueryDanceRequest.HolonType
QueryGraph -> QueryGraph.HolonType
InitialBindings -> ExecutionBinding.HolonType
ExecutionInstance.HolonType
ExecutesRequest -> QueryDanceRequest.HolonType
ExecutionBindings -> ExecutionBinding.HolonType
ExecutionResult -> HolonCollection.HolonType
QueryDanceResponse.DanceResponseType
ResponseBody -> HolonCollection.HolonType
Narratively, this means:
- the command layer gets the request into the system
- the dance layer identifies the executable behavior being invoked
- the affording holon must be an instance whose type affords that dance
- the query layer provides the symbolic plan plus named starting bindings
- the execution layer creates a run-specific
ExecutionInstance - the runtime result is a
HolonCollection
Vocabulary¶
The important v1.1 terms are:
Dance.CommandType: the command surface for dance executionDanceInvocation.HolonType: the typed invocation holon carried as the dance command payloadAffordingHolon: the holon affording the dance, not merely a "target"; the referenced instance must afford the dance named byInvokesDanceQueryDance.DanceType: the concrete dance type for query executionQueryDanceRequest.HolonType: the fixed-shape request holon for query executionQueryGraph.HolonType: the symbolic query planQueryStep.HolonType: an operation node in that planQueryBinding.HolonType: a symbolic variable name used by the planExecutionBinding.HolonType: a runtime binding from query variable toHolonCollectionExecutionInstance.HolonType: one ephemeral execution run of one requestQueryDanceResponse.DanceResponseType: the dance response carrying the final result collection
Query Architecture Overview¶
The externally visible query affordance is no longer best described as a bare:
GraphQueryEngine(QueryGraphReference) -> QueryResultReference
That old framing was too coarse and hid the important seam between command, dance, request, plan, and execution state.
The v1.1 architecture should instead be understood as:
Dance.CommandType
payload -> DanceInvocation
DanceInvocation
invokes -> QueryDance
request -> QueryDanceRequest
QueryDanceRequest
query_graph -> QueryGraph
initial_bindings -> ExecutionBinding*
QueryDance
response -> QueryDanceResponse
QueryDanceResponse
response_body -> HolonCollection
The query language evolves through QueryGraph, QueryStep, QueryStepKind,
parameter projections, and rule holons. It does not evolve by proliferating
algebra-specific dances.
QueryGraph¶
A QueryGraph is the symbolic query plan.
It is the reusable, saveable, replayable MAP artifact that describes what the query means without carrying any live execution state.
In v1.1 it owns:
- human-facing identity through
QueryNameandQueryDescription - the query's
QuerySteps - the query's declared external input names
- the query's declared exported result name
Through its QuerySteps and dependency relationships, a QueryGraph also owns
the symbolic execution topology, operation parameters, relationship traversal
provenance, and explanation topology for the query.
Conceptually:
QueryGraph
QuerySteps -> QueryStep*
DeclaredInputBindings -> QueryBinding*
DeclaredResultBinding -> QueryBinding
DeclaredInputBindings¶
DeclaredInputBindings defines the query's external input contract.
These are symbolic binding names that the plan is allowed to expect from a caller. They are not runtime collections themselves. They are just the names the plan is written against.
For example, a graph may declare that it expects a binding named books or
starting_spaces. The actual runtime values for those names arrive through
QueryDanceRequest.InitialBindings.
So:
DeclaredInputBindingslives on the symbolic planInitialBindingslives on the concrete requestExecutionBindingslives on the runtime execution instance
DeclaredResultBinding¶
DeclaredResultBinding defines the query's exported output contract.
A query may produce several intermediate named bindings internally, but exactly one symbolic binding is designated as the graph's externally meaningful result.
That is the binding whose runtime HolonCollection should be treated as the
result of the query when execution completes.
So, in plain terms:
DeclaredInputBindings= the named inputs the query acceptsDeclaredResultBinding= the named output the query promisesQuerySteps= the transformations in between
QueryDanceRequest¶
QueryDanceRequest is the fixed-shape input contract for query execution.
It contains:
QueryGraph -> QueryGraph.HolonTypeInitialBindings -> ExecutionBinding.HolonType
This keeps the request explicit:
- what symbolic plan is being executed
- what named runtime collections the plan starts from
The request is intentionally simple. It does not carry runtime execution state.
ExecutionInstance¶
ExecutionInstance represents one execution run of one QueryDanceRequest.
It is an ephemeral runtime holon, not a reusable query-plan artifact.
It owns:
- the request it is executing
- the live runtime bindings for that execution
- execution status
- the final result collection
Conceptually:
ExecutionInstance
ExecutesRequest -> QueryDanceRequest
ExecutionBindings -> ExecutionBinding*
ExecutionResult -> HolonCollection?
This separation matters because the same QueryGraph may be executed multiple
times with different initial bindings, different scopes, or concurrently, and
none of that should contaminate the symbolic plan.
HolonCollection as Query Substrate¶
HolonCollection is the primary runtime operand and result substrate for query
execution.
The core algebraic bias remains:
HolonCollection -> Operation -> HolonCollection
This is one of the key simplifications restored in v1.1.
Even projection-producing steps remain collection-oriented at the runtime
substrate level. A Project step produces a HolonCollection of projection
references rather than leaving the collection substrate entirely.
A HolonCollection contains holon references and collection semantics. It does
not contain variable bindings, relationship provenance, execution provenance, or
query-plan metadata. Those belong to QueryGraph, QueryStep, and
ExecutionInstance.
HolonReference preserves holon identity and may defer state access. Callers may
read through the reference surface exposed by MAP's holon APIs, but deferred
materialization does not change the query substrate: operations still consume
and produce collections of references.
The core query engine must not introduce foundational runtime carriers such as
RowSet, Expansion, RelationshipMap, or GraphValue in order to execute
ordinary navigation. Concrete row-like, path-like, graph-like, or scalar result
surfaces may be materialized at explicit boundaries when a caller or
compatibility surface requires them.
QueryStep¶
A QueryStep is an operation node in a QueryGraph.
The v1.1 QueryStep model is intentionally smaller and more chain-oriented than
the v1.0 draft.
Each step identifies:
- its operation kind
- its operation parameters
- its predecessor steps
- optionally, a request-supplied initial binding for root steps
- optionally, a symbolic output binding name
Conceptually:
QueryStep
StepKind -> QueryStepKind
StepParameters -> Projection?
StepDependsOn -> QueryStep*
UsesInitialBinding -> QueryBinding?
StepOutputBinding -> QueryBinding?
StepDependsOn¶
StepDependsOn is the normal structural flow mechanism.
Non-root steps consume the output of predecessor steps through dependency relationships. That means the common step-to-step execution chain does not need a generic explicit input-binding field on every step.
UsesInitialBinding¶
UsesInitialBinding exists only so a root step can explicitly name which
request-supplied starting binding it consumes.
This keeps explicit binding references where they are needed, without forcing every step in the graph to carry them.
StepOutputBinding¶
StepOutputBinding is optional.
Not every intermediate step result needs a stable symbolic name. A step may simply feed successor steps structurally through the dependency chain. A named binding becomes useful when a result needs to be:
- designated as the final query result
- reused by more than one successor
- inspected or explained
- referenced externally
Relationship names, operation identities, and traversal provenance belong to the
step that performs the work. They are not embedded into the HolonCollection
produced by the step.
QueryStepKind¶
QueryStepKind remains an abstract holon type describing a family of query-step
operations.
In v1.1 its common semantic contract is deliberately small:
StepInputType -> HolonCollection.HolonTypeStepResultType -> HolonCollection.HolonTypeStepParameterType -> Projection.HolonType?
This matches the initial algebra more closely than the earlier, driftier design.
Descriptor-Owned Semantics¶
Descriptors are the semantic source for query validation and interpretation.
The query engine should use descriptor-backed structure to validate relationship traversal, property access, projection property names, and operation applicability. It should use descriptor-backed value and operator semantics to interpret filter and ordering rules.
This keeps query execution aligned with MAP's type-and-affordance model:
- holon types define the available structural surface
- relationship descriptors define legal traversal channels and inverse names
- property and value descriptors define what may be projected, compared, sorted, or filtered
- step kinds define the executable operation contract
The query engine is therefore descriptor-governed graph navigation over MAP
holons, not a separate property-graph database runtime hidden inside
holons_core.
Initial Operation Set¶
The v1.1 initial step kinds are:
SeedHolonsQueryStepTypeExpandQueryStepTypeFilterQueryStepTypeOrderByQueryStepTypeSkipQueryStepTypeLimitQueryStepTypeDistinctQueryStepTypeProjectQueryStepType
This is intentionally close to the initial operation set from
query-algebra-design-spec.md.
Parameter Modeling¶
The parameter side of the design is also narrower and more structural in v1.1.
Expand¶
ExpandParameters carries a RelationshipName property.
Expand consumes a HolonCollection, follows a named MAP relationship channel,
and produces a target HolonCollection.
MAP relationships are named traversal channels, not foundational property-bearing edge instances. Each semantic relationship has:
- a declared relationship name
- an inverse relationship name
- a declared source endpoint type
- a declared target endpoint type
Those names and endpoint roles describe one semantic relationship pair, not two separate edge kinds.
For example, for a semantic relationship:
(A)-[R]->(B)
with inverse name Rinv, a declarative surface may express the same semantic
relationship through equivalent surface forms such as:
(A)-[R]->(B)
(A)<-[Rinv]-(B)
(B)-[Rinv]->(A)
(B)<-[R]-(A)
The executable query step should normalize that surface intent onto the one semantic relationship pair before execution. Validation must not be reduced to a naive check that the requested relationship name is directly declared on the current source type.
In the current v1.1 schema, the narrow ExpandParameters shape carries
RelationshipName. Declarative authoring surfaces that distinguish traversal
direction must compile that direction into the chosen declared or inverse
relationship name, or into a future structural direction field if the schema is
extended. Either way, execution-time validation must determine:
- which semantic relationship pair the requested name refers to
- whether the current source holon type is a legal endpoint for the traversal
- whether the requested surface intent is compatible with the declared/inverse relationship semantics
If the traversal is legal but there are no matching runtime targets, Expand
returns an empty HolonCollection.
If no legal normalization exists for the requested relationship name, source
type, and traversal intent, Expand returns a validation error rather than an
empty collection.
If relationship-specific state is needed, MAP should model that state using
holons, typically through an intersection HolonType, rather than treating
relationships themselves as property-bearing runtime edges. Manually ordered
collections may keep sequence information as collection-organization metadata,
but that does not make relationship state a general schema-level edge payload.
ExpandAll, if introduced by an authoring surface or planner, is planning sugar
over multiple Expand steps. It is not a distinct runtime result shape.
Filter¶
FilterParameters no longer relies on a placeholder string expression.
Instead it points structurally to one or more FilterRule holons:
FilterParameters
FilterRules -> FilterRule*
This keeps room for filter semantics to become a proper structural mini-model.
OrderBy¶
OrderByParameters no longer relies on a placeholder string expression.
Instead it points structurally to one or more OrderByRule holons:
OrderByParameters
OrderByRules -> OrderByRule*
Project¶
ProjectParameters does not use a free-form projection expression string in
v1.1.
Instead it uses PropertyNameList.PropertyType, intended as a value-array of
PropertyName values.
That means projection is expressed as an explicit list of requested property names rather than as an opaque mini-language.
Project is the explicit materialization boundary of the executable algebra.
Before projection, execution should generally preserve deferred access through
HolonReference, HolonCollection, QueryGraph, and ExecutionInstance.
A projection is a materialized, self-describing holon-shaped value described by
a derived HolonType. Projection types may be anonymous and inline or reusable
content-addressed descriptors assembled from existing schema elements such as
property, value, and relationship types.
Projection values may implement the same readable holon-facing surface as other holons, but they remain materialized selected state. References preserve identity and defer materialization; projections contain selected state.
Query Results¶
The external result of query execution is simply a HolonCollection.
The older QueryResult wrapper framing is intentionally dropped from the core
v1.1 model.
That does not mean the engine cannot internally track diagnostics or richer execution state. It means the externally meaningful result payload of the query dance is the result collection itself:
QueryDanceResponse
ResponseBody -> HolonCollection
Diagnostics belong to the dance-response layer.
Live state belongs to ExecutionInstance.
The symbolic result designation belongs to QueryGraph.DeclaredResultBinding.
Scalar extraction is not the default query-result shape. If a caller needs scalar values from projected holons, that should be modeled as an explicit materialization or command surface rather than changing ordinary query execution into scalar-stream execution.
Path-like and explanation views are also materialized views over the
QueryGraph, QueryStep identities, relationship-channel names, execution
topology, and execution bindings. They are useful for explanation, provenance,
visualization, export, or declarative-query compatibility, but they are not
primitive runtime carriers.
Distributed Execution¶
Distributed query execution in MAP emerges from nested space topology.
This section is intentionally limited in scope.
Its purpose is to state the conceptual boundary between single-space query execution and possible future multi-space query execution, so that the Command/Dance/Query seam can be landed cleanly now.
It does not attempt to fully specify the runtime coordination machinery for multi-space execution. The current exploratory home for that design work is:
A HolonSpace is not merely another data object. It is also:
- a social boundary
- a trust boundary
- a storage boundary
- an execution boundary
- a Holochain app/DHT boundary
That means MAP's social topology and execution topology are intentionally aligned. Queries follow belonging relationships and may cross from one execution domain into another when the query reaches another space.
Coordinator And Local Executor¶
This document is about execution of an already-formed QueryGraph, not about
query-graph generation.
So the important distributed-runtime distinction is:
- a coordinating host, which owns cross-space orchestration
- a local executor, which evaluates query steps inside one
HolonSpace/ hApp
The local executor always runs within exactly one space-scoped execution context.
An individual step execution never straddles multiple hApps.
If work must continue in several spaces, that is not one distributed step. It is a coordination event in which the host creates one delegated execution per participating space.
The exact mechanics of that coordination event are not yet specified in this document.
Focal Space And Query Horizon¶
The focal space is the place from which a query is authorized, interpreted, and presented.
The query horizon is the permission-filtered set of spaces that may participate in answering the query.
These are not the same thing.
For example, a query may originate from Frank's I-Space while its query horizon includes multiple spaces Frank shares with Mary. The focal space determines the standpoint and authority. The query horizon determines where execution may fan out.
HolonSpace As Execution Boundary¶
HolonSpace is a first-class execution boundary.
The basic rule is:
Each step executes inside one current HolonSpace / hApp.
If a step produces a collection whose members are HolonSpaces,
and the next work must execute inside those spaces,
the coordinating host splits execution into one delegated branch per space.
This is reasonable because HolonSpace is infrastructure, not just ordinary
data. It marks a boundary of storage, trust, host/guest execution, and Holochain
app/DHT locality.
In v1.1 this rule does not require a new core schema type. It is host/executor
behavior over the existing QueryGraph, QueryDanceRequest,
ExecutionInstance, and HolonCollection model.
The fuller execution-coordination design for how this behavior would be realized across spaces remains exploratory at this stage.
Detecting Fanout¶
Static analysis may reveal that a step kind can produce HolonSpace
references, but it cannot know in advance which spaces, or how many, for a
particular execution.
Therefore fanout is fundamentally a runtime discovery.
The coordinating host detects fanout when all of the following are true at execution time:
- a step finishes in the current space
- its output is a
HolonCollection - one or more members of that collection are
HolonSpacereferences - the next step or continuation requires local execution against those spaces
The signal is therefore not a separate schema object. It is the combination of:
- the current execution scope
- the actual output collection
- the next continuation to be executed
Until fanout is detected, execution is simply the ordinary walk of the
QueryGraph through its QueryStep dependencies.
When fanout is detected, the host does not invent a new algebraic structure. It
continues the same QueryGraph execution separately in each discovered target
space, beginning from the next eligible step and using the branch-local
bindings/context for that space.
No Mandatory Fanout Operation¶
v1.1 does not require a distinct FanoutQueryStepType.
Fanout is an execution rule, not part of the core algebra.
That keeps the query graph simpler:
Expand,Filter,OrderBy,Limit, and related operations remain the algebra- crossing from one space to many spaces is handled by the coordinating host
- the symbolic query graph does not need a special distributed-control node just to express "continue this query in each resulting space"
An explicit fanout operation could still be introduced later if MAP needs:
- user-visible control over delegation points
- explicit explain plans for distribution boundaries
- alternative merge policies as first-class query semantics
But it is not required for the v1.1 execution model.
If MAP later needs a more explicit distributed-control surface, that should be specified in a future coordination-oriented design document rather than prematurely hardened here.
Delegation And Reference Resolution¶
MAP has two distinct cross-space retrieval mechanisms.
Delegated execution happens when already-executing query work discovers that continuation must occur in one or more other spaces. For example:
Expand(BelongsTo) -> [SpaceA, SpaceB, SpaceC]
then Expand(Members)
The host evaluates Expand(BelongsTo) in the current space, sees that the
result collection contains HolonSpace references, and then dispatches
Expand(Members) into each target space. This is coarse-grained federation:
move the query toward the data.
Resolution-driven distribution happens when ordinary execution encounters
unresolved references. A HolonCollection contains references, not necessarily
materialized holons. Later, when code asks for state that is not already present
in a SmartReference or SmartLink, the Holon Cache Manager resolves the reference
through cache and fetch behavior. This is demand-driven retrieval: move the data
toward the query only when needed.
These mechanisms should remain separate:
- delegated execution reasons about spaces, execution domains, and query continuation
- reference resolution reasons about cache hits, cache misses, and fetches
- the coordinator should not become a cache-miss engine
- the cache manager should not become a distributed query coordinator
Host And Guest Responsibilities¶
Guests execute within one space/app/DHT.
Hosts coordinate across spaces.
A guest may evaluate local query work using:
- local holons
- SmartLink values
- SmartReference property-map values
- local cache state
But a guest should not initiate external trust-channel calls. Cross-space coordination belongs to the host, which can route dance requests, dispatch eligible query work to other spaces, and merge results.
Asynchronous Delegation¶
Delegated cross-space execution will likely require asynchronous invocation.
Once the coordinating host detects fanout, it may issue one QueryDance
invocation per participating space without blocking local execution on serial
round-trips.
Conceptually:
for each target space S:
invoke QueryDance asynchronously in S
with the delegated continuation and delegated bindings
The host would then need to track outstanding delegated executions until they complete, timeout, fail, or are cancelled.
This document does not specify a particular Rust async shape or a particular schema-level child-execution model.
What is normative is the responsibility split:
- local execution is single-space
- cross-space invocation is host-coordinated
- delegated invocations may eventually run concurrently
- result handling must tolerate partial completion and failure
Expand Returns References¶
Relationship expansion returns a HolonCollection.
That collection contains references. It does not imply every referenced holon has been materialized.
This matters for distributed execution because a collection may contain:
- local references
- external references
- references into several spaces
- references with enough embedded smart data for some operations
- references requiring later materialization
The expand step itself should not chase every link. Resolution happens only when later work needs state that is not already available.
External reference resolution is not itself part of query execution.
This document therefore treats the responsibilities for:
- resolving external references
- fetching missing remote state
- cache hit/miss behavior
- trust-channel retrieval behavior
as out of scope for the graph-query-engine spec.
The intended design home for those responsibilities is a future Holons Cache Manager design spec.
That document has not yet been authored, so the authoritative specification home for external reference resolution is currently TBD.
Until then, dist-query-concept.md remains the active exploratory discussion of how these concerns may interact with distributed query execution.
Expand-Filter Pushdown¶
Expand and Filter often form a useful dyad.
Instead of expanding all members of a space and filtering centrally, the coordinating host should often delegate the paired work into the target space:
Expand(Members)
Filter(criteria)
This lets each social organism filter near storage and return only matching references.
For example, from an I-Space:
Expand(BelongsTo) -> [GroupA, GroupB, GroupC]
For each group:
Expand(Members)
Filter(name contains "Mary")
Each group evaluates locally and returns matches. The host combines, ranks, streams, or otherwise merges the results.
This minimizes data movement while preserving space sovereignty.
Result Merge Semantics¶
When delegated branches complete, the coordinating host would need to merge
their branch results into one HolonCollection for the downstream
continuation.
Here "merge" should be understood carefully.
The default distributed merge is not implicit duplicate elimination. It is combination of branch collections into one logical result collection.
So for design purposes in v1.1:
- branch results are combined into one
HolonCollection - duplicate elimination is performed only by an explicit
Distinctstep - ordering across asynchronous branches is not guaranteed unless an explicit
later
OrderBystep establishes it
In that sense, earlier uses of the word "union" in this document should be read as "combined result set" rather than "mathematical set union with automatic deduplication."
Natural Parallelism¶
Nested belonging provides natural partitioning and parallelism.
If a person belongs to ten spaces, a query over those spaces can become ten parallel subqueries. If they belong to many more spaces, the same rule still applies, with later optimizations for prioritization, streaming, batching, backpressure, ranking, and caching.
The foundational model does not change as these optimizations are added.
Relationship To Recursive QueryGraph Execution¶
The older v1.0 narrative leaned heavily on QueryGraphStepType and nested query
graphs as the central mechanism for distributed execution and graph rewriting.
v1.1 deliberately steps back from making that recursive-subgraph mechanism normative in the core schema.
The important v1.1 point is more precise:
- a query dance is invoked against some affording holon whose type affords that dance
- query execution is therefore naturally space-scoped
HolonCollectionremains the runtime substrateExecutionInstancecarries run-specific state- each step execution is local to one
HolonSpace/ hApp - fanout is runtime-discovered when step results reveal downstream space branches
- hosts coordinate across spaces; guests execute locally within a space
- delegated distributed execution and demand-driven reference resolution remain separate
Distributed rewriting, grouped subgraphs, and recursive query-graph execution remain valid execution strategies. They are no longer the schema foundation of the core query-engine design.
Those strategies are currently better understood as part of the exploratory multi-space design space than as settled v1.1 execution machinery.
Distributed Design Rules¶
The distributed execution model follows these rules:
- focal space is not the same thing as search scope
HolonSpaceis a distributed execution boundary- each concrete step execution is single-space
- fanout is detected at runtime from actual step results
- v1.1 does not require an explicit fanout operation
- guests execute locally
- hosts coordinate across spaces
- delegated query-dance invocations may run concurrently
- branch results are merged into one
HolonCollection - deduplication requires an explicit
Distinct Expandreturns references, not materialized holons- SmartReferences resolve state only when needed
- expand-filter dyads should be delegated when the target space can evaluate them
- predicates should move near storage whenever possible
- distributed delegation and cache resolution remain distinct
- batching, pulsing, prefetching, streaming, and prioritization are optimizations, not semantic requirements
These rules are included to keep the current query design from painting later multi-space work into a corner. They should not be read as a complete runtime specification for distributed query execution.
Rust Intent Layer¶
The Rust layer should use thin typed wrappers around HolonReference so callers
can express intent without mirroring holon state into Rust structs.
Examples:
QueryGraphHolonQueryStepHolonQueryBindingHolonExecutionInstanceHolonExecutionBindingHolonHolonCollectionReference
The important pattern is:
- keep the wrapped
HolonReferenceprivate - provide typed read-through accessor methods
- use helper patterns similar to
accessor_helpers.rs - use collection-oriented helpers like
single_member(),optional_single_member(), andmembers()where callers expect a collection
The detailed wrapper sketch lives in the companion DSL document.
Suggested Core-Schema Source Changes¶
The design above is grounded in the currently generated schema names, but it also implies several source-of-truth Airtable refinements that are not yet reflected in generated schema JSON.
The most important ones are:
DanceType.HolonTypeshould useDanceInput -> HolonTypeinstead ofInputParameters -> Projection.HolonTypeDanceInvocation.HolonTypeshould useAffordingHolon -> HolonTypeinstead ofTarget -> HolonType- the full query schema described here should be introduced as an explicit schema-layer model
Those changes should be made in the Airtable source and then regenerated into schema JSON. This document does not propose editing generated JSON directly.
Summary¶
The v1.1 foundation is:
Dance.CommandType
payload -> DanceInvocation
DanceInvocation
invokes -> QueryDance
request -> QueryDanceRequest
QueryDanceRequest
query_graph -> QueryGraph
initial_bindings -> ExecutionBinding*
QueryGraph
query_steps -> QueryStep*
declared_input_bindings -> QueryBinding*
declared_result_binding -> QueryBinding
ExecutionInstance
executes_request -> QueryDanceRequest
execution_bindings -> ExecutionBinding*
execution_result -> HolonCollection?
QueryDanceResponse
response_body -> HolonCollection
This gives MAP:
- a sharper Command/Dance/Query seam
- a symbolic query plan separated cleanly from runtime execution state
HolonCollectionas the stable runtime query substrate- a smaller and more legible
QueryStep - structural parameter modeling for filter, order-by, and project
- room for typed Rust wrappers that convey intent cleanly
That is the intended v1.1 design center.