# CallEvent Unwrapping in Transport Layer

## Problem

After unifying `plexus.call` with the streaming pattern (see `16679536519907867647_plexus-call-streaming.md`), responses from `plexus.call` are now wrapped in `CallEvent`:

```json
// Before: direct PlexusStreamItem
{"content": {...}, "content_type": "echo.once", "type": "data"}

// After: nested CallEvent inside PlexusStreamItem
{"content": {"content": {...}, "content_type": "echo.once", "type": "data"}, "content_type": "plexus.call", "type": "data"}
```

This breaks synapse and other consumers that expect `PlexusStreamItem` with the original `content_type`.

## Solution

Add transparent unwrapping in `Substrate.Transport` so consumers continue to receive flattened `PlexusStreamItem` responses.

### New Types (Plexus.Types)

```haskell
data CallEvent
  = CallData     { callContent :: Value, callContentType :: Text }
  | CallProgress { callMessage :: Text, callPercentage :: Maybe Double }
  | CallError    { callErrorMessage :: Text, callErrorCode :: Maybe Text }

unwrapCallEvent :: Text -> Provenance -> CallEvent -> PlexusStreamItem
```

### Transport Layer Changes

```haskell
unwrapPlexusCallItem :: PlexusStreamItem -> PlexusStreamItem
unwrapPlexusCallItem item@(StreamData hash prov ct content)
  | ct == "plexus.call" = case fromJSON content of
      Success callEvent -> unwrapCallEvent hash prov callEvent
      Error _ -> item
  | otherwise = item
unwrapPlexusCallItem item = item
```

Applied automatically in:
- `invokeMethod`
- `invokeRaw`
- `invokeMethodStreaming`

## Result

Consumers receive the same `PlexusStreamItem` format as before:

```json
{"content": {...}, "content_type": "echo.once", "type": "data"}
```

The `CallEvent` layer is invisible to synapse and other frontends.

## Version Changes

| Package | Before | After |
|---------|--------|-------|
| hub-core | 0.1.0 | 0.2.0 |
| hub-macro | 0.1.3 | 0.2.0 |
| substrate-protocol | 0.1.0.0 | 0.2.0.0 |
| substrate-synapse | 0.1.0.0 | 0.2.0.0 |
| substrate-hub | 0.2.5 | 0.2.6 |
