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

76 lines
4.4 KiB
Markdown

# 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`).