Commit Graph

62 Commits

Author SHA1 Message Date
ca7c035ea5 docs(handoff): log 2026-07-08 — hexagonal architecture refactor, adapters, integration tests, notsecrets cleanup
- Completed hexagonal architecture refactor with adapter pattern
- Added comprehensive integration tests
- Cleaned up notsecrets integration
- Moved config payload to notfiles-config repo

Commits: 6427d18, 25624c9
2026-07-08 15:22:59 -04:00
6427d188e6 feat(notfiles): hexagonal architecture refactor with adapters, integration tests, and notsecrets cleanup
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
- Extract FileStore port and InMemoryFileStore/FileStoreImpl/Reporter adapters
- Add Reporter trait to notcore with TerminalReporter and JsonReporter
- Refactor linker, package, status modules to use FileStore port
- Add integration test suite with dotfiles fixtures
- Add cross-crate integration tests
- Remove ssh_rsa identity/recipient (unsupported)
- Add rustqual.toml, .sccignore, notfiles.toml config files
- Update CLAUDE.md, README.md, AGENTS.md with current architecture
2026-07-08 13:07:42 -04:00
cb732c24ce chore: add TODO roadmap, nf alias, and install recipe
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
2026-06-14 00:35:39 -04:00
268c981545 feat(notfiles): add detect subcommand for stow/chezmoi/notfiles auto-detection
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
2026-06-14 00:30:27 -04:00
02ed15d6ee feat(nushell): add nu_libs autoload package
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
fix(notgraph): replace sort_by with sort_by_key (clippy)
2026-06-14 00:19:21 -04:00
50ff598684 refactor(notstrap): replace EnvInjector with SecretResolver
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
Remove the EnvInjector closure and replace with a secrets_config path
that loads notsecrets.toml and uses SecretResolver for env injection.
Existing parse_env_line validation (blocked keys, null bytes) is
preserved in the injection loop.
2026-06-06 09:57:20 -04:00
1359def673 feat(notsecrets): add multi-provider secret resolution system
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Has been cancelled
Add a config-driven, strongly-typed secret/env resolution system to
notsecrets with 11 provider backends. The system supports explicit
key bindings with typed SecretRef enums and a priority chain fallback.

Tier 1 providers (implemented): Env, 1Password, dotenvx, SOPS, GSM
Tier 2 providers (stubbed): nuenv, direnv, mise, Bitwarden, Vault, dotenvy

New types: Provider, ProviderConfig, SecretRef, SecretsConfig,
SecretsError, SecretSource, EnumerableSecretSource, SecretResolver

Config lives in notsecrets.toml with typed serde deserialization.
ISP split: EnumerableSecretSource for backends that support bulk
enumeration, SecretSource for single-key lookup only.

Includes conformance test suite, 33 new tests (161 workspace total).
notstrap EnvInjector migration deferred to follow-up.
2026-06-06 09:49:05 -04:00
Joseph O'Brien
c7c074d48b feat: add notnet crate and YubikeySource, thread Tailscale into notstrap
- New crates/notnet: TailscaleOptions, ensure_connected(), auth key chain
  (TS_AUTHKEY env → YubiKey PIV 9d → interactive prompt), install via
  apt/brew/pacman or official install.sh, peer reachability verification
- notsecrets: YubikeySource implementing IdentitySource, reads age key from
  PIV slot 9c; gated behind optional `yubikey` feature
- notstrap: Tailscale step inserted between prerequisites and clone;
  BootstrapOptions.tailscale controls override/skip; NotstrapConfig gains
  optional [tailscale] section; dotfiles_repo is now Option<String> (Tailscale
  gitea_url takes precedence); identity chain adds YubikeySource before
  Bitwarden
- Updated workspace Cargo.toml: notnet added to members and workspace deps
- Integration tests: tailscale: Some(None) to skip Tailscale in all test opts
2026-04-17 00:01:50 -04:00
Joseph O'Brien
67f20eef2d Refactor: Formalize ports and update related files 2026-04-15 21:27:25 -04:00
Joseph O'Brien
aadb1570a3 refactor: formalize FileStore and IdentitySource ports in notfiles
- Create FileStore trait in crates/notfiles/src/ports.rs capturing all file I/O
  operations (read, write, rename, remove, metadata, symlink, etc.)
- Create FileStoreImpl adapter in crates/notfiles/src/adapters/fs.rs wrapping std::fs
- Update linker.rs State::load/save and link_package/unlink_package to accept
  FileStore parameter for dependency injection
- Create IdentitySource port in crates/notsecrets/src/ports.rs
- Move IdentitySource trait from sources/mod.rs to ports.rs, maintain backward
  compatibility via re-export
- Update all source implementations to import from ports
- Update lib.rs in both crates to re-export ports
- Pass FileStoreImpl through call chain in main.rs and lib.rs public API

Maintains 100% backward compatible public API; FileStore dependency is internal.
2026-04-12 16:35:53 -04:00
Joseph O'Brien
19e74b4a1b security: audit Command call sites; confirm no argument injection
Closes #18

All six Command::new call sites audited:
- bitwarden.rs (sh -c): shell string is a hardcoded literal; no user data.
- bitwarden.rs (bw unlock): all args hardcoded.
- bitwarden.rs (bw get): item_name and session passed as discrete .args() elements; no shell.
- nothooks/runner.rs (nu/sh/etc): interp and script path passed as discrete args; no shell.
- notstrap/repo.rs (git clone): url and dest passed as discrete .arg() calls; no shell.
- notfiles/tests/integration.rs: test harness with hardcoded args only.

Added SAFETY comments on the three sites that handle user-controlled config values.
2026-04-11 23:52:40 -04:00
Joseph O'Brien
822abd9c88 fix(notfiles): atomic state file writes via temp-file + rename
Closes #17
2026-04-11 23:51:43 -04:00
Joseph O'Brien
bdc6582aea merge: fix unlink validation and HookRunner state batching (closes #10, #13) 2026-04-11 23:41:16 -04:00
Joseph O'Brien
83008c5353 fix(notstrap): wire age identity to decryption; fix parse_env_line quoting
Closes #14, closes #16
2026-04-11 23:40:47 -04:00
Joseph O'Brien
0d60583c65 fix(notfiles,nothooks): validate package on unlink; batch state I/O in HookRunner
Closes #10, closes #13
2026-04-11 23:40:40 -04:00
Joseph O'Brien
3e7135a398 fix(notfiles): save state on partial link failure; skip re-copy of unchanged files
Closes #8, closes #9
2026-04-11 23:40:32 -04:00
Joseph O'Brien
11d329c5a2 security: fix Bitwarden password exposure and ChaCha nonce hardening
Issue 12: pass bw unlock password via stdin (--passwordstdin) instead of
as a CLI arg, preventing it from appearing in /proc/<pid>/cmdline or ps output.

Issue 11: replace Nonce::default() (all-zero) with the first 12 bytes of the
16-byte random payload nonce. The key-nonce pair was already unique per message
(HKDF salt), but using an explicit non-zero nonce removes the latent risk of
accidental key reuse and makes the safety invariant self-documenting.

Closes #11, closes #12
2026-04-11 23:38:41 -04:00
Joseph O'Brien
ebb8a5946d refactor(nothooks): make hook runner language-agnostic
Some checks failed
Public Repo Readiness / Check Public Repo Readiness (push) Failing after 6s
Remove hardcoded nu interpreter. HookSpec gains an optional interpreter
field; runner infers from file extension (.sh, .nu, .py, .rb, .zsh,
.bash) when not set. Integration tests now use sh — no nu runtime dep
on CI.
2026-04-04 01:14:29 -04:00
Joseph O'Brien
3f529e9ed5 style: replace emoji with [OK] in workflow summary; cargo fmt integration tests 2026-04-03 19:07:47 -04:00
Joseph O'Brien
b4bb5760d6 fix(notgraph): sanitize hyphenated crate IDs in Mermaid output; add graph feature integration tests 2026-04-03 11:44:20 -04:00
Joseph O'Brien
82f84d52bb fix(notgraph): replace :: with / in module graph node labels to fix Mermaid parse error 2026-04-02 21:56:18 -04:00
Joseph O'Brien
17a321c227 fix(notgraph): add closing %% to module graph mermaid init directives 2026-04-02 21:54:54 -04:00
Joseph O'Brien
b5a27108d0 feat(notgraph): heatmap coloring, symbol counts, per-crate module graphs, cycle callouts 2026-04-02 20:53:07 -04:00
Joseph O'Brien
5c14230935 feat(notgraph): group crates into Core/Features/Tools subgraphs 2026-04-02 04:02:50 -04:00
Joseph O'Brien
f5b0dd87f8 fix(notgraph): replace vis.js with Mermaid for clean static flowchart 2026-04-02 03:50:53 -04:00
Joseph O'Brien
a2dcb123e8 fix(notgraph): reverse edge direction to dependency -> dependent 2026-04-02 03:19:19 -04:00
Joseph O'Brien
dcde5d1e82 fix(notgraph): render dep graph edges, add dark mode 2026-04-02 03:04:27 -04:00
Joseph O'Brien
88fa939867 fix(notgraph): phantom node cycles, inline mod symbols, dedup path_to_mod
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 02:38:22 -04:00
Joseph O'Brien
b1f3b36fc2 test(notgraph): fix cyclic integration test to use synthetic graph 2026-04-02 02:36:01 -04:00
Joseph O'Brien
377582269b test(notgraph): add integration tests for clean/cyclic/symbols fixtures 2026-04-02 02:35:15 -04:00
Joseph O'Brien
b61565dc22 feat(notgraph): wire full CLI pipeline 2026-04-02 02:31:40 -04:00
Joseph O'Brien
33fc4354c0 feat(notgraph): implement emit (md, json, html) 2026-04-02 02:30:21 -04:00
Joseph O'Brien
853bfbc427 feat(notgraph): implement analysis (fan stats, Kahn cycles, hotspots) 2026-04-02 02:29:07 -04:00
Joseph O'Brien
b73db06f7b feat(notgraph): implement symbols extractor 2026-04-02 02:27:45 -04:00
Joseph O'Brien
2b46656d3e feat(notgraph): implement module_graph collector 2026-04-02 02:26:53 -04:00
Joseph O'Brien
b3fe098de5 feat(notgraph): implement crate_graph collector 2026-04-02 02:25:57 -04:00
Joseph O'Brien
00b4974e75 feat(notgraph): define all shared types 2026-04-02 02:25:16 -04:00
Joseph O'Brien
f9bd96530e feat(notgraph): scaffold crate with lib+bin targets 2026-04-02 02:23:46 -04:00
Joseph O'Brien
58de007e19 feat(notstrap): migrate to notsecrets age-native API, remove sops shell-out
Replace AgeKeySource/resolve_age_key/install_age_key with IdentitySource/resolve_identities.
Update integration tests to use a valid age bech32 key fixture.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 21:19:23 -04:00
Joseph O'Brien
f80ea02f07 feat(notsecrets): migrate sources to IdentitySource trait, add resolve_identities, remove legacy API
- Replace AgeKeySource+retrieve() with IdentitySource+load() returning Box<dyn Identity>
- Rewrite bitwarden/file/prompt sources to implement new trait
- Add resolve_identities() public API with partial-success semantics
- Delete _legacy.rs and remove legacy re-exports from lib.rs
- Update integration tests to use new API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 21:16:39 -04:00
Joseph O'Brien
e388d75cf1 feat(notsecrets): Decryptor — identity-driven age decryption with MAC verification
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 21:06:55 -04:00
Joseph O'Brien
9863af6b45 feat(notsecrets): Encryptor — multi-recipient age encryption 2026-04-01 21:02:57 -04:00
Joseph O'Brien
b4cba74ea3 docs: update HANDOFF.md — age-native redesign progress (tasks 1–7 complete) 2026-04-01 20:58:09 -04:00
Joseph O'Brien
545a45b3d3 feat(notsecrets): EncryptedIdentity stub — passphrase-protected identity file 2026-04-01 20:57:22 -04:00
Joseph O'Brien
a0fe6f7128 feat(notsecrets): SSH RSA identity and recipient (OAEP-SHA256) 2026-04-01 20:55:42 -04:00
Joseph O'Brien
566501cb42 feat(notsecrets): SSH Ed25519 identity and recipient 2026-04-01 20:53:59 -04:00
Joseph O'Brien
b899198e98 feat(notsecrets): scrypt identity and recipient (passphrase-based) 2026-04-01 20:51:40 -04:00
Joseph O'Brien
6202c5dfe9 feat(notsecrets): X25519 identity and recipient with wrap/unwrap
Implements ECDH key wrapping via HKDF-SHA256 + ChaCha20Poly1305,
bech32 encode/decode for age1... recipients and AGE-SECRET-KEY-1... identities.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:49:31 -04:00
Joseph O'Brien
2476daafa6 feat(notsecrets): age wire format parser/serializer with unit tests 2026-04-01 20:47:00 -04:00
Joseph O'Brien
34d9e3d677 feat(notsecrets): scaffold age-native domain types and trait ports
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:44:05 -04:00