You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SWARM_SPEC §5 defines 15 rejection rules every node MUST agree on. They are the single chokepoint that decides whether a received wire record influences local state. Implementing them as one pure, well-tested function now means every later ingest path (lessons endpoint, hubs endpoint, peer relay) becomes a one-line validate(...) call.
Background — read this BEFORE starting
mcp__vector-memory__prime_context with task_description "implement wire-validator rejection rules for mycelium swarm"
Read docs/SWARM_SPEC.md §5 — the 15-rule list is normative
Read src/services/wire-types.ts (Phase 3a) — depends on its types and canonicalizeForSigning
Skip 14 (local trust — caller-side) and 15 (body cap — transport-layer). Document this skip in a top-of-file comment.
For rule 6 use the multihash multiformats helper already in the repo (introduced for Phase 1b — init-node-identity.mjs); if it's not exported, export it from there in this PR.
For rule 5 use verifySignature from signature.ts and the getPubkeyForNode callback from opts.
Acceptance criteria
src/services/wire-validator.ts exists and exports validateWireRecord
tests/services/wire-validator.test.ts covers:
one valid example per kind → { ok: true }
at least one negative case for each of rules 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13 (12 negative tests minimum), each asserting { ok: false, rule: <n> }
Pure function — no DB, no HTTP, no file I/O
All side-channel data (pubkey lookup, current time) injected via opts
Hard constraints
DO NOT modify SWARM_SPEC.
DO NOT implement rules 14 or 15.
DO NOT cache or memoize — keep this as a pure function for testability.
Why
SWARM_SPEC §5 defines 15 rejection rules every node MUST agree on. They are the single chokepoint that decides whether a received wire record influences local state. Implementing them as one pure, well-tested function now means every later ingest path (lessons endpoint, hubs endpoint, peer relay) becomes a one-line
validate(...)call.Background — read this BEFORE starting
mcp__vector-memory__prime_contextwith task_description "implement wire-validator rejection rules for mycelium swarm"docs/SWARM_SPEC.md§5 — the 15-rule list is normativesrc/services/wire-types.ts(Phase 3a) — depends on its types andcanonicalizeForSigningsrc/services/signature.ts(PR feat(swarm): signature service — Ed25519 sign/verify over JCS (#77) #82) — depends on itsverifySignatureWhat this issue delivers
A new file
src/services/wire-validator.tsexporting:Implement rules 1-13 from §5. Specifically:
spec_versionmajor != opts.ourSpecMajornode_id!= multihash(pubkey)signed_at> now + 5 minsigned_at< now − 90 days (Lesson, HubAnchor only)signed_at < created_atsynthesized_from_cluster_size < 2endpoint_urlnot httpsSkip 14 (local trust — caller-side) and 15 (body cap — transport-layer). Document this skip in a top-of-file comment.
For rule 6 use the multihash multiformats helper already in the repo (introduced for Phase 1b —
init-node-identity.mjs); if it's not exported, export it from there in this PR.For rule 5 use
verifySignaturefromsignature.tsand thegetPubkeyForNodecallback from opts.Acceptance criteria
src/services/wire-validator.tsexists and exportsvalidateWireRecordtests/services/wire-validator.test.tscovers:{ ok: true }{ ok: false, rule: <n> }optsHard constraints