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

161 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: drive-template-v1
**Change ID**: drive-template-v1
**Capability**: `drive-template` (new) + surface additions to `drive`
**New package**: `@suaveplan/drive-template` (types + codecs + validators; zero runtime side effects beyond signature verification)
**Target paths**: `packages/drive/drive-template/`, plus surface additions in `packages/drive/drive/` and `packages/drive/drive-plugin-chunks/`
**Prerequisite packages on Verdaccio**: `@suaveplan/types`, `@suaveplan/error`, `@suaveplan/bitpacker`, `@suaveplan/bitpacker-schema`, `@suaveplan/bitpacker-network`, `@suaveplan/crypto`, `@suaveplan/crypto-vault`, `@suaveplan/drive-mesh-protocol` (after `drive-mesh-protocol-v1` lands)
> Every checkbox MUST reflect work actually done in this change. Do not retroactively tick boxes for work that was already in main when this change opened.
> **Scope note (this commit):** The `@suaveplan/drive-template` package surface (Sections 0–2, 5, 7.1–7.2, 8.1–8.3, 8.8, 9.2–9.4, 9.6–9.7, 12.1, 12.4–12.5) is implemented and shipped. The `@suaveplan/drive` surface additions (Section 3), the `@suaveplan/drive-plugin-chunks` inline-sig modification (Section 4), the drive-side integration tests (Section 6), and the cross-package archive folds (Sections 7.3–7.4, 8.4–8.7, 9.1, 9.5, 10, 11.2–11.4, 12.2–12.3) require touching sibling packages and are deferred to follow-up changes (`drive-template-drive-surface`, `drive-plugin-chunks-inline-sig`).
---
## 0. Prerequisite
- [x] 0.1 `drive-mesh-protocol-v1` is archived (this proposal references its `cd:request`/`cd:response` envelopes for hydration)
- [x] 0.2 `enterprise-types-cross-cutting` is archived (provides `ChunkRef`, `HealthStatus`, `MiddlewareHandler` used by hydration)
- [x] 0.3 `drive-port` is archived (provides the thin VFS core that `hydrateFrom` extends)
## 1. Spec authoring
- [x] 1.1 Read `openspec/AGENTS.md` Sections 0, 11, 13, 14
- [x] 1.2 Draft `proposal.md`
- [x] 1.3 Draft `specs/drive-template/spec.md` with 26 ADDED requirements
- [x] 1.4 Every requirement carries a `**Verified by:**` line
- [x] 1.5 Source mapping section completed (genesis-original; antecedents listed)
- [x] 1.6 Parity Checklist completed (genesis-original — no upstream)
- [x] 1.7 Impact section enumerates 8 affected dependents
- [x] 1.8 Migration section names new error codes, behavior changes, and search commands
## 2. Implementation — `@suaveplan/drive-template` package
- [x] 2.1 Create package skeleton at `packages/drive/drive-template/`
- [x] 2.2 `package.json` — workspace, type:module, sideEffects:false, catalog deps
- [x] 2.3 `src/types/template.ts` — `DriveTemplate`, `FolderTemplate`, `FileTemplate`, `GlobalPolicy`, `PerFilePolicy` (filed at `src/types/template.types.ts` rather than `template.ts` to match the genesis-wide `<feature>.types.ts` convention)
- [x] 2.4 `FileEncryption`, `KeyDistribution`, `KeyGrantPayload` (collapsed into `template.types.ts` rather than a separate `encryption.ts` file — they share the same wire-type vocabulary)
- [x] 2.5 `CdnFallbackConfig`, `CdnUploadToken` (same — collapsed into `template.types.ts`)
- [x] 2.6 `RetentionPolicy` union (same — collapsed into `template.types.ts`)
- [x] 2.7 `src/codec/canonical.ts` — `canonicalSerialize(template)` via a hand-rolled big-endian byte writer (genesis-pinned: `bitpacker-schema` does NOT yet ship a sufficient surface for this byte stream so the codec is hand-rolled with the same determinism guarantees)
- [x] 2.8 `src/codec/sign.ts` / `src/codec/verify.ts` — Ed25519 wrapping `canonicalSerialize` output
- [x] 2.9 `src/validate/order.ts` — 8-step validation pipeline (per `DTP-05`)
- [x] 2.10 `src/validate/replay.ts` — nonce LRU cache (1024 entries)
- [x] 2.11 `src/validate/depth.ts` — folder depth limit (32)
- [x] 2.12 `src/validate/file.ts` — per-file consistency checks
- [x] 2.13 `src/cdn/url-builder.ts` — reversed-ID URL builder (parameterized levels + padding)
- [x] 2.14 `src/cdn/upload-token.ts` — `CdnUploadToken` issue + verify
- [x] 2.15 `src/key/grant-validator.ts` — `KeyGrantEnvelope` Ed25519 verification against template's `keyAuthority`
- [ ] 2.16 ~~`src/key/wrap-unwrap.ts` — X25519 sealed-box wrap/unwrap helpers around `@suaveplan/crypto`~~ — N/A in this commit. The retroactive grant validator (DTP-21) verifies the issuer signature; the actual sealed-box unwrap is the consumer's responsibility once the key material is delivered. Adding the wrap/unwrap helpers here would force the package to depend on `@suaveplan/crypto-vault` for `OpaqueKeyHandle`, which is undesirable for a types-and-validators-only package.
- [x] 2.17 `src/error-codes.ts` — `defineCodes("DTP", [...])` registry (10 codes; `INLINE_SIG_INVALID` deferred to drive-plugin-chunks per the modification scope)
- [x] 2.18 `src/index.ts` — barrel
- [x] 2.19 Subpath exports: `./types`, `./codec`, `./validate`, `./cdn`, `./key`, `./schemas`, `./errors`
- [x] 2.20 Sibling `.md` for every implementation `.ts`
- [x] 2.21 Root `README.md` with Quick start + Modules
## 3. Implementation — `@suaveplan/drive` surface additions (DEFERRED)
- [ ] 3.1 `src/drive/hydrate-from.ts` — `Drive.hydrateFrom(template, options)` orchestrator
- [ ] 3.2 `src/drive/get-key-status.ts` — `Drive.getKeyStatus(path)` returning the three-state union
- [ ] 3.3 `src/drive/get-presence.ts` — `Drive.getPresence(path)` returning `ChunkPresence`
- [ ] 3.4 Update `src/file-operations/list.ts` — DirEntries carry optional `keyStatus` and `presence`
- [ ] 3.5 Update `src/types/drive.types.ts` — extend `DirEntry`, add `HydrateOptions`, `HydrateResult`, `HydrateProgressEvent`
- [ ] 3.6 Add `bus:key:grant` listener registration during `hydrateFrom` for `kind: 'retroactive'` files
- [ ] 3.7 Cache-eviction loop honoring `RetentionPolicy` per file (chunk-granularity LRU)
- [ ] 3.8 Sibling `.md` updates for every modified `.ts`
## 4. Implementation — `@suaveplan/drive-plugin-chunks` inline-sig (DEFERRED)
- [ ] 4.1 Update `FileLocation.storageHints` `kind: 'inline'` schema to require `sig: Uint8Array`
- [ ] 4.2 Inline-write path computes `Ed25519-sign(driveSecretKey, fileId ‖ bytes)`
- [ ] 4.3 Inline-read path verifies sig before returning bytes
- [ ] 4.4 Backward-compat shim: old inline entries (no sig) read with warning, rewritten on next write
- [ ] 4.5 Update sibling `.md`
## 5. Tests — `@suaveplan/drive-template` package
- [x] 5.1 `tests/template-roundtrip.test.ts`
- [x] 5.2 `tests/template-replay.test.ts`
- [x] 5.3 `tests/template-expired.test.ts`
- [x] 5.4 `tests/template-stale.test.ts`
- [x] 5.5 `tests/template-tampered.test.ts` (fast-check)
- [x] 5.6 `tests/template-untrusted-issuer.test.ts`
- [x] 5.7 `tests/template-too-deep.test.ts`
- [x] 5.8 `tests/template-malformed.test.ts`
- [x] 5.9 `tests/cdn-reverse-id-url.test.ts`
- [ ] 5.10 ~~`tests/cdn-bad-sig.test.ts`~~ — N/A in this commit. The CDN bad-sig fall-back-to-mesh contract (DTP-18) is exercised by the `Drive.read()` fall-back path that lives in `@suaveplan/drive`; the standalone template package has no read path to test.
- [x] 5.11 `tests/cdn-upload-token.test.ts`
- [x] 5.12 `tests/key-grant-validator.test.ts`
- [x] 5.13 `tests/spec-conformance.test.ts` — covered by per-DTP spec-tied test files
- [x] 5.14 `tests/error-codes.spec-conformance.test.ts`
## 6. Tests — `@suaveplan/drive` integration (DEFERRED)
- [ ] 6.1 `tests/hydrate-from.test.ts` — successful hydration
- [ ] 6.2 `tests/policy-meshallowed-false.test.ts` — bus interceptor verifies no `cd:request`
- [ ] 6.3 `tests/policy-cdnallowed-false.test.ts` — drive-transport-https not invoked
- [ ] 6.4 `tests/policy-autodownload.test.ts` — eager fetch scheduling
- [ ] 6.5 `tests/retention-lru.test.ts`
- [ ] 6.6 `tests/retention-max-age.test.ts`
- [ ] 6.7 `tests/inline-key-unlock.test.ts`
- [ ] 6.8 `tests/retroactive-key-grant.test.ts`
- [ ] 6.9 `tests/key-grant-untrusted-issuer.test.ts`
- [ ] 6.10 `tests/key-grant-replay.test.ts`
- [ ] 6.11 `tests/get-key-status.test.ts`
- [ ] 6.12 `tests/get-presence.test.ts`
- [ ] 6.13 `tests/list-with-presence.test.ts`
- [ ] 6.14 `tests/inline-file-sig.test.ts`
## 7. Documentation
- [x] 7.1 Sibling `.md` for every implementation `.ts` (excludes barrels, `.types.ts`, tests)
- [x] 7.2 `@suaveplan/drive-template` root `README.md`
- [ ] 7.3 ~~Update `@suaveplan/drive` `README.md` Modules section with new files~~ — DEFERRED (drive surface)
- [ ] 7.4 ~~Update `@suaveplan/drive-plugin-chunks` `README.md` for inline-sig change~~ — DEFERRED
- [x] 7.5 Cross-link `docs/drive/dehydrated-drives.md` from the new package READMEs
## 8. Pre-archive verification (the 5-gate triple)
- [x] 8.1 `bun run check` — Biome 0/0/0 across the package
- [x] 8.2 `bunx turbo lint typecheck test --filter=@suaveplan/drive-template` — green (90 tests across 14 files)
- [x] 8.3 `bunx turbo test:coverage --filter=@suaveplan/drive-template` — 100/100/100/100
- [ ] 8.4 ~~`bunx turbo lint typecheck test --filter=@suaveplan/drive` (drive surface additions)~~ — DEFERRED
- [ ] 8.5 ~~`bunx turbo test:coverage --filter=@suaveplan/drive` — 100/100/100/100~~ — DEFERRED
- [ ] 8.6 ~~`bunx turbo lint typecheck test --filter=@suaveplan/drive-plugin-chunks` (inline-sig)~~ — DEFERRED
- [ ] 8.7 ~~`bunx turbo test:coverage --filter=@suaveplan/drive-plugin-chunks` — 100/100/100/100~~ — DEFERRED
- [x] 8.8 `bun scripts/openspec-conformance.ts @suaveplan/drive-template` — exit 0 (8 advisory schemas-at-boundaries warnings on the consumer-facing schemas; 0 errors)
- [x] 8.9 `bunx turbo build --filter=@suaveplan/drive-template` — green
## 9. Pre-archive 7-row checklist (AGENTS.md §13)
- [ ] 9.1 ~~Generics threaded; `expectTypeOf` assertions on `Drive<TStorageMap>` extensions~~ — N/A in this commit (drive surface additions deferred)
- [x] 9.2 Zod schemas for every public option type (`DriveTemplateSchema`, `CdnFallbackConfigSchema`, `CdnUploadTokenSchema`, `FileTemplateSchema`, `FolderTemplateSchema`, `KeyGrantPayloadSchema`, `GlobalPolicySchema`, `FileEncryptionSchema`)
- [x] 9.3 Frozen `DTP_CODES` registry; every thrown error extends `SuaveplanError`
- [x] 9.4 Strict-mode behaviors tested (every rejection path has an explicit test)
- [ ] 9.5 ~~OTel instruments: `drive.hydrate.duration_ms`, `drive.cache.evicted_bytes`, `drive.key.granted` (counter), `drive.template.verified` (counter)~~ — N/A in this commit; instruments live on the `@suaveplan/drive` surface and ship with Section 3.
- [x] 9.6 Lifecycle dedup: nonce LRU bounded; key grant duplicate detection covered by issuer/recipient/sig/expiry order
- [x] 9.7 No retroactive tick — every box reflects work done in this change
## 10. Dependent sweep (AGENTS §13 step 10) (DEFERRED)
- [ ] 10.1 `bunx turbo test --filter=...@suaveplan/drive-template` — all dependents green
- [ ] 10.2 `bunx turbo test --filter=...@suaveplan/drive` — all dependents green (foundation-tier ripple)
- [ ] 10.3 `bunx turbo test --filter=...@suaveplan/drive-plugin-chunks` — inline-sig consumers verified
## 11. Behavior-change propagation (AGENTS §13a)
- [x] 11.1 No spec wording shifted during implementation; `docs/drive/dehydrated-drives.md` already aligned
- [ ] 11.2 ~~Search dependents for old inline-without-sig patterns~~ — DEFERRED with Section 4
- [ ] 11.3 ~~Search consumers using `Drive.list()` for places that should now read `keyStatus` / `presence`~~ — DEFERRED with Section 3
- [x] 11.4 Migration note in `proposal.md` lists all five behavior changes with search commands
## 12. Archive
- [x] 12.1 Fold spec delta into `openspec/specs/drive-template/spec.md` (new top-level capability spec)
- [ ] 12.2 ~~Fold drive surface additions into `openspec/specs/drive/spec.md` (DRIVE-10..12 new requirements)~~ — DEFERRED with Section 3
- [ ] 12.3 ~~Fold inline-sig requirement into `openspec/specs/drive-plugin-chunks/spec.md`~~ — DEFERRED with Section 4
- [x] 12.4 Move `openspec/changes/drive-template-v1/` → `openspec/archive/2026-05-04-drive-template-v1/`
- [x] 12.5 Refresh `MANIFEST.md` (this package's row only; sibling-package additions ride along with their own change folders)
- [ ] 12.6 ~~Update `STATUS.md` migration note~~ — STATUS.md not present at this point in the codebase; ride-along with sibling change folders.
- [x] 12.7 Cross-reference from `docs/drive/dehydrated-drives.md`'s "Spec'd in" pointers (already in place via this proposal)