10 KiB
Capability Spec Delta: drive-uri (drive-uri)
Package: @suaveplan/drive-uri
Status: PROPOSED
Every requirement carries a
**Verified by:**line at authoring time naming planned tests.
ADDED Requirements
Requirement: drive:// SHALL support writes and removes via the resolver surface
The drive plugin's instrumented adapter SHALL delegate set(key, value, signal?) to Drive.write(path, data, { signal }) and delete(key, signal?) to Drive.delete(path, signal). Successful writes SHALL increment drive_uri.writes_total{scheme:"drive", outcome:"success"}; successful removes SHALL increment drive_uri.deletes_total{scheme:"drive", outcome:"success"}. The AbortSignal passed to resolver.write(uri, body, signal) / resolver.remove(uri, signal) SHALL be threaded through to the underlying Drive call. A pre-aborted signal SHALL short-circuit to DRIVE_URI.ABORTED without invoking Drive.write / Drive.delete.
Scenario: write round-trips via Drive.write
- WHEN
resolver.write("drive://primary/clip.mov", bytes)is called against adriveplugin bound to a real local-storageDrive - THEN the call resolves with
void, the underlyingDrivereports the path persisted, andresolver.read("drive://primary/clip.mov")returnsbytes
Scenario: remove delegates to Drive.delete
- WHEN
resolver.remove("drive://primary/clip.mov")is called after a successful write - THEN the call resolves with
trueand a subsequentresolver.read(...)rejects withSTORAGE_URI.NOT_FOUND
Scenario: AbortSignal threads through writes
- WHEN a
resolver.write(...)is invoked with anAbortSignalthat aborts mid-call - THEN the call rejects with
DRIVE_URI.ABORTEDand any underlyingDrive.writeinvocation observes the abort
Verified by: src/plugins/drive/drive.test.ts::"writes succeed and round-trip via Drive.write" AND src/plugins/drive/drive.test.ts::"removes delegate to Drive.delete and return its boolean" AND src/plugins/drive/drive.test.ts::"writes propagate AbortSignal to Drive.write" AND tests/integration/drive-roundtrip-write.test.ts::"resolver.write then resolver.read round-trips on a real Drive"
Requirement: drive+mesh:// SHALL support writes/removes locally without triggering mesh re-advertisement
The drive+mesh plugin's instrumented adapter SHALL delegate set/delete to the underlying Drive exactly as the drive scheme does. It SHALL NOT call mesh.advertise(...) or any equivalent gossip API; gossip propagation remains the consumer's responsibility. On every successful drive+mesh:// write, the plugin SHALL emit a span event named drive_uri.mesh_write_local_only carrying { scheme: "drive+mesh", path } so operators can audit that the contract holds.
Scenario: write persists locally without auto-advertise
- WHEN
resolver.write("drive+mesh://swarmA/clip.mov", bytes)is called against a mesh-configuredDrivewith a spy transport - THEN the call resolves with
void, the bytes are persisted viaDrive.write, and the spy transport records zeroadvertise(...)calls
Scenario: explicit consumer-side advertise still works
- WHEN the consumer invokes
mesh.advertise(fileId, bitset, totalChunks)after the write resolves - THEN the spy transport records one outbound advertisement
Scenario: span event marks local-only write
- WHEN any successful
drive+mesh://write completes - THEN the active span carries an event
drive_uri.mesh_write_local_onlywith attributes{ scheme: "drive+mesh", path }
Verified by: src/plugins/drive-mesh/drive-mesh.test.ts::"writes succeed without triggering mesh.advertise" AND src/plugins/drive-mesh/drive-mesh.test.ts::"writes emit drive_uri.mesh_write_local_only span event" AND tests/integration/drive-mesh-roundtrip-write.test.ts::"explicit mesh.advertise after write produces an outbound advertisement"
Requirement: drive+template:// writes and removes SHALL be permanently rejected with DRIVE_URI.TEMPLATE_READ_ONLY
The drive+template plugin's instrumented adapter SHALL throw a DriveUriError with code === "DRIVE_URI.TEMPLATE_READ_ONLY" on every set and delete call, before any delegation to Drive. The error SHALL carry scheme: "drive+template", the offending path, and the templateId that was bound. The rejection SHALL increment drive_uri.writes_total{scheme:"drive+template", outcome:"error"} for writes and drive_uri.deletes_total{scheme:"drive+template", outcome:"error"} for removes. The error message SHALL state that template-backed drives require authority re-signing not held by the resolver.
Scenario: write against drive+template:// rejects with TEMPLATE_READ_ONLY
- WHEN
resolver.write("drive+template://tplA/clip.mov", bytes)is called - THEN the call rejects with
DriveUriErrorwhosecode === "DRIVE_URI.TEMPLATE_READ_ONLY",scheme === "drive+template",path === "clip.mov", andtemplateId === "tplA"
Scenario: remove against drive+template:// rejects with TEMPLATE_READ_ONLY
- WHEN
resolver.remove("drive+template://tplA/clip.mov")is called - THEN the call rejects with
DriveUriErrorwhosecode === "DRIVE_URI.TEMPLATE_READ_ONLY"
Scenario: rejection increments error counters
- WHEN any
drive+template://write rejection fires - THEN
drive_uri.writes_total{scheme:"drive+template", outcome:"error", code:"DRIVE_URI.TEMPLATE_READ_ONLY"}increments by 1
Verified by: src/plugins/drive-template/drive-template.test.ts::"writes reject with DRIVE_URI.TEMPLATE_READ_ONLY" AND src/plugins/drive-template/drive-template.test.ts::"removes reject with DRIVE_URI.TEMPLATE_READ_ONLY" AND src/otel/otel.test.ts::"increments writes_total{outcome:error,code:TEMPLATE_READ_ONLY} on template writes" AND tests/integration/template-write-rejection.test.ts::"resolver.write and resolver.remove both reject on template-backed drive"
Requirement: DRIVE_URI_CODES SHALL include TEMPLATE_READ_ONLY
The DRIVE_URI_CODES registry produced by defineCodes("DRIVE_URI", […]) SHALL include TEMPLATE_READ_ONLY as a distinct, fully-qualified DRIVE_URI.TEMPLATE_READ_ONLY code. The DriveUriErrorCode union SHALL include it. The code SHALL be reachable from real call sites (the drive+template adapter's set and delete overrides).
Scenario: registry exposes TEMPLATE_READ_ONLY
- WHEN
DRIVE_URI_CODES.TEMPLATE_READ_ONLYis read - THEN the value is the string
"DRIVE_URI.TEMPLATE_READ_ONLY"
Scenario: registry remains size-stable elsewhere
- WHEN the registry's key count is asserted
- THEN it equals 8, comprising the original 7 plus
TEMPLATE_READ_ONLY
Verified by: src/error-codes/error-codes.test.ts::"includes TEMPLATE_READ_ONLY and totals 8 codes"
Requirement: runUriPluginConformance writes suite SHALL pass for drive/drive+mesh and reject for drive+template
The conformance harness re-exported from @suaveplan/storage-uri SHALL be re-run against each of the three plugins. The drive and drive+mesh plugins SHALL pass the full write/read/exists/list/remove cycle. The drive+template plugin SHALL continue to fail the write/remove portions of the suite, but with DRIVE_URI.TEMPLATE_READ_ONLY as the rejection code rather than WRITE_UNSUPPORTED.
Scenario: conformance writes suite passes for drive
- WHEN the harness is configured with a real-
Drive-backeddriveplugin and asked to exercise the writes suite - THEN every write/read round-trip assertion holds and no test is skipped
Scenario: conformance writes suite passes for drive+mesh
- WHEN the harness is configured with a mesh-configured
Drive-backeddrive+meshplugin - THEN every write/read round-trip holds; no
advertiseis observed on the spy transport during the harness
Scenario: conformance writes suite rejects drive+template with the new code
- WHEN the harness is configured with a
drive+templateplugin and exercises any write/remove - THEN every such call rejects with
DRIVE_URI.TEMPLATE_READ_ONLY
Verified by: src/conformance/conformance.test.ts::"writes suite passes for drive plugin" AND src/conformance/conformance.test.ts::"writes suite passes for drive+mesh plugin" AND src/conformance/conformance.test.ts::"writes suite rejects drive+template with TEMPLATE_READ_ONLY"
MODIFIED Requirements
Requirement: DRIVE_URI.WRITE_UNSUPPORTED SHALL only be raised by DriveStorageLikeAdapter.clear()
Previously the three plugins rejected every set (write) call with DRIVE_URI.WRITE_UNSUPPORTED. The code SHALL now be raised by exactly one call site: DriveStorageLikeAdapter.clear(), which intentionally refuses to wipe an entire Drive through the URI surface and points the caller at Drive.delete(path) (or resolver.remove(uri)). The code SHALL remain in DRIVE_URI_CODES so consumers that already assert on it for the clear() path continue to function unchanged. No other call site in drive-uri SHALL raise WRITE_UNSUPPORTED.
Scenario: clear() still rejects with WRITE_UNSUPPORTED
- WHEN any consumer invokes
adapter.clear()on aDriveStorageLikeAdapter(directly or via an unusual resolver extension) - THEN the call rejects with
DriveUriErrorwhosecode === "DRIVE_URI.WRITE_UNSUPPORTED"
Scenario: set on drive:// no longer raises WRITE_UNSUPPORTED
- WHEN
resolver.write("drive://primary/x", bytes)is called against a realDrive - THEN the call resolves with
voidand noDRIVE_URI.WRITE_UNSUPPORTEDis thrown anywhere in the call chain
Scenario: set on drive+template:// raises TEMPLATE_READ_ONLY not WRITE_UNSUPPORTED
- WHEN
resolver.write("drive+template://tplA/x", bytes)is called - THEN the rejection's
codeisDRIVE_URI.TEMPLATE_READ_ONLY, neverDRIVE_URI.WRITE_UNSUPPORTED
Verified by: src/adapter/drive-storage-like.test.ts::"clear() rejects with DRIVE_URI.WRITE_UNSUPPORTED" AND src/plugins/drive/drive.test.ts::"writes succeed and round-trip via Drive.write" AND src/plugins/drive-template/drive-template.test.ts::"writes reject with DRIVE_URI.TEMPLATE_READ_ONLY"