Skip to content

Explore graceful delegate upgrade mechanisms #74

@sanity

Description

@sanity

Context

Similar to contracts (#59), updating the chat delegate WASM results in a new DelegateKey because the key is derived from:

DelegateKey = Blake3(CodeHash || Parameters)

This means any change to delegate logic creates an entirely new delegate identity. Since all delegate secrets (signing keys, key-value storage) are tied to the DelegateKey, upgrading the delegate effectively orphans all user data stored by the old delegate.

Current State

The chat delegate stores critical user data via the Freenet secret storage system:

  • Signing keys for each room (32-byte Ed25519 keys)
  • Key-value storage for room-specific data
  • Key indices tracking what data exists

This data is encrypted using XChaCha20Poly1305 with a cipher registered per-delegate. When the delegate code changes:

  1. A new CodeHash is computed (BLAKE3 of WASM)
  2. A new DelegateKey is derived
  3. The new delegate cannot access secrets stored under the old key
  4. Users lose their signing keys and stored data

Options to Explore

1. UI-Mediated Migration (short-term)

The UI already communicates with delegates via ApplicationMessage. A migration flow could:

  • Detect when a new delegate version is available
  • Request data export from old delegate (new ExportData message type)
  • Register new delegate
  • Import data to new delegate (new ImportData message type)
  • Unregister old delegate

Questions:

  • How does the UI know a new delegate version exists?
  • Should export/import be one message type or separate per data category?
  • How do we handle partial migration failures?

2. Direct Delegate-to-Delegate Communication

Delegates currently communicate only with their registering contract/app. Enabling direct delegate communication could allow:

  • Old delegate receives "migration request" from new delegate
  • Old delegate exports secrets to new delegate directly
  • New delegate validates and stores the imported data

Questions:

  • What authentication ensures only the legitimate new version can request migration?
  • How do we prevent malicious delegates from extracting secrets?
  • Does this require Freenet protocol changes?

3. Stable Delegate Identity Layer

Separate delegate identity from code hash:

  • Introduce DelegateIdentity independent of code
  • DelegateKey becomes Blake3(DelegateIdentity || Version)
  • Secrets keyed by DelegateIdentity, not DelegateKey
  • New versions of same identity can access existing secrets

Questions:

  • How is DelegateIdentity established and verified?
  • Who controls what code versions map to an identity?
  • Does this require significant Freenet changes?

4. Secret Storage Migration at Protocol Level

Add Freenet support for secret migration:

  • MigrateSecrets(old_delegate_key, new_delegate_key, proof) operation
  • Runtime transfers encrypted secrets between delegate keys
  • Proof validates the migration is authorized

Questions:

  • What constitutes valid migration proof?
  • Should old secrets be deleted or preserved?
  • How does this interact with the encryption cipher per-delegate?

5. Versioned Delegate with Backward Compatibility

Include version handling in delegate code:

  • Delegate parameters include version field
  • Same code handles multiple storage formats
  • Backward-compatible changes reuse existing secrets

Limitations:

  • Doesn't solve code hash change problem
  • Only works for additive changes
  • WASM size bloat over time

Related

  • Explore graceful contract upgrade mechanisms #59 - Graceful contract upgrade mechanisms (same problem for contracts)
  • delegates/chat-delegate/src/handlers.rs - current secret storage logic
  • freenet-stdlib/rust/src/delegate_interface.rs - delegate identification

Next Steps

Looking for input on:

  1. Which approach(es) are most feasible for delegates specifically?
  2. Can we leverage any contract migration work from Explore graceful contract upgrade mechanisms #59?
  3. What's the minimal viable solution that preserves user signing keys?

[AI-assisted - Claude]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions