Files
2026-05-27 23:29:53 +01:00

4.4 KiB

Drive Mesh — Spec Delta (drive-mesh-port)

ADDED Requirements

MESH-DEPS-01 — Mesh consumes ChunkSource, not drive core

@suaveplan/drive-mesh MUST NOT import @suaveplan/drive. It MUST consume only the ChunkSource interface exported by @suaveplan/drive-plugin-chunks and DriveTransport interfaces from transport packages.

Verified by: src/mesh.spec-conformance.test.ts (MESH-DEPS-01); package.json import audit.

MESH-SCHED-01 — Racing window for parallel pull

Scheduler MUST issue a request to the best-scored peer for a chunk; after racingWindowMs, MUST issue a parallel request to the next-best peer. The first valid (sig-verified) chunk to return wins; in-flight losers MUST be cancelled.

Verified by: src/scheduler/scheduler.spec-conformance.test.ts (MESH-SCHED-01).

MESH-SCHED-02 — Per-chunk timeout

If a peer does not return a chunk within perChunkTimeoutMs, the request MUST be aborted, the peer's score MUST be penalised, and the next-best peer MUST be tried. Repeated until peer pool is exhausted, then server fallback.

Verified by: src/scheduler/scheduler.spec-conformance.test.ts (MESH-SCHED-02).

MESH-SCHED-03 — Server fallback

When all candidate peers for a chunk fail, the scheduler MUST attempt serverFallback.url via the HTTPS transport. Failure of that fallback MUST throw MeshError(MESH.ALL_PEERS_FAILED) with cause chain including the most recent peer error.

Verified by: src/scheduler/scheduler.spec-conformance.test.ts (MESH-SCHED-03).

MESH-SCORE-01 — Bad sig blocks peer

A peer that delivers a chunk failing sig verification MUST have its score set to -Infinity (effective ban) and MUST NOT be selected for future chunks. If peerPolicy.blocklistOnBadSig is true, the peer is added to a persistent deny list.

Verified by: src/scheduler/peer-score.spec-conformance.test.ts (MESH-SCORE-01).

MESH-SCORE-02 — Score updates on every result

PeerScore MUST update latency EMA, success count, and error count on every chunk-receive completion. Score function MUST be deterministic given inputs.

Verified by: src/scheduler/peer-score.spec-conformance.test.ts (MESH-SCORE-02).

MESH-GOSSIP-01 — Availability bitset gossip

AvailabilityIndex MUST encode peer-availability as a BitSet per fileId, gzip-compressed on the wire. On chunk acquisition, the local peer MUST push an updated advertisement to known peers via the transport. On peer-join, the local peer MUST request advertisements for files it cares about.

Verified by: src/registry/availability-index.spec-conformance.test.ts (MESH-GOSSIP-01).

MESH-BOOTSTRAP-01 — Manifest bootstrap is peer-first

fetchManifest(fileId) MUST first attempt peers via the same transport pipeline (manifest-as-chunk default of the chunks plugin), then fall back to serverFallback.url only when no peer can serve it. Sig verification on the manifest MUST run regardless of source.

Verified by: src/bootstrap/fetch-manifest.spec-conformance.test.ts (MESH-BOOTSTRAP-01).

MESH-FETCH-FILE-01 — End-to-end fetch happy path

mesh.fetchFile(fileId) MUST: (1) fetch manifest, (2) sig-verify manifest, (3) diff against chunks.hasChunks(fileId), (4) schedule missing chunks via Scheduler, (5) resolve when the local bitset is full. Each chunk that arrives MUST be sig-verified by the chunks plugin before persistence.

Verified by: src/bootstrap/fetch-file.spec-conformance.test.ts (MESH-FETCH-FILE-01).

MESH-UPLOAD-01 — Upload backpressure

UploadGovernor MUST limit concurrent uploads per peer to peerPolicy.maxConcurrentUploadsPerPeer. For WebRTC transports, governor MUST honour datachannel bufferedAmount watermark and pause sends when above the high-water mark.

Verified by: src/upload/governor.spec-conformance.test.ts (MESH-UPLOAD-01).

MESH-CODES-01 — Error registry namespaced and frozen

MESH_CODES MUST be declared via defineCodes("MESH", [...]). Object.isFrozen(MESH_CODES) MUST be true. Every code value MUST start with MESH.. MeshError MUST extend SuaveplanError<MeshErrorCode>.

Verified by: src/error-codes.spec-conformance.test.ts (MESH-CODES-01).

MESH-LIFECYCLE-01 — Start/stop are idempotent

mesh.start() and mesh.stop() MUST be idempotent. start opens all configured transports; stop closes them and drains in-flight requests with MeshError(MESH.ABORTED).

Verified by: src/mesh.spec-conformance.test.ts (MESH-LIFECYCLE-01).