-
Notifications
You must be signed in to change notification settings - Fork 0
docs: rewrite roadmap and prepare v5.3.2 #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
50708d7
docs: rewrite roadmap around dual CLI surfaces
flyingrobots c3e7271
Fix: stabilize multi-runtime CLI test runs
flyingrobots 053ea77
docs: fix README json output wording
flyingrobots 00def38
fix: harden cli version and vitest projects
flyingrobots 7525cc3
chore: start v5.3.2 development line
flyingrobots 47d603a
docs: clarify milestone ordering in status
flyingrobots File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| .git | ||
| node_modules | ||
| npm-debug.log | ||
| .gitignore | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,88 +1,84 @@ | ||
| # @git-stunts/cas — Project Status | ||
|
|
||
| **Current version:** v5.1.0 (Locksmith) | ||
| **Last release:** 2026-02-28 | ||
| **Test suite:** 757 tests (vitest) | ||
| **Current release:** `v5.3.1` | ||
| **Current branch version:** `v5.3.2` | ||
| **Last release:** `2026-03-15` | ||
| **Current line:** M16 Capstone shipped in `v5.3.0`; `v5.3.1` fixed repeated-chunk tree emission; `v5.3.2` is the next maintenance/doc/test follow-up in flight. | ||
| **Runtimes:** Node.js 22.x, Bun, Deno | ||
|
|
||
| --- | ||
|
|
||
| ## What's shipped | ||
| ## Interface Strategy | ||
|
|
||
| | Version | Codename | Highlights | | ||
| |---------|----------|------------| | ||
| | v5.1.0 | Locksmith | Envelope encryption (DEK/KEK), multi-recipient APIs, `--recipient` CLI, recipient management | | ||
| | v5.0.0 | Hydra | Content-defined chunking (CDC), `ChunkingPort`, buzhash engine, 98% dedup on edits | | ||
| | v4.0.1 | Spit Shine + Cockpit | CryptoPort refactor, `verify` command, `--json` mode, `runAction`, vault list filtering | | ||
| | v4.0.0 | Conduit | ObservabilityPort, `restoreStream()`, parallel chunk I/O, `concurrency` option | | ||
| | v3.1.0 | Bijou | Interactive vault dashboard, animated progress bars, `git cas inspect`, chunk heatmap | | ||
| | v3.0.0 | Vault | GC-safe ref-based storage (`refs/cas/vault`), slug-based addressing, vault CLI | | ||
| | v2.0.0 | Horizon | Compression (gzip), KDF (pbkdf2/scrypt), Merkle manifests | | ||
| | v1.x | — | Core CAS, AES-256-GCM encryption, fixed chunking, Git ODB persistence | | ||
| - **Human CLI/TUI:** the current public operator surface. Existing `git cas ...` commands, Bijou formatting, prompts, dashboards, and `--json` convenience output stay here. | ||
| - **Agent CLI:** planned next as `git cas agent`. It will be JSONL-first, non-interactive by default, and independent from Bijou rendering or TTY-only behavior. | ||
|
|
||
| --- | ||
|
|
||
| ## What's next | ||
| ## Recently Shipped | ||
|
|
||
| One open milestone remains. | ||
| | Version | Milestone | Highlights | | ||
| |---------|-----------|------------| | ||
| | `v5.3.1` | Maintenance | Repeated-chunk tree integrity fix; unique chunk tree entries; `git fsck` regression coverage | | ||
| | `v5.3.0` | M16 Capstone | Audit remediation, `.casrc`, passphrase-file support, restore guards, `encryptionCount`, lifecycle rename | | ||
| | `v5.2.0` | M12 Carousel | Key rotation without re-encrypting data | | ||
| | `v5.1.0` | M11 Locksmith | Envelope encryption and recipient management | | ||
| | `v5.0.0` | M10 Hydra | Content-defined chunking | | ||
| | `v4.0.1` | M8 + M9 | Review hardening, `verify`, `--json`, CLI polish | | ||
| | `v4.0.0` | M14 Conduit | Streaming restore, observability, parallel chunk I/O | | ||
| | `v3.1.0` | M13 Bijou | Interactive dashboard and animated progress | | ||
|
|
||
| ### M12 — Carousel (~13h) | ||
| Key rotation without re-encrypting data. Now unblocked by M11 Locksmith. | ||
|
|
||
| - [ ] **12.1** Key rotation workflow (`rotateKey()`) | ||
| - [ ] **12.2** Key version tracking in manifest | ||
| - [ ] **12.3** CLI key rotation commands | ||
| - [ ] **12.4** Vault-level key rotation | ||
| Milestone labels are thematic and non-sequential; the versions above are listed in release order. | ||
|
|
||
| --- | ||
|
|
||
| ## Dependency graph | ||
| ## Next Up | ||
|
|
||
| ### M17 — Ledger (`v5.3.2`) | ||
|
|
||
| Planning and ops reset: | ||
|
|
||
| - Reconcile `ROADMAP.md`, `STATUS.md`, and release messaging | ||
| - Add review automation (`CODEOWNERS` or equivalent) | ||
| - Document Git tree ordering test conventions | ||
| - Define release-prep workflow for changelog/version timing | ||
| - Automate test-count injection into release notes or changelog prep | ||
| - Add property-based fuzz coverage for envelope encryption | ||
|
|
||
| ### M18 — Relay (`v5.4.0`) | ||
|
|
||
| ``` | ||
| M8 Spit Shine ──────── ✅ v4.0.1 | ||
| M9 Cockpit ─────────── ✅ v4.0.1 | ||
| M10 Hydra ──────────── ✅ v5.0.0 | ||
| M11 Locksmith ──────── ✅ v5.1.0 | ||
| └──► M12 Carousel ── (ready) | ||
| ``` | ||
| LLM-native CLI foundation: | ||
|
|
||
| - Introduce `git cas agent` | ||
| - Define the JSONL protocol envelope and exit codes | ||
| - Add machine-facing parity for the current operational command set | ||
| - Enforce strict non-interactive input handling | ||
|
|
||
| ### M19 — Nouveau (`v5.5.0`) | ||
|
|
||
| Human UX refresh: | ||
|
|
||
| - Upgrade Bijou packages to `3.0.0` | ||
| - Move the inspector shell to the v3 `ViewOutput` model | ||
| - Split the dashboard into sub-apps | ||
| - Add better styling, motion, layout persistence, and richer heatmap/detail rendering | ||
|
|
||
| --- | ||
|
|
||
| ## Backlog (unscheduled ideas) | ||
|
|
||
| - Named vaults (`refs/cas/vaults/<name>`) | ||
| - Export vault to archive | ||
| - Publish to working tree / branch | ||
| - Duplicate detection on store | ||
| - Repo scan / dedup advisor | ||
| - Add `CODEOWNERS` or reviewer auto-assignment for PRs | ||
| - Document Git tree filename ordering semantics in test conventions | ||
| - Define release-prep workflow for CHANGELOG/version bump timing | ||
| - Automate test count injection into CHANGELOG from CI output | ||
| - Property-based fuzz tests for envelope encryption round-trips | ||
| - Investigate HSM/Vault key management as a future `KeyManagementPort` | ||
|
|
||
| ## Visions (researched, not committed) | ||
|
|
||
| - **V1** Snapshot trees — directory-level store (~410 LoC, ~19h) | ||
| - **V2** Portable bundles — air-gap transfer (~340 LoC, ~15h) | ||
| - **V3** Manifest diff engine (~180 LoC, ~8h) | ||
| - **V4** CompressionPort — zstd, brotli, lz4 (~180 LoC, ~8h) | ||
| - **V5** Watch mode — continuous sync (~220 LoC, ~10h) | ||
| - **V6** Interactive passphrase prompt (~90 LoC, ~4h) | ||
|
|
||
| ## Known concerns | ||
|
|
||
| | # | Issue | Severity | Summary | | ||
| |---|-------|----------|---------| | ||
| | C1 | Memory amplification | High | Encrypted/compressed restore buffers entire file | | ||
| | C2 | Orphaned blobs | Medium | STREAM_ERROR leaves unreferenced blobs in ODB | | ||
| | C3 | No chunk size cap | Medium | No upper bound on configured chunk size | | ||
| | C4 | Web Crypto buffering | Medium | Deno adapter silently buffers entire file | | ||
| | C5 | Passphrase exposure | High | `--vault-passphrase` visible in shell history | | ||
| | C6 | KDF no rate limit | Low | No brute-force detection on failed decryption | | ||
| | C7 | GCM nonce collision | Low | 96-bit random nonce, safe to ~2^32 encryptions | | ||
| ## Sequenced Roadmap | ||
|
|
||
| | Version | Milestone | Theme | | ||
| |---------|-----------|-------| | ||
| | `v5.3.2` | M17 Ledger | Planning and ops reset | | ||
| | `v5.4.0` | M18 Relay | LLM-native CLI foundation | | ||
| | `v5.5.0` | M19 Nouveau | Bijou v3 human UX refresh | | ||
| | `v5.6.0` | M20 Sentinel | Vault health and safety | | ||
| | `v5.7.0` | M21 Atelier | Vault ergonomics and publishing | | ||
| | `v5.8.0` | M22 Cartographer | Repo intelligence and change analysis | | ||
| | `v5.9.0` | M23 Courier | Artifact sets and transfer | | ||
| | `v5.10.0` | M24 Spectrum | Storage and observability extensibility | | ||
| | `v5.11.0` | M25 Bastion | Enterprise key-management research | | ||
|
|
||
| --- | ||
|
|
||
| *Full task cards: [ROADMAP.md](./ROADMAP.md) | Completed: [COMPLETED_TASKS.md](./COMPLETED_TASKS.md) | Superseded: [GRAVEYARD.md](./GRAVEYARD.md)* | ||
| *Future details: [ROADMAP.md](./ROADMAP.md) | Shipped detail: [COMPLETED_TASKS.md](./COMPLETED_TASKS.md) | Superseded: [GRAVEYARD.md](./GRAVEYARD.md)* | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| import { setTimeout as delay } from 'node:timers/promises'; | ||
|
|
||
| /** | ||
| * @param {unknown} err | ||
| * @returns {err is NodeJS.ErrnoException} | ||
| */ | ||
| function isBrokenPipeError(err) { | ||
| return Boolean(err && typeof err === 'object' && /** @type {NodeJS.ErrnoException} */ (err).code === 'EPIPE'); | ||
| } | ||
|
|
||
| /** | ||
| * Install stdout/stderr error handlers that exit cleanly when the downstream | ||
| * consumer closes the pipe before the CLI finishes writing. | ||
| * | ||
| * @param {Object} [options] | ||
| * @param {{ on(event: string, listener: (...args: any[]) => void): any, removeListener(event: string, listener: (...args: any[]) => void): any }} [options.stdout] | ||
| * @param {{ on(event: string, listener: (...args: any[]) => void): any, removeListener(event: string, listener: (...args: any[]) => void): any }} [options.stderr] | ||
| * @param {(code?: number) => never} [options.exit] | ||
| * @param {() => number} [options.getExitCode] | ||
| * @returns {{ dispose(): void }} | ||
| */ | ||
| export function installBrokenPipeHandlers({ | ||
| stdout = process.stdout, | ||
| stderr = process.stderr, | ||
| exit = process.exit, | ||
| getExitCode = () => process.exitCode || 0, | ||
| } = {}) { | ||
| const onError = (/** @type {unknown} */ err) => { | ||
| if (isBrokenPipeError(err)) { | ||
| exit(getExitCode()); | ||
| } | ||
| }; | ||
|
|
||
| stdout.on('error', onError); | ||
| stderr.on('error', onError); | ||
|
|
||
| return { | ||
| dispose() { | ||
| stdout.removeListener('error', onError); | ||
| stderr.removeListener('error', onError); | ||
| }, | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Flush stdout/stderr before exit so the CLI does not hang on open handles in | ||
| * containerized test environments. | ||
| * | ||
| * @param {Object} [options] | ||
| * @param {{ write(chunk: string, callback?: () => void): boolean }} [options.stdout] | ||
| * @param {{ write(chunk: string, callback?: () => void): boolean }} [options.stderr] | ||
| * @param {(code?: number) => void} [options.exit] | ||
| * @param {number} [options.code] | ||
| * @returns {Promise<void>} | ||
| */ | ||
| export async function flushStdioAndExit({ | ||
| stdout = process.stdout, | ||
| stderr = process.stderr, | ||
| exit = process.exit, | ||
| code = process.exitCode || 0, | ||
| } = {}) { | ||
| await flushStream(stdout); | ||
| await flushStream(stderr); | ||
| exit(code); | ||
| } | ||
|
|
||
| /** | ||
| * @param {{ write(chunk: string, callback?: () => void): boolean }} stream | ||
| * @returns {Promise<void>} | ||
| */ | ||
| async function flushStream(stream) { | ||
| try { | ||
| await new Promise((resolve) => { | ||
| stream.write('', resolve); | ||
| }); | ||
| } catch (err) { | ||
| if (!isBrokenPipeError(err)) { | ||
| throw err; | ||
| } | ||
| } | ||
|
|
||
| // Give stream error handlers one turn to observe late EPIPE events before exit. | ||
| await delay(0); | ||
| } | ||
|
|
||
| export { isBrokenPipeError }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.