Locked files (--lock): repo-authoritative entries. Checkpoint skips
them (preserves repo version). Status reports "drifted" instead of
"modified". Restore always overwrites if hash differs, no prompt.
Use case: system-managed files the OS overwrites.
Directory-only entries (--dir): track directory itself without
recursing. Restore ensures directory exists with correct permissions.
Use case: directories that must exist but contents are managed
elsewhere.
Add refactored to use AddOptions struct (Encrypt, Lock, DirOnly)
instead of variadic bools.
Proto: ManifestEntry gains locked field. convert.go updated.
7 new tests. ARCHITECTURE.md and README.md updated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI: sgard encrypt init [--fido2], add-fido2 [--label], remove-slot,
list-slots, change-passphrase. sgard add --encrypt flag with
passphrase prompt for DEK unlock.
Garden: RemoveSlot (refuses last slot), ListSlots, ChangePassphrase
(re-wraps DEK with new passphrase, fresh salt).
Proto: ManifestEntry gains encrypted + plaintext_hash fields. New
KekSlot and Encryption messages. Manifest gains encryption field.
server/convert.go: full round-trip conversion for encryption section
including KekSlot map.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace per-call SSH signing with a two-layer auth system:
Server: AuthInterceptor verifies JWT tokens (HMAC-SHA256 signed with
repo-local jwt.key). Authenticate RPC accepts SSH-signed challenges
and issues 30-day JWTs. Expired-but-valid tokens return a
ReauthChallenge in error details (server-provided nonce for fast
re-auth). Authenticate RPC is exempt from token requirement.
Client: TokenCredentials replaces SSHCredentials as the primary
PerRPCCredentials. NewWithAuth creates clients with auto-renewal —
EnsureAuth obtains initial token, retryOnAuth catches Unauthenticated
errors and re-authenticates transparently. Token cached at
$XDG_STATE_HOME/sgard/token (0600).
CLI: dialRemote() helper handles token loading, connection setup,
and initial auth. Push/pull/prune commands simplified to use it.
Proto: Added Authenticate RPC, AuthenticateRequest/Response,
ReauthChallenge messages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add now recursively walks directories instead of creating a single
"directory" type entry. Extract addEntry helper for reuse. Implement
MirrorUp (sync filesystem state into manifest) and MirrorDown (sync
manifest state to filesystem with untracked file cleanup). Add CLI
mirror command with up/down subcommands.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GoReleaser builds static binaries for linux/darwin on amd64/arm64,
injecting version via ldflags. Version command prints the embedded
version (defaults to "dev" for local builds).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove: untrack files, remove manifest entries, save. 2 tests.
Verify: check blobs against manifest hashes, report ok/mismatch/missing. 3 tests.
List: return all tracked entries, CLI formats by type. 2 tests.
Diff: compare stored blob vs current file, simple line diff. 3 tests.
Each command in its own file (garden/<cmd>.go) for parallel development.
Remove, verify, list implemented by parallel worktree agents; diff manual.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds Garden.List() method that returns manifest entries, unit tests
for empty and populated repos, and a CLI command that formats output
by entry type (file with hash prefix, link with target, directory).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verify iterates manifest file entries, confirms each blob exists in the
store, and re-hashes the content to detect corruption. Includes unit
tests for the ok, hash-mismatch, and blob-missing cases, plus a thin
CLI wrapper that exits non-zero on any failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements Garden.Remove() which unregisters paths from the manifest,
plus unit tests and the CLI wiring via cobra.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restore writes tracked files back to their original locations.
Supports selective path restoration, force mode, and a confirm
callback for files where the on-disk mtime >= manifest timestamp
(truncated to seconds for cross-platform reliability). Creates
parent directories, recreates symlinks, and sets file permissions.
CLI: sgard restore [path...] [--force].
6 new tests (file, permissions, symlink, parent dirs, selective, confirm skip).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Checkpoint re-hashes all tracked files, stores changed blobs, and
updates per-file timestamps only when content changes. Missing files
are skipped gracefully. Status compares each tracked entry against
the filesystem and reports ok/modified/missing.
CLI: sgard checkpoint [-m message], sgard status.
4 new tests (changed file, unchanged file, missing file, status).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Garden package ties manifest and store together. Supports adding
files (hashed and stored as blobs), directories (manifest-only),
and symlinks (target recorded). Paths under $HOME are stored as
~/... in the manifest for portability. CLI init and add commands
wired up via cobra.
8 tests covering init, open, add for all three entry types,
duplicate rejection, HashFile, and tilde path expansion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove all old C++ source files, proto definitions, CMake build,
clang configs, IDE files, and Trunk linter config. Initialize Go
module (github.com/kisom/sgard) with cobra and yaml.v3 deps.
Set up cobra root command with --repo persistent flag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>