Skip to content

DanceInitiator for Guest->Guest Dancing #331

@evomimic

Description

@evomimic

UNDER CONSTRUCTION

On Hold -- while we think through the testing strategy for guest->guest dancing

1. Summary (Required)

What is the enhancement?
Implement a DanceInitiator for guest → guest dancing within the same conductor process.
This enables WASM guest zomes to invoke other guest zomes (possibly in different cells or DNAs) through the same conductor, using the same TrustChannel envelope and session-state mechanism that powers client → guest and test → guest interactions.


2. Problem Statement (Required)

Why is this needed?
Currently, guest zomes can only serve as dance endpoints—they can respond to dance() calls from clients or tests—but cannot themselves initiate new dances toward other guests.

This prevents any guest → guest choreography inside a conductor (e.g., one holon type requesting services from another).
Such coordination will be essential once multiple holon spaces and roles (e.g., “Authority”, “Publisher”, “Collaborator”) begin interacting dynamically.

Without a guest-side DanceInitiator, all outbound requests from a guest must be simulated externally or faked during tests, blocking a major class of real distributed workflows.


3. Dependencies (Required)

Does this depend on other issues or features?

  • PR Add DanceCallService to Space Manager's Service Registry #328 — Introduced the DanceInitiator trait and TrustChannel abstraction.
  • Guest Session-State Envelope — Already available within TrustChannel for wrapping/unwrapping state.
  • ⚙️ Conductor access API — Depends on Holochain’s HDK ability to call other cells within the same conductor.

No external blockers; this builds directly atop the infrastructure introduced in PR #328.


4. Proposed Solution (Required)

How would you solve it?

We extend the guest-side environment to include an internal DanceInitiator implementation, allowing guest → guest calls.

1. Add GuestConductorConfig

Define a lightweight configuration struct (analogous to MockConductorConfig and TauriConductorConfig):

#[derive(Clone)]
pub struct GuestConductorConfig;

#[async_trait(?Send)]
impl DanceInitiator for GuestConductorConfig {
    async fn initiate_dance(
        &self,
        _context: &dyn HolonsContextBehavior,
        request: DanceRequest,
    ) -> DanceResponse {
        // Use HDK to call another zome’s `dance()` function
        let zome_call = Call {
            cell_id: resolve_target_cell(&request)?,
            zome_name: ZomeName::from("holons"),
            fn_name: FunctionName::from("dance"),
            payload: ExternIO::encode(&request)?,
            cap_secret: None,
            provenance: agent_info()?.agent_initial_pubkey,
        };

        match call(zome_call) {
            Ok(result) => DanceResponse::from(result),
            Err(e) => DanceResponse::from_error(HolonError::ConductorError(e.to_string())),
        }
    }
}

This lets guest zomes send new DanceRequests to other zomes/cells through the same conductor without leaving the WASM environment.

2. Update init_guest_context

Modify init_guest_context to inject this new initiator:

let guest_initiator: Arc<dyn DanceInitiator> =
    Arc::new(TrustChannel::new(Arc::new(GuestConductorConfig)));

let space_manager = Arc::new(HolonSpaceManager::new_with_managers(
    Some(guest_initiator),
    holon_service,
    local_space_holon,
    ServiceRoutingPolicy::Combined,
    nursery,
    transient_manager,
));

This ensures all outbound dance calls from within the guest context use the same TrustChannel and session-state envelope handling as clients and tests.

3. Extend TrustChannel

No API change needed; it already handles session-state wrapping/unwrapping.
Just ensure the envelope logic remains active in both directions for intra-conductor guest calls.


5. Scope and Impact (Required)

What does this impact?

  • Holons Guest Runtime — gains the ability to initiate dances internally (guest → guest).
  • Holons Core / TrustChannel — minor update to support guest context injection.
  • init_guest_context — modified to include the guest-side DanceInitiator.
  • Tests — can begin validating multi-guest choreography in a single conductor instance.

This enhancement completes the triangle:
client → guest, test → guest, and now guest → guest.


6. Testing Considerations (Required)

How will this enhancement be tested?

This will be the first introduction of multiple zomes/DHT's into the architecture. ChatGPT suggested the following testing possibilities, but they involve setting up multiple spaces for testing and additional design thought is needed on how best to do that.

Testing the guest→guest DanceInitiator spans several layers, from isolated unit tests to full conductor integration. Each layer ensures correctness, stability, and compatibility with the existing client→guest and test→guest flows.


🧩 1. Unit Tests — GuestConductorConfig + TrustChannel

Validate that the GuestConductorConfig correctly implements DanceInitiator semantics without needing a running conductor.

Focus

  • Proper HDK.call() construction (zome name, payload encoding).
  • Conversion of HolonError into DanceResponse via ResponseStatusCode::from.
  • Outbound and inbound session-state envelope handling.

Example

  • Mock the HDK layer to simulate call() success/failure.
  • Confirm:
    • Success yields a valid DanceResponse.
    • Errors are mapped to DanceResponse with ServerError.

🧪 2. Integration Tests — SweetConductor (Guest→Guest Flow)

Run an in-process Holochain conductor hosting two zomes:

  • holons_guest_a (initiator)
  • holons_guest_b (responder)

Flow

  1. holons_guest_a invokes trigger_dance().
  2. That triggers GuestConductorConfig::initiate_dance()HDK.call()holons_guest_b::dance().
  3. holons_guest_b responds with a DanceResponse.
  4. The session-state envelope is hydrated and returned to guest_a.

Assertions

  • DanceResponse.status_code == OK
  • Response body matches the expected echo payload.
  • Session state round-trips correctly between both guests.

🧱 3. Contract-Level Test — DanceProtocol Envelope Roundtrip

Verify that session-state encapsulation is consistent across guest→guest, client→guest, and test→guest use cases.

Focus

  • attach_to_request() followed by hydrate_from_response() preserves the original SessionState.
  • Serialization/deserialization of DanceRequest and DanceResponse is stable and deterministic.

This guards against subtle regressions in TrustChannel envelope behavior.


🧬 4. End-to-End (Holon Loader Scenario)

Integrate the new guest→guest initiator into the Holon Loader flow:

Rust client → guest_a (loader)
    ↳ guest_a initiates guest→guest dance → guest_b (storage)

Expected Outcome

  • Parsed holons from guest_a are successfully staged in guest_b’s DHT.
  • Response propagates back through the TrustChannel layers.
  • All session-state envelopes remain synchronized end-to-end.

⚠️ 5. Re-entrancy & Cycle Handling

Ensure the system detects and handles potential recursion:

  • Scenario: guest_a calls guest_b, which re-invokes guest_a.
  • Validation: bounded recursion or explicit ServerError response instead of stack overflow or infinite loop.

Summary Table

Level Environment Focus Key Assertion
1️⃣ Unit Mocked HDK Error and payload mapping HolonErrorResponseStatusCode
2️⃣ Integration SweetConductor Guest→Guest invocation Response OK, envelope intact
3️⃣ Contract No conductor Protocol integrity SessionState round-trip
4️⃣ E2E Full runtime Loader pipeline Holons staged via guest→guest
5️⃣ Re-entrancy SweetConductor Safety Recursive calls safely handled

Together, these tests ensure the new guest→guest DanceInitiator behaves consistently, safely, and symmetrically with existing initiator types while unlocking multi-guest choreography in the Holons runtime.

7. Definition of Done (Required)

When is this enhancement complete?

  • Implement GuestConductorConfig implementing DanceInitiator.
  • Update init_guest_context to inject a TrustChannel wrapping this initiator.
  • Verify session-state envelopes apply correctly in both directions.
  • Add a minimal guest→guest integration test (test_guest_to_guest_dance).
  • Confirm existing sweetests remain passing.

Optional Details (Expand if needed)

8. Alternatives Considered

Alternative:
Use host-side routing (client or proxy) for guest→guest communication.
Rejected: adds unnecessary latency and external dependencies for calls that can stay local within the same conductor.


9. Risks or Concerns

  • HDK version compatibility — depends on stable intra-cell call() behavior.
  • Must prevent recursive or cyclical guest→guest calls causing stack overflows.
  • May need future guards for cross-DNA or unauthorized invocation.

10. Additional Context

Supporting code sketches and references:

  • MockConductorConfig — pattern for implementing DanceInitiator.
  • TrustChannel — session-state handling logic (outbound + inbound).
  • init_test_context — reference for injecting a conductor-backed initiator.

This enhancement completes the unified DanceInitiator model across test, client, and guest environments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requeston holdOn hold due to unsatisfied dependencies

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions