# Blurt platform parity gap analysis

> Canonical platform sources for this review:
>
> - Layer 1: `../blurt` (`blurtd`) at `8fe6145cf` on branch `dev`.
> - Layer 2: `../nexus` Python implementation at `035a0ec` on branch `main`.
> - Target SDK: this `@beblurt/dblurt` repository.
>
> `dblurt` is not the source of truth. It is an SDK that should faithfully expose
> the platform defined by Layer 1 and Nexus.

Generated evidence lives in [`generated/platform-parity-inventory.md`](./generated/platform-parity-inventory.md).
The JSON source is [`generated/platform-parity-inventory.json`](./generated/platform-parity-inventory.json).
Regenerate both with:

```bash
node scripts/platform-parity-audit.js
```

## Executive conclusion

`dblurt` does **not** yet faithfully expose the complete functional surface of the
current Blurt platform.

The SDK does provide an important escape hatch:

```ts
client.call(api, method, params)
```

That means many unwrapped Layer 1 and Nexus RPC methods can still be reached by
advanced users. However, raw reachability is not the same as faithful SDK parity.
For a production SDK, parity requires:

- correct consensus serialization for every submitted operation it claims to support;
- typed helpers or documented raw-call surfaces for canonical RPC APIs;
- parameter and return-shape fidelity;
- clear namespace separation between Layer 1 and Nexus;
- tests that detect drift from the canonical implementations.

The most important confirmed runtime divergence found during this milestone was
fixed immediately: `witness_update` was serialized with operation id `11`
(`delete_comment`) instead of canonical id `7`. A regression test now locks the
canonical id.

## Methodology

1. Treat `../blurt` and `../nexus` as canonical implementations.
2. Extract Layer 1 API methods from `DECLARE_API` / `FC_API` declarations in:
   - `libraries/plugins/apis/**/include/**/_api.hpp`
   - `libraries/legacy_plugins/**/include/**/*_api.hpp`
3. Extract canonical operation ordering from:
   - `../blurt/libraries/protocol/include/blurt/protocol/operations.hpp`
4. Extract Nexus public JSON-RPC registration from:
   - `../nexus/hive/server/serve.py::build_methods()`
5. Extract dblurt helper coverage from:
   - `src/helpers/*.ts`
6. Extract dblurt operation types and serializers from:
   - `src/chain/operation.ts`
   - `src/chain/serializer.ts`
7. Classify gaps by whether raw `client.call` can reach the method, whether a typed
   helper exists, whether consensus serialization is correct, and whether docs/tests
   make the behavior defensible.

Static extraction is intentionally conservative. It proves presence/absence of
source-declared surfaces; it does not prove live behavioral parity for every method.

## Severity scale

| Severity | Meaning |
| --- | --- |
| Critical | Can cause signed transactions to be serialized as a different canonical operation, or can make user funds/governance actions materially unsafe. |
| High | Canonical platform capability is unreachable or materially misleading through the SDK for common production use. |
| Medium | Capability is reachable only by raw calls, lacks typing/tests/docs, or diverges in return/parameter modeling. |
| Low | Documentation, discoverability, or advanced/optional API coverage issue. |

## Findings

### F-001 — `witness_update` consensus operation id mismatch

Severity: **Critical**  
Status: **Fixed in this milestone**  
Class: **Implementation bug**

Canonical evidence:

- `../blurt/libraries/protocol/include/blurt/protocol/operations.hpp` lists
  `witness_update_operation` at operation id `7`.

Previous dblurt behavior:

- `src/chain/serializer.ts` serialized `witness_update` with id `11`, which is
  canonical `delete_comment`.

Impact:

- Any signed `witness_update` constructed through this serializer would not be a
  faithful Layer 1 witness update operation.
- This is a consensus-serialization bug, not an ergonomic helper gap.

Remediation applied:

- `src/chain/serializer.ts` now uses operation id `7` for `witness_update`.
- `test/crypto_modernization_contract.ts` verifies the serialized operation id byte.

### F-002 — Submitted operation serializers cover only 17 of 37 canonical submitted operations

Severity: **High**  
Class: **Functional parity gap / implementation incompleteness**

Canonical evidence:

- `../blurt/libraries/protocol/include/blurt/protocol/operations.hpp` declares
  37 submitted operations before virtual operations.

Current dblurt evidence:

- `src/chain/operation.ts` names all 52 submitted + virtual operations.
- `src/chain/serializer.ts` provides serializers for 17 submitted operations.

Missing submitted operation serializers detected statically:

- `withdraw_vesting`
- `account_witness_proxy`
- `custom`
- `delete_comment`
- `set_withdraw_vesting_route`
- `claim_account`
- `create_claimed_account`
- `request_account_recovery`
- `recover_account`
- `escrow_transfer`
- `escrow_dispute`
- `escrow_release`
- `escrow_approve`
- `transfer_to_savings`
- `transfer_from_savings`
- `cancel_transfer_from_savings`
- `custom_binary`
- `decline_voting_rights`
- `reset_account`
- `set_reset_account`

Impact:

- These operations are named in TypeScript but cannot be signed/broadcast through
  `sendOperations()` because the serializer throws `No serializer for operation`.
- Some have helper methods that construct an operation (`claimAccount`,
  `createClaimedAccount`, `cancelTransferFromSavings`) but are not actually
  serializable. That is worse than a missing helper because it appears supported.

Recommendation:

1. Treat every helper whose operation lacks a serializer as a release-blocking bug
   for that helper.
2. Add canonical serialization fixtures for all 37 submitted operations.
3. Only advertise a broadcast helper after serializer parity exists.
4. Prefer a generated operation-id table from canonical `operations.hpp` to avoid
   manual drift.

### F-003 — Layer 1 typed RPC helper coverage is partial

Severity: **Medium**  
Class: **SDK API parity gap**

Canonical evidence:

- Static extraction found 17 Layer 1 API namespaces in canonical `blurtd` source.
- dblurt exposes a generic raw call path for arbitrary namespaces:
  `Client.call(api, method, params)`.

Current typed helper coverage from generated inventory:

| Canonical API | Methods | Typed helpers | Missing typed helpers |
| --- | ---: | ---: | ---: |
| `account_history_api` | 4 | 4 | 0 |
| `block_api` | 2 | 2 | 0 |
| `condenser_api` | 76 | 32 | 44 |
| `database_api` | 44 | 10 | 34 |
| `follow_api` | 9 | 5 | 4 |
| `network_broadcast_api` | 2 | 1 | 1 |
| `account_by_key_api` | 1 | 0 | 1 |
| `rc_api` | 3 | 0 | 3 |
| `tags_api` | 20 | 3 | 17 |
| `transaction_status_api` | 1 | 0 | 1 |
| legacy/admin/stat APIs | 20+ | 0 | 20+ |

Interpretation:

- This is not a hard reachability failure because raw `client.call()` can call many
  of these methods.
- It is a helper parity failure: the public SDK does not make the full platform
  discoverable, typed, or tested.

Important missing production-facing methods include:

- authority/signature helpers: `get_required_signatures`, `get_potential_signatures`,
  `verify_account_authority`, `verify_signatures`, `get_transaction_hex`;
- account/key lookup: `get_key_references`, `lookup_account_names`, `find_accounts`;
- RC/resource APIs: `find_rc_accounts`, `get_resource_params`, `get_resource_pool`;
- transaction status: `find_transaction`;
- synchronous broadcast: `broadcast_transaction_synchronous`;
- database find/list APIs for escrows, routes, savings withdrawals, votes, comments,
  proposals and witnesses.

Recommendation:

- Keep `client.call()` as the complete raw escape hatch.
- Add namespace-specific raw helpers for unwrapped canonical APIs first, e.g.
  `client.rc.call(...)`, `client.tags.call(...)`, `client.accountByKey.call(...)`.
- Add typed helpers by priority, not by count: signing/authority, transaction status,
  RC, account/key lookup, then long-tail list/find APIs.

### F-004 — Nexus bridge helper coverage is now complete by registered method name

Severity: **Medium**  
Status: **Fixed in this milestone**  
Class: **Layer 2 SDK parity gap / guardrail**

Canonical evidence:

- `../nexus/hive/server/serve.py::build_methods()` registers 23 public bridge methods.

Fixed in this milestone:

- `get_post_header`
- `get_trending_topics`
- `list_community_titles`
- `list_top_communities`
- `normalize_post`
- corrected spelling alias `listPopCommunities` while preserving legacy
  `listPopComunities`
- Python defaults for cursor/limit values on bridge helpers

Interpretation:

- The method-name gap for the registered `bridge.*` namespace is closed.
- This is not the same as schema-complete parity: response fields, optionality,
  validation limits and error behavior still need schema-aware fixtures.

Recommendation:

- Keep the generated inventory as the method-name guardrail.
- Continue with response-shape and error-shape fixtures from canonical Nexus Python.

### F-005 — Nexus also exposes condenser/follow/tags compatibility APIs

Severity: **Medium**  
Class: **Namespace modeling / documentation gap**

Canonical evidence:

- Nexus registers `condenser_api.*`, `follow_api.*`, `tags_api.*`, root `call`, and
  `hive.db_head_state` in addition to `bridge.*`.

Current dblurt state:

- Many of these methods are reachable through `client.condenser` if the configured
  RPC endpoint is Nexus-backed.
- There is no explicit SDK documentation explaining that Nexus is more than
  `bridge.*`.
- `client.nexus` only targets the `bridge` namespace.

Interpretation:

- This is not necessarily a design bug. Keeping Layer 1 condenser helpers separate
  from Nexus bridge helpers is reasonable.
- The SDK should document that a Nexus endpoint may implement multiple namespaces
  and that `client.call(namespace, method, params)` is the authoritative fallback.

Recommendation:

- Document Nexus namespace behavior.
- Consider a `client.hive.call(...)` or general namespace helper registry if Nexus
  health/status APIs become first-class.

### F-006 — Parameter and return types are not proven canonical

Severity: **Medium**  
Class: **Validation gap**

Evidence:

- Type definitions in `src/chain/*.ts` are hand-maintained.
- Canonical Layer 1 reflects API args/returns in `*_api_args.hpp`,
  `*_api_objects.hpp`, and `FC_REFLECT` blocks.
- Nexus returns are shaped by Python object loaders in `hive/server/**/objects.py`.
- Subagent/source review found concrete fixed examples:
  - `account_history_api.enum_virtual_ops` canonical args do **not** include
    `include_reversible` or `group_by_block`.
  - `account_history_api.get_ops_in_block` canonical args are only
    `block_num` and `only_virtual`.
  - Nexus profile stats use `bp` plus `referrer`, not `sp`.
  - Nexus notifications may emit `reply_comment`.

Impact:

- Even when a helper exists by method name, parameter object shape, defaults, enum
  values, optional fields, and result structures may drift.

Recommendation:

- Extend `scripts/platform-parity-audit.js` to extract Layer 1 arg/return structs
  and Nexus function signatures/defaults.
- Add generated parity fixtures for representative methods in every namespace.
- Classify method-name coverage as only the first gate.

### F-007 — Error handling differs by transport and source implementation

Severity: **Medium**  
Class: **Compatibility / developer experience gap**

Evidence:

- dblurt has legacy and core transports with documented divergence in contract tests.
- Nexus uses `jsonrpcserver` and `return_error_info` wrappers in Python.
- blurtd uses FC/appbase JSON-RPC error structures.

Impact:

- Applications may observe different error object shapes depending on Layer 1 vs
  Nexus endpoint and legacy vs core transport.

Recommendation:

- Define a canonical SDK error compatibility layer that preserves original RPC error
  details while normalizing common fields.
- Add parity tests for known invalid calls against both blurtd-style and Nexus-style
  error responses.

### F-008 — Package documentation previously implied broader parity than proven

Severity: **Low/Medium**  
Class: **Documentation / DX gap**

Impact:

- Users can reasonably infer that named operation types or high-level helper classes
  mean full platform support.
- The current evidence shows raw reachability is broad but typed/broadcast parity is
  partial.

Recommendation:

- Keep this parity analysis as a maintained architecture artifact.
- Add a release checklist item: every new helper must link to canonical evidence and
  tests.

## Roadmap to faithful platform representation

### Phase 0 — Guardrails already started

- Maintain `scripts/platform-parity-audit.js`.
- Regenerate `architecture/parity/generated/*` after canonical source changes.
- Keep `client.call(api, method, params)` documented as the complete raw escape hatch.

### Phase 1 — Consensus serialization parity

Goal: every canonical submitted operation can be serialized correctly or is clearly
marked unsupported.

Work:

1. Generate/lock operation id table from `operations.hpp`.
2. Add serializers for all missing submitted operations.
3. Add binary fixtures for all 37 submitted operations.
4. Remove or mark unsupported any broadcast helper whose operation cannot serialize.

### Phase 2 — Critical Layer 1 helper parity

Prioritize methods that wallets, bots and infrastructure need for correctness:

1. authority/signature methods;
2. transaction status and synchronous broadcast semantics;
3. RC/resource APIs;
4. key/account lookup;
5. account recovery, escrow, savings, withdraw routes;
6. proposal/witness list/find completeness.

### Phase 3 — Nexus bridge parity

Method-name parity for registered `bridge.*` methods is now present. Continue with:

1. response-shape fixtures for profile, post, post header, community, notification
   and referral objects;
2. error behavior fixtures for missing posts, invalid accounts and community lookup;
3. explicit documentation for Nexus compatibility namespaces beyond `bridge.*`.

### Phase 4 — Arg/return model generation

Move from method-name coverage to schema-aware parity:

- parse Layer 1 `FC_REFLECT` structs;
- parse Nexus public function signatures/defaults;
- compare to TypeScript interfaces;
- generate a maintained parity matrix.

### Phase 5 — Long-tail API coverage policy

Decide which canonical APIs should have typed helpers and which should remain raw:

- admin/debug/raw-block APIs may remain raw or test-only;
- production read/write APIs should be typed;
- unsupported or node-configuration-dependent APIs should be documented explicitly.

## Validation performed for this milestone

- Static extraction from canonical Layer 1 and Nexus sources.
- Regenerated generated parity inventory.
- Corrected confirmed `witness_update` operation id divergence.
- Added targeted serializer regression test.
- Full project validation should run before merge/push:

```bash
node scripts/platform-parity-audit.js
npm run docs:check
npm run lint
npm run typecheck
npm test
npm pack --dry-run
```
