Files
psf-memo/docs/reviews/binary-payload-broadcast-summary.md
T

85 lines
4.2 KiB
Markdown

# Architect Review — binary-payload-broadcast
**Reviewed commits**
- `62e0479` Specify binary hash160 broadcast payload for follow/mute (specifier)
- `5e1f473` Broadcast follow/mute/unfollow/unmute hash160 payloads as Uint8Array (coder)
- `53f6b90` / `8d40f2b` Deduplicate Memo follow/mute onto shared MemoStateAction base (refactorer)
**Task**: Follow/unfollow and mute/unmute must broadcast the target's raw
20-byte hash160 (not its display-form cash address text) as the OP_RETURN
payload, and must not depend on the Node-only `Buffer` global. The refactorer
also consolidated the previously near-identical `MemoFollow`/`MemoMute` action
classes onto a shared `MemoStateAction` base.
## Architectural findings
**UI/Core separation — good.** The follow/mute services remain pure logic over
injected `wallet`/`profiles` adapters. No UI, framework, or IO leaked into the
core; everything network/UI-specific stays behind the small wallet/profile
adapter boundaries. The modules remain fully testable without launching a UI or
network.
**Dependency rule — good.** `MemoFollow`/`MemoMute``MemoStateAction`
`MemoAction``hex`/`utf8`. High-level action semantics depend on low-level
byte/hex helpers through a stable base; the direction is inward. The base
subclasses (`MemoFollow`, `MemoMute`) are thin facades exposing only
`follow`/`unfollow` and `mute`/`unmute`.
**Information hiding / encapsulation — good.** `MemoStateAction` encapsulates
the shared validate → toHash160 → hexToBytes → sendOpReturn → reflect
transition. Subclasses expose only config (`followConfig`/`muteConfig`) and
their two public methods; static exports and the public API are preserved. The
20-byte length lives on the base as `PK_HASH_LENGTH`, surfaced on both
subclasses.
**Local code quality.** The refactor is a clean DRY extraction (~150 duplicate
lines removed). Two minor, pre-existing notes (not requiring change):
- Each config carries a `prefix` key that is unused (state actions pass the
prefix explicitly to `_setState`); harmless dead config carried over from the
prior `MemoAction` contract.
- `MemoStateAction.validate` throws a typed error whereas the base
`MemoAction.validate` returns `{ok:false}`; contract difference is intended
and documented in the module header.
No architectural changes were required. The merged work confirms and preserves
the earlier binary `Uint8Array` broadcast behavior (`hexToBytes`) and the
Buffer-free production source.
## Verification
All per-component verification for `psf-memo-client` (the only touched
component) passed.
- **Unit tests**: 280/280 pass
- **Property tests**: 40/40 pass (run separately, as required)
- **Lint**: clean (`standard`)
- **Acceptance**: all 23 generated feature suites pass, including the new
`binary-payload-broadcast.feature`
- **Language mutation** (`mutate4javascript --mutate-all --max-workers 8`):
- `memo-follow.js`: 2 killed, 0 survived, 0 uncovered
- `memo-mute.js`: 2 killed, 0 survived, 0 uncovered
- `memo-state-action.js` (new base): 5 killed, 0 survived, 0 uncovered
- `hex.js`/`memo-action.js` unchanged and unaffected.
- **DRY** (`dry4javascript`) on `memo-state-action.js`/`memo-follow.js`/
`memo-mute.js`: no duplicate candidates.
## Soft Gherkin acceptance mutation (survivors)
`gherkin-mutator --level soft` over `binary-payload-broadcast.feature`:
4 mutations run, 4 survived, 0 killed, 0 errors. All four are single-character
**case** mutations of the shared example cash address (`q``Q`, `x``X`,
`c``C`, `k``K`). Each mutated example is applied consistently on both the
broadcast setup side and the assertion side of its scenario, so the scenario
still passes under the mutation (both sides derive from the same mutated
value). These are **genuine intrinsic equivalents**, not implementation gaps,
and match the documented read-only-payload survivor pattern. Documented here;
no chase performed.
## Handoffs
No functional handoffs sent. The work was a review of an already-functional
refactorer merge; my branch adds only the durable review summary plus the
tool-refreshed manifests (mutation `tested_at` timestamps and the new
acceptance-mutation manifest) from the verification runs. Function and module
hashes in the mutation manifests are unchanged, confirming no code drift.