14 KiB
14 KiB
Tasks — complete-drive-uri
Every checkbox MUST reflect work actually done in this change. Walk every
### Requirementand#### Scenarioinspecs/drive-uri/spec.mdANDspecs/drive/spec.mdbefore declaring done (§12a).
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Spec authoring
- 1.1 Read
openspec/AGENTS.md§0c, §2b, §2c, §6a, §7, §11, §13, §13a, §14 - 1.2 Read
openspec/archive/2026-05-16-add-drive-uri/proposal.md,_superseded-narrow-deferrals-2026-05-17/{add-drive-uri-writes,add-drive-range-reads}/{proposal,design}.md - 1.3 Read
openspec/specs/drive-uri/spec.mdandopenspec/specs/drive/spec.md - 1.4 Confirm
Drive.{read,write,delete,stat,list,createReadStream,createWriteStream,hydrateFrom,getKeyStatus,getPresence}surface;DriveStorage.capabilitiesflag pattern;StreamingStorageExtensionsshape;MeshDrive.{advertise,unadvertise}shape;ChunkRequestunion;parseUriquery/fragment shape - 1.5 Draft
proposal.md+design.md+tasks.md+ spec deltas - 1.6 Build the numbered Requirement / Scenario implementation checklist (per §0c step 6)
- 1.7
openspec validate complete-drive-uri --strictexits 0
2. @suaveplan/drive — range overload + new codes
- 2.1
src/types/drive.types.ts— addRangeReadOptions { offset?, length?, signal? }; extendDriveStoragewithcapabilities.nativeRange?: booleanand an extendedcreateReadStream?(path, options?: { offset?, length?, signal? })signature - 2.2
src/error-codes.ts— addRANGE_INVALID,RANGE_OUT_OF_BOUNDStoDRIVE_CODES(registry grows 11 → 13) - 2.3
src/error-codes.spec-conformance.test.ts— extend frozen-registry and every-code-starts-with-DRIVE.checks - 2.4
src/file-operations/streams.range.ts— pure slicing transformsliceStream(stream, offset, length)honouringsignal - 2.5
src/file-operations/streams.range.md— sibling doc - 2.6
src/file-operations/streams.ts— overloadcreateReadStream(storage, path, signal?)ANDcreateReadStream(storage, path, options: RangeReadOptions); runtimeinstanceof AbortSignaldiscriminator; synchronous validation →DRIVE.RANGE_INVALID;nativeRange→ forward{ offset, length }; otherwise wrap insliceStream - 2.7
src/file-operations/streams.md— update docs - 2.8
src/file-operations/streams.range.test.ts— boundary table: fully inside one chunk, spans boundary, aligned multi-chunk, tail-to-EOF, zero-length, whole-file, abort mid-stream - 2.9
src/drive/drive.ts—createReadStreamoverload signatures forwarded tostreams.ts; middleware context carriesrange?: { offset, length? } - 2.10
src/drive/drive.test.ts— overload-compat (bare signal still works), options form,DRIVE.RANGE_INVALIDsynchronous throw,DRIVE.RANGE_OUT_OF_BOUNDS(size-known) synchronous throw
3. @suaveplan/drive-uri — error registry + types
- 3.1
src/error-codes/error-codes.ts— extendDRIVE_URI_CODESto 14 codes:TEMPLATE_READ_ONLY,RANGE_INVALID,RANGE_OUT_OF_BOUNDS,MESH_PROPAGATION_TIMEOUT,STAT_UNAVAILABLE,LIST_UNSUPPORTED,INVALID_QUERYadded to the existing 7 - 3.2
src/error-codes/error-codes.ts— extendDriveUriErrorOptionswithrange?: { offset: number; length?: number },fileId?: string,key?: string,value?: string - 3.3
src/error-codes/error-codes.md— describe every code, its call site, and the narrowed role ofWRITE_UNSUPPORTED - 3.4
src/error-codes/error-codes.test.ts— exhaustive registry shape (14 codes, every code starts withDRIVE_URI.,Object.isFrozenholds),DriveUriErrordiscriminants all surface,causepreserved across re-wraps - 3.5
src/types/plugin-options.types.ts— addMeshAdvertiseHook { advertise(fileId, bitset, totalChunks, signal?), unadvertise(fileId, signal?) }; widenTemplateProvider.fetchTemplate(templateId, options?: { nonce?, signal? })(preserve back-compat by making the second arg optional); add?advertise?: MeshAdvertiseHooktoDriveMeshUriPluginOptions - 3.6
src/types/plugin-options.types.md— update
4. @suaveplan/drive-uri — query parsing
- 4.1
src/query/parse-query.ts—parseQuery(query: string | undefined, scheme: string): ParsedQueryreturning{ signalTimeoutMs?, advertise?, nonce? }; unknown keys throwDRIVE_URI.INVALID_QUERY - 4.2
src/query/parse-query.md— sibling doc - 4.3
src/query/parse-query.test.ts— per-scheme allow-list, unknown keys, malformed values (?advertise=maybe,?signal-timeout-ms=-1), empty/missing query
5. @suaveplan/drive-uri — events
- 5.1
src/events/events.ts— typed topic constantsDRIVE_URI_TOPICS = { write: "drive_uri:write", delete: "drive_uri:delete", meshAdvertised: "drive_uri:mesh_advertised" } as const;emit(events, topic, payload)no-op wheneventsis undefined - 5.2
src/events/events.md— sibling doc - 5.3
src/events/events.test.ts— emission against a realEventBusLikefixture; no-op when bus absent
6. @suaveplan/drive-uri — adapter widening
- 6.1
src/adapter/drive-storage-like.ts— widenget/set/delete/exists/stat/listto accept and forwardAbortSignal; addgetMetadata(key, signal?): Promise<StatResult | undefined>mappingDrive.stat → StatResult; addcreateWriteStream(key, body, signal?): Promise<void>consumingReadableStream<Uint8Array>and piping intoDrive.createWriteStream; widencreateReadStreamto accept{ offset?, length?, signal? }; advertisecapabilities = { nativeRange: true, nativeStreams: true } - 6.2
src/adapter/drive-storage-like.md— update for every new method and signature - 6.3
src/adapter/drive-storage-like.test.ts—get/set/delete/exists/stat/listall propagatesignal; pre-aborted signal short-circuits;getMetadatareturnsStatResultshape;createWriteStreamround-trips;createReadStream({ offset, length })forwards;clear()still rejectsWRITE_UNSUPPORTED;listreturns the expected re-serialisable keys
7. @suaveplan/drive-uri — InstrumentedDriveAdapter per-scheme dispatch
- 7.1
src/plugins/drive/drive.streams.ts— replace unconditionalsetrejection with per-scheme dispatch:drive/drive+mesh→super.set(key, value, signal);drive+template→ throwDRIVE_URI.TEMPLATE_READ_ONLY. Same fordeleteandcreateWriteStream - 7.2
src/plugins/drive/drive.streams.ts— pre-aborted signal on every op → throwDRIVE_URI.ABORTED - 7.3
src/plugins/drive/drive.streams.ts— range pass-through oncreateReadStream; OTeldrive.uri.range = "{offset}-{end}"span attribute when present - 7.4
src/plugins/drive/drive.streams.ts— emitdrive_uri:write/drive_uri:deleteevents viaevents/events.tson every success and every failure - 7.5
src/plugins/drive/drive.streams.ts— narrowWRITE_UNSUPPORTEDtoDriveStorageLikeAdapter.clear()only (preserve constant forclearcall site) - 7.6
src/plugins/drive/drive.streams.md— update - 7.7
src/plugins/drive/drive.streams.test.ts— pre-aborted abort short-circuits per op; range round-trip; write-stream round-trip; event emission asserted via real bus fixture
8. @suaveplan/drive-uri — drive:// plugin
- 8.1
src/plugins/drive/drive.ts— invokeparseQuery(parts.query, "drive")and propagatesignal-timeout-ms; reject?advertiseand?noncewithDRIVE_URI.INVALID_QUERY - 8.2
src/plugins/drive/drive.test.ts— full op matrix: read/write/delete/stat/list/exists; AbortSignal threading; pre-aborted abort;?signal-timeout-mshonoured;?advertiserejected;DRIVE_ID_MISMATCHpreserved;INVALID_URIfor malformed inputs
9. @suaveplan/drive-uri — drive+mesh:// plugin
- 9.1
src/plugins/drive-mesh/drive-mesh.ts— invokeparseQuery(parts.query, "drive+mesh"); honour?advertise=true|false; ontruerequiresoptions.advertisehook else throwsDRIVE_URI.CAPABILITY_MISSING(reason:advertise) synchronously atparse - 9.2
src/plugins/drive-mesh/drive-mesh.ts— after a successful write under?advertise=true, invokeoptions.advertise.advertise(fileId, bitset, totalChunks, signal); rejection → wrap asDRIVE_URI.MESH_PROPAGATION_TIMEOUT; on success emitdrive_uri:mesh_advertised - 9.3
src/plugins/drive-mesh/drive-mesh.ts— without?advertise, emitdrive_uri.mesh_write_local_onlyspan event on every successful write - 9.4
src/plugins/drive-mesh/drive-mesh.md— update for opt-in flow + redaction policy - 9.5
src/plugins/drive-mesh/drive-mesh.test.ts— default = no advertise (spy asserts zero calls + local-only span event);?advertise=true→ exactly one advertise call;MeshAdvertiseHookrejection →MESH_PROPAGATION_TIMEOUT; absence of hook with?advertise=true→CAPABILITY_MISSING; full op matrix
10. @suaveplan/drive-uri — drive+template:// plugin
- 10.1
src/plugins/drive-template/drive-template.ts— invokeparseQuery(parts.query, "drive+template"); forward?nonce=…totemplateProvider.fetchTemplate(templateId, { nonce, signal }) - 10.2
src/plugins/drive-template/drive-template.ts—set/delete/createWriteStreamthrowDRIVE_URI.TEMPLATE_READ_ONLYsynchronously, carrying{ scheme, path: key, templateId } - 10.3
src/plugins/drive-template/drive-template.md— update - 10.4
src/plugins/drive-template/drive-template.test.ts— full read-side op matrix post-hydrate; nonce forwarding; write/delete/writeStream all rejectTEMPLATE_READ_ONLY; existing hydration behaviour preserved (memoised, concurrent-share, NOT_AVAILABLE, INVALID)
11. @suaveplan/drive-uri — OTel
- 11.1
src/otel/otel.ts— adddrive_uri.stream_chunks_fetchedhistogram; setter fordrive.uri.rangeanddrive.uri.has_advertisespan attributes; extendredactUrito also strip the fragment - 11.2
src/otel/otel.md— update - 11.3
src/otel/otel.test.ts— every counter/histogram fires per op; range attribute present iff range supplied; advertise attribute on mesh writes; redaction holds for?and#
12. @suaveplan/drive-uri — conformance
- 12.1
src/conformance/conformance.test.ts— re-runrunUriPluginConformancewith full read/write/delete/stat/list/exists/range matrices for all three plugins. Fixtures: 3 valid URIs + 6 invalid + build round-trip + range round-trip per scheme;drive/drive+meshpass full cycle;drive+templaterejects writes withTEMPLATE_READ_ONLY
13. Integration tests (no mocks per CLAUDE.md rule 2)
- 13.1
tests/integration/drive-roundtrip-write.test.ts— real local-storageDrive;resolver.writethenresolver.read; assert equality - 13.2
tests/integration/drive-mesh-roundtrip-write.test.ts— mesh-configuredDrivewith a real advertise hook implementation; default = no advertise;?advertise=true→ exactly one advertise observed - 13.3
tests/integration/template-write-rejection.test.ts— wired template-backedDrive;resolver.writeandresolver.removeboth rejectTEMPLATE_READ_ONLY - 13.4
tests/integration/drive-range-roundtrip.test.ts— write 200 KiB file via local Drive;resolver.open("drive://…", { offset: 60_000, length: 10_000, signal })returns exactly bytes [60 000, 70 000) - 13.5
tests/integration/drive-stat-list-exists.test.ts— full read-side matrix on a real Drive:resolver.stat→StatResult,resolver.exists→ boolean,resolver.list→ URIs that round-trip throughresolver.read
14. Migration audit
- 14.1
grep -rln "DRIVE_URI.WRITE_UNSUPPORTED" packages/ | grep -v "/dist/\|/coverage/\|/drive-uri/"— every hit reviewed; non-matching consumers re-routed ontoTEMPLATE_READ_ONLY/RANGE_*/MESH_PROPAGATION_TIMEOUTwhere appropriate - 14.2 Update
README.mdFeatures + Modules sections to reflect full surface
15. Pre-publish gate (§13)
- 15.1 Spec reconciliation — walk every
### Requirementand#### Scenarioinspecs/drive-uri/spec.mdANDspecs/drive/spec.md; confirm every**Verified by:**test name exists verbatim - 15.2
bunx turbo lint typecheck test --filter=@suaveplan/drive --filter=@suaveplan/drive-uri— green - 15.3
bunx turbo test:coverage --filter=@suaveplan/drive --filter=@suaveplan/drive-uri— 100/100/100/100 on touched modules - 15.4
bunx turbo build --filter=@suaveplan/drive --filter=@suaveplan/drive-uri— green - 15.5 Banned-pattern, barrel, test-runner-import, missing-
.md, README, bare-version, subpath-export, security scans — all clean - 15.6 Dependent sweep:
bunx turbo test --filter=...@suaveplan/drive— green
16. Root-doc refresh (§13b)
- 16.1
bun scripts/folder-reorg/generate-manifest.ts— refreshMANIFEST.md - 16.2
bun scripts/generate-missing.ts— refreshMISSING.yml - 16.3 Update
STATUS.md/SUMMARY.mdparagraphs fordrive-urianddriveto reflect full surface - 16.4
bunx markdownlint-cli2 --fixover touched docs
17. Archival (§14)
- 17.1 Fold
specs/drive-uri/spec.mddelta intoopenspec/specs/drive-uri/spec.md - 17.2 Fold
specs/drive/spec.mddelta intoopenspec/specs/drive/spec.md - 17.3 Move
openspec/changes/complete-drive-uri/→openspec/archive/<yyyy-mm-dd>-complete-drive-uri/ - 17.4 Delete
openspec/changes/_superseded-narrow-deferrals-2026-05-17/(research already folded into this change's archive)