Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1697c3b
docs: add forensic architectural audit report
flyingrobots Mar 4, 2026
12205b0
feat(roadmap): add M16 Capstone milestone — audit remediation
flyingrobots Mar 4, 2026
7dfbc0e
fix(errors): guard Error.captureStackTrace for cross-runtime portability
flyingrobots Mar 4, 2026
c713d63
chore(hooks): rename git-hooks → hooks, add pre-commit lint gate
flyingrobots Mar 4, 2026
5240536
fix(lint): fix curly brace and unused imports from 16.8/16.9
flyingrobots Mar 4, 2026
8163d46
fix(crypto): normalize adapter behavioral contracts across runtimes
flyingrobots Mar 4, 2026
ea4eeae
feat(restore): add maxRestoreBufferSize guard for buffered restore
flyingrobots Mar 4, 2026
23ce968
feat(cli): add passphrase file input and interactive TTY prompt
flyingrobots Mar 4, 2026
cf91548
feat(chunking): enforce 100 MiB upper bound on chunk size
flyingrobots Mar 4, 2026
314f36f
feat(crypto): add encryption buffer guard to WebCryptoAdapter
flyingrobots Mar 4, 2026
263c608
feat(store): warn when CDC chunking is combined with encryption
flyingrobots Mar 4, 2026
23474de
feat(store): track orphaned blobs on stream failure
flyingrobots Mar 4, 2026
605036f
perf(chunking): replace Buffer.concat loop with pre-allocated buffer
flyingrobots Mar 4, 2026
47828e5
refactor(api): rename lifecycle methods with deprecated aliases
flyingrobots Mar 4, 2026
67f9bcd
feat(security): add KDF brute-force awareness metrics and CLI delay
flyingrobots Mar 4, 2026
aae160a
feat(security): add encryption counter and move SECURITY.md to root
flyingrobots Mar 4, 2026
fd3eab4
docs(roadmap): add V7 (OTLP observability adapter) and V8 (auto-rotat…
flyingrobots Mar 4, 2026
4d908a0
test(vault): wire observability port into VaultService tests
flyingrobots Mar 4, 2026
804cfd5
docs(changelog): fix test count (46, not 78)
flyingrobots Mar 4, 2026
8cb6c34
docs(changelog): drop exact test count from observability entry
flyingrobots Mar 4, 2026
a1dc2c9
fix(cli): defer passphrase prompt until vault encryption is confirmed
flyingrobots Mar 4, 2026
a3db8ad
fix: validate constructor params for buffer/chunk size bounds
flyingrobots Mar 4, 2026
e93053e
fix(restore): enforce size limit after decompression
flyingrobots Mar 4, 2026
e257aee
test: harden error-path assertions to fail on missing throws
flyingrobots Mar 4, 2026
621f361
docs: fix JSDoc return types, add maxRestoreBufferSize param, fix hea…
flyingrobots Mar 4, 2026
c910cda
docs(changelog): add PR feedback fixes to unreleased section
flyingrobots Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- **CODE-EVAL.md** — Forensic architectural audit (zero-knowledge code extraction, critical assessment, roadmap reconciliation, prescriptive blueprint).
- **M16 Capstone** — New milestone in ROADMAP.md addressing all 9 audit flaws and 10 concerns (C1–C10). 13 task cards, ~698 LoC, ~21h estimated.
- **Concerns C8–C10** — Three new architectural concerns identified by the audit: crypto adapter LSP violation (C8), FixedChunker quadratic allocation (C9), encrypt-then-chunk dedup loss (C10).
- **CasError codes** — `RESTORE_TOO_LARGE` and `ENCRYPTION_BUFFER_EXCEEDED` registered in canonical error code table.

### Changed
- **VaultService test observability wiring** — `VaultService.test.js` now passes a `mockObservability()` port to all tests instead of relying on the silent no-op default. `rotateVaultPassphrase.test.js` now passes `SilentObserver` explicitly. If observability wiring breaks, the test suite will catch it.
- **`NodeCryptoAdapter.encryptBuffer` JSDoc** — `@returns` annotation corrected to `Promise<...>`, matching the async implementation.
- **`maxRestoreBufferSize` documented** — constructor JSDoc and `#config` type in `ContentAddressableStore` now include the parameter.
- **ROADMAP.md heading level** — added `## Task Cards` heading between `# M16` and `### 16.1` to satisfy MD001 heading-increment rule.

### Fixed
- **Post-decompression size guard** — `_restoreBuffered` now enforces `maxRestoreBufferSize` after decompression, not just before. Compressed payloads that inflate beyond the configured limit now throw `RESTORE_TOO_LARGE` instead of silently allocating unbounded memory.
- **CLI passphrase prompt deferral** — `resolveEncryptionKey` now checks vault metadata before calling `resolvePassphrase`, avoiding unnecessary TTY prompts for unencrypted vaults. Store action recipient-conflict check inspects flags/env without consuming stdin.
- **CRLF passphrase normalization** — `readPassphraseFile` now strips trailing `\r\n` (Windows line endings) in addition to `\n`, preventing passphrase mismatches from Windows-edited files.
- **Constructor validation** — `CasService.maxRestoreBufferSize` (integer >= 1024), `WebCryptoAdapter.maxEncryptionBufferSize` (finite, positive), and `FixedChunker.chunkSize` (positive integer) are now validated at construction time, preventing silent misconfiguration.
- **Error-path test hardening** — `orphanedBlobs`, `restoreGuard`, `kdfBruteForce`, and `conformance` tests now fail explicitly when expected errors are not thrown (previously silent pass-through).
- **16.8 — CasError portability guard** — `Error.captureStackTrace` now guarded with a runtime check. CasError constructs correctly on runtimes where `captureStackTrace` is unavailable (e.g. Firefox, older Deno).
- **16.9 — Pre-commit hook + hooks directory** — `scripts/git-hooks/` renamed to `scripts/hooks/` per CLAUDE.md convention. New `pre-commit` hook runs lint gate. `install-hooks.sh` updated accordingly.
- **16.1 — Crypto adapter behavioral normalization** — `NodeCryptoAdapter.encryptBuffer` now returns a Promise (was sync), matching Bun/Web. `decryptBuffer` validates key on all adapters. `NodeCryptoAdapter.createEncryptionStream` guards `finalize()` with `STREAM_NOT_CONSUMED`. New conformance test suite asserts identical contracts across all adapters.
- **16.2 — Memory restore guard** — `CasService` accepts `maxRestoreBufferSize` (default 512 MiB). `_restoreBuffered` throws `RESTORE_TOO_LARGE` with `{ size, limit }` meta when encrypted/compressed restore would exceed the limit. Unencrypted streaming restore is unaffected.
- **16.11 — Passphrase input security** — New `--vault-passphrase-file <path>` CLI option reads passphrase from file (use `-` for stdin). Interactive TTY prompt added as fallback when no other passphrase source is available. `resolvePassphrase` is now async with priority: file → flag → env → TTY → undefined.
- **16.6 — Chunk size upper bound** — CasService, FixedChunker, and CdcChunker now reject chunk sizes exceeding 100 MiB. CasService logs a warning when chunk size exceeds 10 MiB.
- **16.3 — Web Crypto encryption buffer guard** — `WebCryptoAdapter` accepts `maxEncryptionBufferSize` (default 512 MiB). Throws `ENCRYPTION_BUFFER_EXCEEDED` when streaming encryption exceeds the limit, since Web Crypto AES-GCM is a one-shot API. NodeCryptoAdapter uses true streaming and is unaffected.
- **16.5 — Encrypt-then-chunk dedup warning** — `CasService.store()` now logs a warning when encryption is combined with CDC chunking, since ciphertext is pseudorandom and content-defined boundaries provide no dedup benefit.
- **16.10 — Orphaned blob tracking** — `STREAM_ERROR` now includes `meta.orphanedBlobs` — an array of OIDs for blobs successfully written before the stream failure. Error metric includes `orphanedBlobs` count for observability.
- **16.4 — FixedChunker pre-allocated buffer** — Replaced `Buffer.concat()` loop with a pre-allocated `Buffer.allocUnsafe(chunkSize)` working buffer, eliminating O(n²) copies for many small input buffers. Matches the allocation strategy used by `CdcChunker`.
- **16.7 — Lifecycle method naming** — Added `inspectAsset()` (replaces `deleteAsset()`) and `collectReferencedChunks()` (replaces `findOrphanedChunks()`) as canonical names on both `CasService` and the facade. Old names are preserved as deprecated aliases that emit observability warnings. Type definitions updated with `@deprecated` JSDoc.
- **16.12 — KDF brute-force awareness** — `CasService` now emits `decryption_failed` metric with slug context when decryption fails with `INTEGRITY_ERROR` during encrypted restore. CLI adds a 1-second delay after `INTEGRITY_ERROR` to slow brute-force attempts. Library API imposes no delay — callers manage their own rate-limiting policy.
- **16.13 — GCM nonce collision docs + encryption counter** — `SECURITY.md` moved to project root with new sections: GCM nonce bound (2^32 NIST limit), key rotation frequency, KDF parameter guidance, and passphrase entropy recommendations. Vault metadata now tracks `encryptionCount`, incremented per encrypted `addToVault()`. Observability warning emitted when count exceeds 2^31. `VaultService` accepts optional `observability` port.

## [5.2.4] — Prism polish (2026-03-03)

### Fixed
Expand Down
Loading