Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
# Tasks: complete-rng-unification
## 0. Pre-flight (non-negotiable)
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in 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.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
## 0. Pre-flight (mandatory before any edit)
- [ ] 0.1 Confirm `bunx turbo typecheck test --filter=@suaveplan/types` green at HEAD (baseline).
- [ ] 0.2 Confirm `bunx turbo typecheck test --filter=@suaveplan/testing` green at HEAD (baseline).
- [ ] 0.3 Confirm `bunx turbo typecheck test --filter=@suaveplan/crypto-core` green at HEAD (baseline).
- [ ] 0.4 Confirm `bunx turbo typecheck test --filter=@suaveplan/crypto` green at HEAD (baseline).
- [ ] 0.5 Confirm `bunx turbo typecheck test --filter=@suaveplan/mime` green at HEAD (baseline).
- [ ] 0.6 Re-run the exhaustive grep documented in `proposal.md` § Audit and confirm zero NEW matches have appeared since this proposal was drafted.
## 1. `@suaveplan/types` — spec-only tightening
- [ ] 1.1 Update `packages/core/types/src/rng.md` to add a "Single source of truth" section noting that `@suaveplan/types` is the only canonical home for `Rng` across the monorepo and the permitted forms of downstream redeclaration (consume-direct, extend, or distinct-concept-under-distinct-name).
- [ ] 1.2 No code change to `packages/core/types/src/rng.ts` (shape is already correct).
- [ ] 1.3 `bunx turbo typecheck test --filter=@suaveplan/types` — green.
- [ ] 1.4 `bunx turbo test --filter=...@suaveplan/types` — foundation dependent sweep green (mandatory per §13 step 10).
## 2. `@suaveplan/testing` — migrate Rng interface to re-export
- [ ] 2.1 Locate local declaration: `packages/testing/testing/src/context/context.ts` line 45 (`export interface Rng { nextUint32(): number; nextFloat(): number }`).
- [ ] 2.2 Confirm structural compatibility — required members are an exact subset of canonical; canonical adds two OPTIONAL members which existing `cryptoRng` / `seededRng` may omit.
- [ ] 2.3 Add `"@suaveplan/types": "workspace:^"` to `packages/testing/testing/package.json` `dependencies` (rule 8 exception: testing-infra may depend on `@suaveplan/types` for types-only — confirm byte-size guard still passes).
- [ ] 2.4 Replace `export interface Rng { ... }` with:
```ts
// Back-compat re-export of @suaveplan/types' canonical Rng. Prefer importing
// Rng from @suaveplan/types directly; this forwarder will be removed in the
// follow-up `remove-deprecated-rng-aliases` change.
export type { Rng } from "@suaveplan/types";
```
- [ ] 2.5 Confirm `cryptoRng: Rng = { ... }` and `seededRng(seed): Rng` still typecheck against the canonical (they provide only the required members).
- [ ] 2.6 Update sibling `context.md` API reference: note `Rng` is now a re-export of canonical; cross-link to `@suaveplan/types`.
- [ ] 2.7 No barrel edits needed — `src/index.ts:61` `export type { Clock, Rng } from "./context/context.js"` continues to forward correctly.
- [ ] 2.8 `bunx turbo typecheck --filter=@suaveplan/testing` — green.
- [ ] 2.9 `bunx turbo test --filter=@suaveplan/testing` — green, zero assertion edits.
- [ ] 2.10 `bunx turbo test:coverage --filter=@suaveplan/testing` — 100/100/100/100 preserved.
- [ ] 2.11 Dependent sweep: `bunx turbo test --filter=...@suaveplan/testing` — every test in the monorepo flows through `@suaveplan/testing`, must be green.
## 3. `@suaveplan/crypto-core` — drop misleading Rng alias + defaultRng
- [ ] 3.1 Locate local declarations in `packages/crypto/crypto-core/src/primitives/random-bytes/random-bytes.ts`:
- line 9: `export type ByteSource = (n: number) => Uint8Array;` — KEEP.
- line 12: `export type Rng = ByteSource;` — REMOVE.
- line 19: `export const defaultByteSource: ByteSource = ...` — KEEP.
- line 36: `export const defaultRng: ByteSource = defaultByteSource;` — REMOVE.
- line 38–41: `RandomBytesOptions { byteSource?: ByteSource; rng?: ByteSource }` — drop the `rng` field.
- line 62: `const source = options.byteSource ?? options.rng ?? defaultByteSource;` — simplify to `options.byteSource ?? defaultByteSource`.
- [ ] 3.2 Add back-compat re-export at the bottom of `random-bytes.ts`:
```ts
// Back-compat re-export of @suaveplan/types' canonical Rng. Prefer importing
// Rng from @suaveplan/types directly. This forwarder exists for one release
// cycle — the legacy local `type Rng = ByteSource` alias was structurally
// incompatible with canonical (callable vs object) and has been removed.
// The follow-up `remove-deprecated-rng-aliases` change will delete this line.
export type { Rng } from "@suaveplan/types";
```
- [ ] 3.3 Confirm `@suaveplan/types` is in `packages/crypto/crypto-core/package.json` `dependencies` (it already is per `MANIFEST.md`).
- [ ] 3.4 Update barrel `packages/crypto/crypto-core/src/primitives/random-bytes/index.ts`:
- keep `type ByteSource`, `defaultByteSource`, `type RandomBytesOptions`, `randomBytes`.
- keep `type Rng` (now forwards canonical via the back-compat re-export).
- drop `defaultRng`.
- [ ] 3.5 Update barrel `packages/crypto/crypto-core/src/primitives/index.ts` — same: drop `defaultRng`, keep `Rng` forwarding canonical.
- [ ] 3.6 Update barrel `packages/crypto/crypto-core/src/index.ts` — same: drop `defaultRng`, keep `Rng` forwarding canonical.
- [ ] 3.7 Update sibling `random-bytes.md`: drop `Rng` and `defaultRng` from local API reference; add "Implementation Notes" section explaining the type-class distinction (canonical `Rng` is an object; `ByteSource` is a callable; the local `Rng` is now a back-compat re-export of the canonical, not the legacy callable alias).
- [ ] 3.8 Repo-internal callsite check — confirm no `crypto-core` test or impl file uses `defaultRng` or `RandomBytesOptions.rng`:
```bash
grep -rn "defaultRng\b\|\.rng:\|, rng:" packages/crypto/crypto-core/src/ --include="*.ts"
```
- [ ] 3.9 `bunx turbo typecheck --filter=@suaveplan/crypto-core` — green.
- [ ] 3.10 `bunx turbo test --filter=@suaveplan/crypto-core` — green, zero assertion edits.
- [ ] 3.11 `bunx turbo test:coverage --filter=@suaveplan/crypto-core` — 100/100/100/100 preserved.
- [ ] 3.12 Dependent sweep: `bunx turbo test --filter=...@suaveplan/crypto-core` — every consumer (`crypto`, `crypto-rsa`, `crypto-vault`, `crypto-keys`, `vault`, `vault-sync`, `webauthn`, `crypto-cli`, `crypto-bin`, `crypto-sodium`, `crypto-browser`) green.
## 4. `@suaveplan/crypto` — update forwarder barrel
- [ ] 4.1 Locate `Rng` and `defaultRng` re-exports in `packages/crypto/crypto/src/index.ts` (currently re-exported from `@suaveplan/crypto-core` block).
- [ ] 4.2 Keep the `Rng` re-export (it now forwards canonical via `crypto-core`'s back-compat re-export).
- [ ] 4.3 Drop the `defaultRng` re-export.
- [ ] 4.4 Repo-internal callsite check — confirm no `crypto` test or impl file uses `defaultRng`:
```bash
grep -rn "defaultRng\b" packages/crypto/crypto/src/ --include="*.ts"
```
- [ ] 4.5 If any `.md` in `packages/crypto/crypto/src/` mentions `Rng` or `defaultRng`, update to reference `@suaveplan/types` (canonical) and `defaultByteSource` (correct name for the dropped alias).
- [ ] 4.6 `bunx turbo typecheck --filter=@suaveplan/crypto` — green.
- [ ] 4.7 `bunx turbo test --filter=@suaveplan/crypto` — green.
- [ ] 4.8 `bunx turbo test:coverage --filter=@suaveplan/crypto` — 100/100/100/100 preserved.
## 5. `@suaveplan/mime` — rename file-scope ByteSource
- [ ] 5.1 Locate `packages/data/mime/src/detection/from-stream.ts` line 19: `type ByteSource = ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>`.
- [ ] 5.2 Rename to `StreamByteSource`; update the single reference at line 30 (`source: StreamByteSource`).
- [ ] 5.3 Confirm the type is NOT exported from `from-stream.ts` (it is `type`, not `export type`) — name collision is internal only, but renaming eliminates future confusion.
- [ ] 5.4 Update sibling `from-stream.md` if it mentions `ByteSource`.
- [ ] 5.5 Confirm `from-stream-reader.ts` (which uses `ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>` inline) is unaffected.
- [ ] 5.6 `bunx turbo typecheck --filter=@suaveplan/mime` — green.
- [ ] 5.7 `bunx turbo test --filter=@suaveplan/mime` — green.
- [ ] 5.8 `bunx turbo test:coverage --filter=@suaveplan/mime` — 100/100/100/100 preserved.
## 6. Spec deltas
- [ ] 6.1 Author `specs/types/spec.md` delta with `## MODIFIED Requirements` block on the canonical-Rng requirement, adding the single-source-of-truth clause.
- [ ] 6.2 Author `specs/testing/spec.md` delta with `## MODIFIED Requirements` block documenting `Rng` is now a back-compat re-export.
- [ ] 6.3 Author `specs/crypto-core/spec.md` delta with `## MODIFIED Requirements` documenting: `Rng` is canonical re-export; `defaultRng` is removed; `RandomBytesOptions.rng` field is removed; `ByteSource` is preserved under its real name (callable byte producer, distinct from `Rng`).
- [ ] 6.4 Author `specs/crypto/spec.md` delta with `## MODIFIED Requirements` documenting the forwarder barrel update.
- [ ] 6.5 Author `specs/mime/spec.md` delta with `## MODIFIED Requirements` documenting the `ByteSource` → `StreamByteSource` rename.
- [ ] 6.6 Every requirement carries `**Verified by:**` line at authoring time.
## 7. Repo-wide verification gate
- [ ] 7.1 Repo-wide grep returns exactly the documented set:
```bash
grep -rln "interface Rng\b\|type Rng\s*=\|class Rng\b\|RngLike\b\|RandomSource\b" \
packages/ --include="*.ts" --exclude-dir=dist --exclude-dir=node_modules
```
Allowed hits:
- `packages/core/types/src/rng.ts` (canonical declaration)
- `packages/random/pseudo-random/src/types/seeded-rng.types.ts` (legitimate `SeededRng extends Rng`)
- back-compat `export type { Rng } from "@suaveplan/types"` forwarder lines in `crypto-core/random-bytes`, `crypto-core/primitives/index`, `crypto-core/primitives/random-bytes/index`, `crypto-core/index`, `crypto/index`, `testing/context`
- [ ] 7.2 Repo-wide `ByteSource` grep — confirm zero unintended renames; only the `mime` file-scope occurrence has changed.
- [ ] 7.3 Repo-wide `defaultRng` grep returns zero hits in genesis source (it remains in `@suaveplan/crypto-rsa/src/encrypt/default-rng.ts` as a `function defaultRng(): Rng` — that is correct usage, not the dropped alias).
- [ ] 7.4 `bunx turbo lint typecheck --filter=...` (full repo) — green.
## 8. Doc-drift + behaviour-change propagation
- [ ] 8.1 Per CLAUDE.md §4a: every `.ts` edited has its sibling `.md` updated in the same change set (covered by tasks 1.1, 2.6, 3.7, 4.5, 5.4).
- [ ] 8.2 Per CLAUDE.md §13a: the `## Migration` note is authored in `proposal.md` (already done) — verify the search command works and produces the expected callsites.
- [ ] 8.3 Update root `MIGRATION.md` with the per-package migration note (canonical `Rng` import path, `defaultRng` → `defaultByteSource`, `RandomBytesOptions.rng` → `byteSource`).
- [ ] 8.4 Repo-wide consumer scan:
```bash
grep -rln "from ['\"]@suaveplan/\(crypto-core\|crypto\|testing\)['\"]" packages/ \
| xargs grep -l "Rng\b" 2>/dev/null
```
Every hit either continues to compile via the back-compat forwarder OR is updated to canonical import in this change set.
## 9. Root-doc refresh + markdownlint
- [ ] 9.1 No package add/remove; `MANIFEST.md` dep graph gains one edge (`@suaveplan/testing → @suaveplan/types`). Run `bun scripts/folder-reorg/generate-manifest.ts`.
- [ ] 9.2 `STATUS.md` unchanged (no new pending → completed transitions).
- [ ] 9.3 `SUMMARY.md` — update `@suaveplan/types`, `@suaveplan/testing`, `@suaveplan/crypto-core`, `@suaveplan/crypto` paragraphs to mention the canonical `Rng` clause and the back-compat forwarder.
- [ ] 9.4 `MIGRATION.md` — updated per task 8.3.
- [ ] 9.5 `bunx markdownlint-cli2 --fix` — green.
## 10. Fold + archive
- [ ] 10.1 Fold `specs/types/spec.md` delta into `openspec/specs/types/spec.md`.
- [ ] 10.2 Fold `specs/testing/spec.md` delta into `openspec/specs/testing/spec.md`.
- [ ] 10.3 Fold `specs/crypto-core/spec.md` delta into `openspec/specs/crypto-core/spec.md`.
- [ ] 10.4 Fold `specs/crypto/spec.md` delta into `openspec/specs/crypto/spec.md`.
- [ ] 10.5 Fold `specs/mime/spec.md` delta into `openspec/specs/mime/spec.md`.
- [ ] 10.6 Move `openspec/changes/complete-rng-unification/` → `openspec/archive/<yyyy-mm-dd>-complete-rng-unification/`.
- [ ] 10.7 Open the follow-up `remove-deprecated-rng-aliases` change to track removal of the back-compat re-export forwarders after one release cycle.