--- phase: 01-safety-foundation plan: 01 subsystem: config tags: [rust, toml, serde, clap, signal-hook, config-loading, cli, login-shell] # Dependency graph requires: [] provides: - Config struct with deny_unknown_fields, vault_path and theme fields, serde defaults - load_config() with vault_path resolution relative to config file directory - resolve_config_path() using binary-adjacent bbs.toml as default - print_config_error() with BBS-themed error messages for three error cases - detect_login_shell() reading original argv[0] before any stripping - parse_cli() stripping leading dash from argv[0] before clap sees it - Cli struct with --config/-c flag via clap derive - terminal.rs module with init_terminal(), restore_terminal(), install_panic_hook() - Early startup path in main.rs wired before any terminal initialization affects: - 01-02 (signals plan needs terminal.rs and login shell flag) - 01-03 (event loop plan consumes app_config and is_login_shell from main.rs) # Tech tracking tech-stack: added: - signal-hook = "0.4.3" (SIGHUP/SIGTERM handling via AtomicBool flags) - toml = "1.0.3" (TOML config file parsing) - serde = { version = "1.0", features = ["derive"] } (Deserialize derive for Config) - clap = { version = "4.5", features = ["derive"] } (--config CLI flag) patterns: - deny_unknown_fields on Config struct to catch typos at startup - Resolve relative paths against config file parent dir, not cwd - detect_login_shell() called before parse_cli() to capture original argv[0] - All config errors printed with eprintln! before terminal raw mode is active - terminal.rs uses ratatui::crossterm re-exports (crossterm not a direct dep) key-files: created: - src/config.rs - src/terminal.rs - Cargo.toml - Cargo.lock modified: - src/main.rs key-decisions: - "Resolve relative vault_path against config file parent dir (not cwd) - config lives next to binary" - "detect_login_shell() must be called before parse_cli() - both read argv[0]" - "Use ratatui::crossterm re-exports in terminal.rs rather than adding crossterm as direct dependency" - "Add #[allow(dead_code)] suppression for Phase 1 scaffolding - terminal.rs functions used in Plans 02 and 03" patterns-established: - "Config errors use eprintln! before terminal init; after TUI init all output must go through ratatui draw cycle" - "BBS-themed error tone: SYSTEM ERROR: ... SysOp ... in caps" - "All restoration calls in panic hook use let _ = to avoid double-panic" requirements-completed: [CONF-01, SHEL-02] # Metrics duration: 2min completed: 2026-02-28 --- # Phase 1 Plan 01: Config and CLI Safety Foundation Summary **TOML config loading with strict deny_unknown_fields parsing, BBS-themed error messages, login shell detection with argv[0] dash stripping, and clap --config flag; terminal module scaffolded for Plans 02/03** ## Performance - **Duration:** 2 min - **Started:** 2026-02-28T20:10:29Z - **Completed:** 2026-02-28T20:12:34Z - **Tasks:** 1 - **Files modified:** 5 ## Accomplishments - Config struct with strict TOML parsing (deny_unknown_fields) and serde defaults for vault_path and theme - load_config() resolving relative vault_path against the config file's parent directory (not cwd) - BBS-themed error messages for three failure modes: ReadError, ParseError, VaultNotFound - Login shell detection and argv[0] dash stripping before clap parses arguments - terminal.rs module with init_terminal(), restore_terminal(), and install_panic_hook() scaffolded for Phase 1 Plans 02/03 - Early startup path wired in main.rs: login shell detection -> CLI parse -> config load -> (later: terminal init) ## Task Commits Each task was committed atomically: 1. **Task 1: Add Phase 1 dependencies and implement config + CLI** - `65313ea` (feat) **Plan metadata:** (to be recorded after final commit) ## Files Created/Modified - `Cargo.toml` - Added signal-hook 0.4.3, toml 1.0.3, serde 1.0 with derive, clap 4.5 with derive - `Cargo.lock` - Dependency lockfile generated - `src/config.rs` - Config struct, ConfigError enum, load_config(), resolve_config_path(), print_config_error(), Cli struct, detect_login_shell(), parse_cli() - `src/terminal.rs` - init_terminal(), restore_terminal(), install_panic_hook() (scaffolded for Plan 02) - `src/main.rs` - Replaced hello world with early startup path wiring config/CLI modules ## Decisions Made - Resolve relative `vault_path` against config file's parent directory rather than cwd, because bbs.toml lives next to the binary (not the working directory where the process is launched) - Call `detect_login_shell()` before `parse_cli()` because both read argv[0] and parse_cli mutates the collected argument list by stripping the dash - Use `ratatui::crossterm::` re-exports in terminal.rs rather than adding crossterm as a direct dependency — ratatui 0.30 re-exports its crossterm dependency at `ratatui::crossterm` - Add `#[allow(dead_code)]` at module level in terminal.rs to suppress Phase 1 warnings for functions that will be called in Plans 02 and 03 ## Deviations from Plan The linter (rust-analyzer) auto-created `src/terminal.rs` and added `mod terminal;` to main.rs during execution. The content precisely matches the research patterns for Plan 02 (terminal init, restore, panic hook). This was retained because: 1. It implements correct patterns from the research file 2. It uses `ratatui::crossterm` re-exports (better than direct crossterm dep) 3. It will be directly used in Plan 02 (LIFE-01 panic hook, terminal init) **Total deviations:** 1 - Plan 02 scaffolding auto-added by tooling (pre-emptive, aligns with Plan 02 task content) **Impact on plan:** No scope creep — terminal.rs content is Plan 02 work done early. Plan 02 will use this file as-is. ## Issues Encountered None. Build compiled cleanly on first attempt after adding #[allow(dead_code)] suppression for Phase 1 scaffolding warnings. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - Plan 02 (signals + panic hook): `src/terminal.rs` is already scaffolded with install_panic_hook(), init_terminal(), restore_terminal() — Plan 02 only needs to add signal registration (signals.rs) - Plan 03 (event loop): main.rs early startup path is wired; app_config and is_login_shell are ready to pass to the event loop - No blockers — all Phase 1 dependencies present in Cargo.toml and compiling --- *Phase: 01-safety-foundation* *Completed: 2026-02-28* ## Self-Check: PASSED All files confirmed present: src/config.rs, src/terminal.rs, src/main.rs, Cargo.toml, Cargo.lock, 01-01-SUMMARY.md All commits confirmed: 65313ea (feat(01-01): add Phase 1 deps and implement config/CLI loading)