docs(12-01): complete CLI key input plan
- SUMMARY.md with execution results and decisions - STATE.md updated with position, metrics, decisions - ROADMAP.md updated with phase 12 progress - REQUIREMENTS.md: KEY-01, KEY-02, KEY-07 marked complete Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -99,13 +99,13 @@
|
|||||||
|
|
||||||
### User Key Input (Пользовательский ввод ключа)
|
### User Key Input (Пользовательский ввод ключа)
|
||||||
|
|
||||||
- [ ] **KEY-01**: CLI аргумент `--key <HEX>` — 64 символа hex, декодируется в 32-байтный AES-256 ключ
|
- [x] **KEY-01**: CLI аргумент `--key <HEX>` — 64 символа hex, декодируется в 32-байтный AES-256 ключ
|
||||||
- [ ] **KEY-02**: CLI аргумент `--key-file <PATH>` — чтение ровно 32 байт из файла как raw ключ
|
- [x] **KEY-02**: CLI аргумент `--key-file <PATH>` — чтение ровно 32 байт из файла как raw ключ
|
||||||
- [ ] **KEY-03**: CLI аргумент `--password [VALUE]` — интерактивный промпт (rpassword) или значение из CLI
|
- [ ] **KEY-03**: CLI аргумент `--password [VALUE]` — интерактивный промпт (rpassword) или значение из CLI
|
||||||
- [ ] **KEY-04**: Argon2id KDF — деривация 32-байтного ключа из пароля + 16-байтный random salt
|
- [ ] **KEY-04**: Argon2id KDF — деривация 32-байтного ключа из пароля + 16-байтный random salt
|
||||||
- [ ] **KEY-05**: Хранение salt в архиве — flags bit 4 (0x10), 16-байтный salt между header и TOC при pack
|
- [ ] **KEY-05**: Хранение salt в архиве — flags bit 4 (0x10), 16-байтный salt между header и TOC при pack
|
||||||
- [ ] **KEY-06**: Чтение salt из архива при unpack/inspect — автоматическое определение по flags bit 4
|
- [ ] **KEY-06**: Чтение salt из архива при unpack/inspect — автоматическое определение по flags bit 4
|
||||||
- [ ] **KEY-07**: Один из `--key`, `--key-file`, `--password` обязателен для pack/unpack; inspect принимает ключ опционально
|
- [x] **KEY-07**: Один из `--key`, `--key-file`, `--password` обязателен для pack/unpack; inspect принимает ключ опционально
|
||||||
|
|
||||||
## Future Requirements
|
## Future Requirements
|
||||||
|
|
||||||
@@ -192,13 +192,13 @@
|
|||||||
| TST-05 | Phase 11 | Pending |
|
| TST-05 | Phase 11 | Pending |
|
||||||
| TST-06 | Phase 11 | Pending |
|
| TST-06 | Phase 11 | Pending |
|
||||||
| TST-07 | Phase 11 | Pending |
|
| TST-07 | Phase 11 | Pending |
|
||||||
| KEY-01 | Phase 12 | Pending |
|
| KEY-01 | Phase 12 | Complete |
|
||||||
| KEY-02 | Phase 12 | Pending |
|
| KEY-02 | Phase 12 | Complete |
|
||||||
| KEY-03 | Phase 12 | Pending |
|
| KEY-03 | Phase 12 | Pending |
|
||||||
| KEY-04 | Phase 12 | Pending |
|
| KEY-04 | Phase 12 | Pending |
|
||||||
| KEY-05 | Phase 12 | Pending |
|
| KEY-05 | Phase 12 | Pending |
|
||||||
| KEY-06 | Phase 12 | Pending |
|
| KEY-06 | Phase 12 | Pending |
|
||||||
| KEY-07 | Phase 12 | Pending |
|
| KEY-07 | Phase 12 | Complete |
|
||||||
|
|
||||||
**Coverage:**
|
**Coverage:**
|
||||||
- v1.0 requirements: 30 total -- all Complete
|
- v1.0 requirements: 30 total -- all Complete
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
|
|||||||
**Goal:** Replace hardcoded encryption key with user-specified key input: `--password` (interactive prompt or CLI value, derived via Argon2id), `--key` (raw 64-char hex), `--key-file` (read 32 bytes from file). All three methods produce a 32-byte AES-256 key passed through pack/unpack/inspect.
|
**Goal:** Replace hardcoded encryption key with user-specified key input: `--password` (interactive prompt or CLI value, derived via Argon2id), `--key` (raw 64-char hex), `--key-file` (read 32 bytes from file). All three methods produce a 32-byte AES-256 key passed through pack/unpack/inspect.
|
||||||
**Requirements**: KEY-01, KEY-02, KEY-03, KEY-04, KEY-05, KEY-06, KEY-07
|
**Requirements**: KEY-01, KEY-02, KEY-03, KEY-04, KEY-05, KEY-06, KEY-07
|
||||||
**Depends on:** Phase 11
|
**Depends on:** Phase 11
|
||||||
**Plans:** 2 plans
|
**Plans:** 1/2 plans executed
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
- [ ] 12-01-PLAN.md -- CLI key args (--key, --key-file, --password), refactor archive.rs to accept key parameter, update all tests
|
- [ ] 12-01-PLAN.md -- CLI key args (--key, --key-file, --password), refactor archive.rs to accept key parameter, update all tests
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
gsd_state_version: 1.0
|
gsd_state_version: 1.0
|
||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: Directory Support
|
milestone_name: Directory Support
|
||||||
status: unknown
|
status: in-progress
|
||||||
last_updated: "2026-02-26T19:09:56.676Z"
|
last_updated: "2026-02-26T20:53:36Z"
|
||||||
progress:
|
progress:
|
||||||
total_phases: 9
|
total_phases: 12
|
||||||
completed_phases: 9
|
completed_phases: 9
|
||||||
total_plans: 13
|
total_plans: 15
|
||||||
completed_plans: 13
|
completed_plans: 14
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -18,29 +18,30 @@ progress:
|
|||||||
See: .planning/PROJECT.md (updated 2026-02-25)
|
See: .planning/PROJECT.md (updated 2026-02-25)
|
||||||
|
|
||||||
**Core value:** Archive impossible to unpack without knowing the format -- standard tools (7z, tar, unzip, binwalk) cannot recognize or extract contents
|
**Core value:** Archive impossible to unpack without knowing the format -- standard tools (7z, tar, unzip, binwalk) cannot recognize or extract contents
|
||||||
**Current focus:** Milestone v1.1 Directory Support -- Phase 9: Kotlin Decoder Update COMPLETE
|
**Current focus:** Phase 12: User Key Input -- Plan 01 COMPLETE, Plan 02 next
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 9 of 11 (Kotlin Decoder Update) -- COMPLETE
|
Phase: 12 of 12 (User Key Input)
|
||||||
Plan: 1 of 1 -- COMPLETE
|
Plan: 1 of 2 -- COMPLETE
|
||||||
Status: Phase 9 complete, Kotlin decoder updated for v1.1 format with directory support
|
Status: Phase 12 Plan 01 complete, --key and --key-file support added
|
||||||
Last activity: 2026-02-26 -- Phase 9 Plan 01 executed (Kotlin decoder v1.1 update)
|
Last activity: 2026-02-26 -- Phase 12 Plan 01 executed (CLI key input + archive refactor)
|
||||||
|
|
||||||
Progress: [#############.......] 68% (13/~19 plans estimated)
|
Progress: [##############......] 70% (14/~20 plans estimated)
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
- Total plans completed: 13
|
- Total plans completed: 14
|
||||||
- Average duration: 3.6 min
|
- Average duration: 3.6 min
|
||||||
- Total execution time: 0.8 hours
|
- Total execution time: 0.9 hours
|
||||||
|
|
||||||
| Phase | Plan | Duration | Tasks | Files |
|
| Phase | Plan | Duration | Tasks | Files |
|
||||||
|-------|------|----------|-------|-------|
|
|-------|------|----------|-------|-------|
|
||||||
| 07-01 | Format Spec Update | 8 min | 2 | 1 |
|
| 07-01 | Format Spec Update | 8 min | 2 | 1 |
|
||||||
| 08-01 | Rust Directory Archiver | 6 min | 3 | 4 |
|
| 08-01 | Rust Directory Archiver | 6 min | 3 | 4 |
|
||||||
| 09-01 | Kotlin Decoder Update | 2 min | 2 | 2 |
|
| 09-01 | Kotlin Decoder Update | 2 min | 2 | 2 |
|
||||||
|
| 12-01 | CLI Key Input | 5 min | 2 | 8 |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -66,11 +67,19 @@ Recent decisions affecting current work:
|
|||||||
- v1.1: Kotlin decoder uses Java File API owner/everyone permission model (no group-level granularity)
|
- v1.1: Kotlin decoder uses Java File API owner/everyone permission model (no group-level granularity)
|
||||||
- v1.1: Directory entries in Kotlin decoder skip crypto pipeline entirely, use mkdirs()
|
- v1.1: Directory entries in Kotlin decoder skip crypto pipeline entirely, use mkdirs()
|
||||||
- v1.1: Permission application order: everyone flags first, then owner-only overrides
|
- v1.1: Permission application order: everyone flags first, then owner-only overrides
|
||||||
|
- v1.2: KeyArgs as top-level clap flatten (--key before subcommand)
|
||||||
|
- v1.2: inspect accepts optional key: without key shows header only, with key shows full TOC
|
||||||
|
- v1.2: LEGACY_KEY kept as #[cfg(test)] for golden test vectors
|
||||||
|
- v1.2: All archive functions parameterized by explicit key (no global state)
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
None yet.
|
None yet.
|
||||||
|
|
||||||
|
### Roadmap Evolution
|
||||||
|
|
||||||
|
- Phase 12 added: User-specified encryption key (--password, --key, --key-file)
|
||||||
|
|
||||||
### Blockers/Concerns
|
### Blockers/Concerns
|
||||||
|
|
||||||
None.
|
None.
|
||||||
@@ -78,5 +87,5 @@ None.
|
|||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-02-26
|
Last session: 2026-02-26
|
||||||
Stopped at: Completed 09-01-PLAN.md -- Phase 9 complete, Kotlin decoder updated for v1.1
|
Stopped at: Completed 12-01-PLAN.md -- Phase 12 Plan 01 complete, --key and --key-file support
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
127
.planning/phases/12-user-key-input/12-01-SUMMARY.md
Normal file
127
.planning/phases/12-user-key-input/12-01-SUMMARY.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
---
|
||||||
|
phase: 12-user-key-input
|
||||||
|
plan: 01
|
||||||
|
subsystem: crypto
|
||||||
|
tags: [clap, hex, aes-256, key-management, cli]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 08-rust-directory-archiver
|
||||||
|
provides: "pack/unpack/inspect with hardcoded key"
|
||||||
|
provides:
|
||||||
|
- "CLI --key (hex) and --key-file (raw) key input for pack/unpack"
|
||||||
|
- "inspect works without key (header only) or with key (full TOC listing)"
|
||||||
|
- "KeySource enum and resolve_key() in key.rs"
|
||||||
|
- "All archive functions parameterized by user-provided key"
|
||||||
|
affects: [12-02-PLAN, kotlin-decoder]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: [hex 0.4]
|
||||||
|
patterns: [key-parameterized archive API, clap arg group for mutually exclusive key sources]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- Cargo.toml
|
||||||
|
- src/cli.rs
|
||||||
|
- src/key.rs
|
||||||
|
- src/archive.rs
|
||||||
|
- src/main.rs
|
||||||
|
- src/crypto.rs
|
||||||
|
- tests/round_trip.rs
|
||||||
|
- tests/golden.rs
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "KeyArgs as top-level clap flatten (not per-subcommand) so --key goes before subcommand"
|
||||||
|
- "inspect accepts optional key: without key shows header only, with key shows full TOC"
|
||||||
|
- "LEGACY_KEY kept as #[cfg(test)] constant for golden vectors"
|
||||||
|
- "Password option uses Option<Option<String>> for future interactive prompt support"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Key threading: all archive functions accept explicit key parameter instead of global state"
|
||||||
|
- "cmd_with_key() test helper for CLI integration tests"
|
||||||
|
|
||||||
|
requirements-completed: [KEY-01, KEY-02, KEY-07]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 5min
|
||||||
|
completed: 2026-02-26
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 12 Plan 01: User Key Input Summary
|
||||||
|
|
||||||
|
**CLI key input via --key (hex) and --key-file (raw bytes), replacing hardcoded constant, with inspect working keyless for header metadata**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 5 min
|
||||||
|
- **Started:** 2026-02-26T20:47:52Z
|
||||||
|
- **Completed:** 2026-02-26T20:53:36Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 8
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- Removed hardcoded KEY constant from production code; all archive functions now parameterized by key
|
||||||
|
- Added --key (64-char hex) and --key-file (32-byte raw file) as mutually exclusive CLI args
|
||||||
|
- inspect works without a key (shows header metadata + "TOC is encrypted" message) and with a key (full entry listing)
|
||||||
|
- All 47 tests pass: 25 unit + 7 golden + 15 integration (6 new tests added)
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Add CLI key args and refactor key.rs + archive.rs signatures** - `acff31b` (feat)
|
||||||
|
2. **Task 2: Update tests and verify round-trip with explicit key** - `551e499` (test)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `Cargo.toml` - Added hex 0.4 dependency
|
||||||
|
- `src/cli.rs` - Added KeyArgs struct with --key, --key-file, --password as clap arg group
|
||||||
|
- `src/key.rs` - Replaced hardcoded KEY with KeySource enum and resolve_key() function
|
||||||
|
- `src/archive.rs` - Refactored pack/unpack/inspect to accept key parameter
|
||||||
|
- `src/main.rs` - Wired CLI key args to key resolution and archive functions
|
||||||
|
- `src/crypto.rs` - Updated tests to use local TEST_KEY constant
|
||||||
|
- `tests/golden.rs` - Updated to use local KEY constant instead of imported
|
||||||
|
- `tests/round_trip.rs` - All tests updated with --key, 6 new tests added
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
- KeyArgs placed at top-level Cli struct (not per-subcommand) so --key goes BEFORE the subcommand name
|
||||||
|
- inspect accepts optional key: without key shows only header fields, with key decrypts and shows full TOC
|
||||||
|
- LEGACY_KEY kept as #[cfg(test)] constant in key.rs for golden test vector compatibility
|
||||||
|
- Password field uses `Option<Option<String>>` to support both `--password mypass` and `--password` (future interactive prompt)
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] Fixed wrong-key test assertion**
|
||||||
|
- **Found during:** Task 2 (test_rejects_wrong_key)
|
||||||
|
- **Issue:** Wrong key causes TOC decryption failure ("invalid padding or wrong key") before HMAC check on individual files. The test expected "HMAC" or "verification" in stderr.
|
||||||
|
- **Fix:** Broadened assertion to also accept "Decryption failed" or "wrong key" in error message
|
||||||
|
- **Files modified:** tests/round_trip.rs
|
||||||
|
- **Verification:** Test passes with actual error behavior
|
||||||
|
- **Committed in:** 551e499 (Task 2 commit)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 1 auto-fixed (1 bug fix in test)
|
||||||
|
**Impact on plan:** Trivial test assertion fix. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
None
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
- Key input foundation complete for Plan 02 (Argon2 password-based key derivation)
|
||||||
|
- --password CLI arg already accepted (returns "not yet implemented" error)
|
||||||
|
- KeySource::Password variant ready for Plan 02 implementation
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
All 9 files verified present. Both task commits (acff31b, 551e499) found in git log.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 12-user-key-input*
|
||||||
|
*Completed: 2026-02-26*
|
||||||
Reference in New Issue
Block a user