@@ -9,7 +9,7 @@ This roadmap is structured as:
993 . ** Contracts** — Return/throw semantics for all public methods
10104 . ** Version Plan** — Table mapping versions to milestones
11115 . ** Milestone Dependency Graph** — ASCII diagram
12- 6 . ** Milestones & Task Cards** — 7 milestones, 24 tasks (uniform task card template)
12+ 6 . ** Milestones & Task Cards** — 7 milestones, 26 tasks (uniform task card template)
1313
1414---
1515
@@ -42,6 +42,7 @@ Single registry of all error codes used across the codebase. Each code is a stri
4242| ` INVALID_KEY_TYPE ` | Encryption key is not a Buffer. | Task 1.3 |
4343| ` INTEGRITY_ERROR ` | Decryption auth-tag verification failed (wrong key, tampered ciphertext, or tampered tag), or chunk digest mismatch on restore. | Exists (decrypt); extended by Task 1.6, Task 2.1 |
4444| ` STREAM_ERROR ` | Read stream failed during ` storeFile ` . Partial chunks may have been written to Git ODB (unreachable; handled by ` git gc ` ). Meta includes ` { chunksWritten: <number> } ` . | Task 2.4 |
45+ | ` MISSING_KEY ` | Encryption key required to restore encrypted content but none was provided. | Task 2.1 |
4546| ` TREE_PARSE_ERROR ` | ` git ls-tree ` output could not be parsed into valid entries. | Task 2.2 |
4647| ` MANIFEST_NOT_FOUND ` | No manifest entry (e.g. ` manifest.json ` / ` manifest.cbor ` ) found in the Git tree. | Task 4.1 |
4748| ` GIT_ERROR ` | Underlying Git plumbing command failed. Wraps the original error from the plumbing layer. | Task 2.2, Task 4.1 |
@@ -106,14 +107,29 @@ Return and throw semantics for every public method (current and planned).
106107- ** Algorithms:** ` pbkdf2 ` (default), ` scrypt ` — both Node.js built-ins.
107108- ** Throws:** Standard Node.js crypto errors on invalid parameters.
108109
110+ ### CLI: ` git cas store <file> --slug <slug> [--key-file <path>] ` * (planned — Task 2.5)*
111+ - ** Output:** Prints manifest JSON to stdout. If ` --tree ` is passed, prints only the Git tree OID instead.
112+ - ** Exit 0:** Store succeeded.
113+ - ** Exit 1:** Store failed (error message to stderr).
114+
115+ ### CLI: ` git cas tree --manifest <path> ` * (planned — Task 2.5)*
116+ - ** Output:** Prints Git tree OID to stdout.
117+ - ** Exit 0:** Tree created.
118+ - ** Exit 1:** Invalid manifest or Git error (message to stderr).
119+
120+ ### CLI: ` git cas restore <tree-oid> --out <path> [--key-file <path>] ` * (planned — Task 2.6)*
121+ - ** Output:** Writes restored file to ` --out ` path.
122+ - ** Exit 0:** Restore succeeded, prints bytes written to stdout.
123+ - ** Exit 1:** Integrity error, missing manifest, or I/O error (message to stderr).
124+
109125---
110126
111127## 4) Version Plan
112128
113129| Version | Milestone | Codename | Theme |
114130| --------:| -----------| ----------| -------|
115131| v1.1.0 | M1 | Bedrock | Foundation hardening |
116- | v1.2.0 | M2 | Boomerang| File retrieval round trip |
132+ | v1.2.0 | M2 | Boomerang| File retrieval round trip + CLI |
117133| v1.3.0 | M3 | Launchpad| CI/CD pipeline |
118134| v1.4.0 | M4 | Compass | Lifecycle management |
119135| v1.5.0 | M5 | Sonar | Observability |
@@ -152,13 +168,13 @@ M3 Launchpad (v1.3.0) M4 Compass (v1.4.0)
152168| # | Codename | Theme | Version | Tasks | ~ LoC | ~ Hours |
153169| ---:| --------------| ----------------------------| :-------:| ------:| -------:| ------:|
154170| M1 | Bedrock | Foundation hardening | v1.1.0 | 7 | ~ 475 | ~ 6.5h |
155- | M2 | Boomerang | File retrieval round trip | v1.2.0 | 4 | ~ 295 | ~ 9.5h |
171+ | M2 | Boomerang | File retrieval round trip + CLI | v1.2.0 | 6 | ~ 435 | ~ 14h |
156172| M3 | Launchpad | CI/CD pipeline | v1.3.0 | 2 | ~ 110 | ~ 4h |
157173| M4 | Compass | Lifecycle management | v1.4.0 | 3 | ~ 180 | ~ 5.5h |
158174| M5 | Sonar | Observability | v1.5.0 | 2 | ~ 210 | ~ 5.5h |
159175| M6 | Cartographer | Documentation | v1.6.0 | 3 | ~ 750 | ~ 10h |
160176| M7 | Horizon | Advanced features | v2.0.0 | 3 | ~ 450 | ~ 17h |
161- | | ** Total** | | | ** 24 ** | ** ~ 2,470 ** | ** ~ 58h ** |
177+ | | ** Total** | | | ** 26 ** | ** ~ 2,610 ** | ** ~ 62.5h ** |
162178
163179---
164180
@@ -535,7 +551,7 @@ As a maintainer, I want error conditions covered by tests so regressions in vali
535551---
536552
537553# M2 — Boomerang (v1.2.0)
538- ** Theme:** Complete store→retrieve round trip.
554+ ** Theme:** Complete store→retrieve round trip + CLI .
539555
540556---
541557
@@ -761,6 +777,132 @@ As a developer, I want storeFile to fail safely on stream errors so partial stor
761777
762778---
763779
780+ ## Task 2.5: CLI scaffold + ` store ` and ` tree ` subcommands
781+
782+ ** User Story**
783+ As a developer, I want ` git cas store ` and ` git cas tree ` commands so I can use CAS from the terminal without writing Node scripts.
784+
785+ ** Requirements**
786+ - R1: Add ` bin/git-cas.js ` entry point (Git discovers ` git-cas ` on PATH for ` git cas ` subcommands).
787+ - R2: Add ` "bin": { "git-cas": "./bin/git-cas.js" } ` to ` package.json ` .
788+ - R3: Use a lightweight CLI framework (e.g., ` commander ` ) for subcommand routing.
789+ - R4: ` git cas store <file> --slug <slug> [--key-file <path>] [--tree] ` :
790+ - Reads the file, calls ` storeFile() ` .
791+ - Prints manifest JSON to stdout by default.
792+ - If ` --tree ` is passed, also calls ` createTree() ` and prints tree OID.
793+ - ` --key-file ` reads a 32-byte raw key from a file for encryption.
794+ - R5: ` git cas tree --manifest <path> ` :
795+ - Reads a manifest JSON from file/stdin, calls ` createTree() ` .
796+ - Prints tree OID to stdout.
797+ - R6: Exit 0 on success, exit 1 on error with message to stderr.
798+ - R7: ` --cwd ` flag to set Git working directory (defaults to ` . ` ).
799+
800+ ** Acceptance Criteria**
801+ - AC1: ` npx git-cas store ./test.txt --slug test ` prints manifest JSON.
802+ - AC2: ` npx git-cas store ./test.txt --slug test --tree ` prints tree OID.
803+ - AC3: ` npx git-cas tree --manifest manifest.json ` prints tree OID.
804+ - AC4: Invalid arguments produce helpful usage message and exit 1.
805+ - AC5: ` --key-file ` with valid 32-byte file encrypts successfully.
806+ - AC6: ` --key-file ` with wrong-size file exits 1 with clear error.
807+
808+ ** Scope**
809+ - In scope: CLI scaffold, store subcommand, tree subcommand, key-file reading.
810+ - Out of scope: ` restore ` subcommand (Task 2.6), shell completions, config files.
811+
812+ ** Est. Complexity (LoC)**
813+ - Prod: ~ 80
814+ - Tests: ~ 30
815+ - Total: ~ 110
816+
817+ ** Est. Human Working Hours**
818+ - ~ 3h
819+
820+ ** Test Plan**
821+ - Golden path:
822+ - store a file via CLI → valid manifest JSON on stdout.
823+ - store with ` --tree ` → tree OID on stdout.
824+ - tree from manifest file → tree OID on stdout.
825+ - Failures:
826+ - missing file → exit 1 with error.
827+ - missing ` --slug ` → exit 1 with usage message.
828+ - bad key file → exit 1 with INVALID_KEY_LENGTH/TYPE error.
829+ - Edges:
830+ - 0-byte file store.
831+ - manifest piped via stdin (if supported).
832+ - Fuzz/stress:
833+ - None (thin wrapper over tested API).
834+
835+ ** Definition of Done**
836+ - DoD1: ` bin/git-cas.js ` exists with store and tree subcommands.
837+ - DoD2: ` package.json ` declares bin entry.
838+ - DoD3: ` npx git-cas --help ` prints usage.
839+ - DoD4: Integration smoke test passes against real Git repo.
840+
841+ ** Blocking**
842+ - Blocks: Task 2.6
843+
844+ ** Blocked By**
845+ - Blocked by: None
846+
847+ ---
848+
849+ ## Task 2.6: CLI ` restore ` subcommand
850+
851+ ** User Story**
852+ As a developer, I want ` git cas restore <tree-oid> --out <path> ` so I can retrieve stored assets from the terminal.
853+
854+ ** Requirements**
855+ - R1: ` git cas restore <tree-oid> --out <path> [--key-file <path>] ` :
856+ - Reads the tree, extracts the manifest, restores the file to ` --out ` .
857+ - Prints bytes written to stdout on success.
858+ - ` --key-file ` supplies decryption key for encrypted assets.
859+ - R2: Exit 0 on success, exit 1 on error (INTEGRITY_ERROR, MANIFEST_NOT_FOUND, etc.) with message to stderr.
860+ - R3: Requires ` restoreFile() ` (Task 2.1) and ` readManifest() ` or equivalent tree-reading capability.
861+
862+ ** Acceptance Criteria**
863+ - AC1: ` npx git-cas restore <oid> --out ./restored.txt ` writes correct file.
864+ - AC2: Encrypted asset with ` --key-file ` restores correctly.
865+ - AC3: Wrong key exits 1 with INTEGRITY_ERROR message.
866+ - AC4: Invalid tree OID exits 1 with clear error.
867+
868+ ** Scope**
869+ - In scope: restore subcommand wired to restoreFile API.
870+ - Out of scope: Streaming output to stdout, partial restore, resume.
871+
872+ ** Est. Complexity (LoC)**
873+ - Prod: ~ 30
874+ - Tests: ~ 20
875+ - Total: ~ 50
876+
877+ ** Est. Human Working Hours**
878+ - ~ 1.5h
879+
880+ ** Test Plan**
881+ - Golden path:
882+ - store → tree → restore → byte-compare original.
883+ - encrypted store → tree → restore with key → byte-compare.
884+ - Failures:
885+ - wrong key → exit 1 INTEGRITY_ERROR.
886+ - nonexistent tree OID → exit 1.
887+ - missing ` --out ` → exit 1 with usage.
888+ - Edges:
889+ - 0-byte file round-trip via CLI.
890+ - Fuzz/stress:
891+ - None (thin wrapper over tested API).
892+
893+ ** Definition of Done**
894+ - DoD1: ` restore ` subcommand added to ` bin/git-cas.js ` .
895+ - DoD2: Full CLI round-trip (store → tree → restore) documented and tested.
896+ - DoD3: README CLI section is now accurate and deliverable.
897+
898+ ** Blocking**
899+ - Blocks: None
900+
901+ ** Blocked By**
902+ - Blocked by: Task 2.1, Task 2.5
903+
904+ ---
905+
764906# M3 — Launchpad (v1.3.0)
765907** Theme:** Automated quality gates and release process.
766908
0 commit comments