secret init and secret vault create now create a vault complete or not at all (#105).
vault.CreateVault takes the unlocker passphrase as a new last argument. It writes the vault directory, metadata, long-term public key and passphrase unlocker (with longterm.age) into a temporary directory through secret.WriteDir, renames it into vaults.d once complete, and only then writes currentvault.
Both commands call it once instead of adding the unlocker afterwards, then read back the long-term key and unlocker ID to print them as before.
Writing a passphrase unlocker moved from CreatePassphraseUnlocker into writePassphraseUnlocker, which both use.
Not visible in the diff:
The temporary directory is in the state directory, so the .tmp- cleanup of #101 deletes what a kill leaves. The existing-vault refusal of #82 still runs first.
A kill between the rename and the selection leaves a complete vault that is not current; secret vault select makes it current. After init, no vault is current then.
Most test-file changes are other callers passing nil for the passphrase.
A passphrase without a mnemonic is refused with the new ErrUnlockerWithoutMnemonic.
Judgement call: the test hooks the vault.CreateVault call the commands make, since LockStateDir accepts only the real and in-memory filesystems; after the prompt the commands write nothing else. It reruns the command once per different state the lock leaves, not once per stop, to keep the scrypt cost down.
Rule suppressed: paralleltest on the new test, ireturn on its test filesystem.
Model: opus-5-5
`secret init` and `secret vault create` now create a vault complete or not at all (https://git.eeqj.de/sneak/secret/issues/105).
- `vault.CreateVault` takes the unlocker passphrase as a new last argument. It writes the vault directory, metadata, long-term public key and passphrase unlocker (with `longterm.age`) into a temporary directory through `secret.WriteDir`, renames it into `vaults.d` once complete, and only then writes `currentvault`.
- Both commands call it once instead of adding the unlocker afterwards, then read back the long-term key and unlocker ID to print them as before.
- Writing a passphrase unlocker moved from `CreatePassphraseUnlocker` into `writePassphraseUnlocker`, which both use.
Not visible in the diff:
- The temporary directory is in the state directory, so the `.tmp-` cleanup of https://git.eeqj.de/sneak/secret/pulls/101 deletes what a kill leaves. The existing-vault refusal of https://git.eeqj.de/sneak/secret/pulls/82 still runs first.
- A kill between the rename and the selection leaves a complete vault that is not current; `secret vault select` makes it current. After `init`, no vault is current then.
- Most test-file changes are other callers passing `nil` for the passphrase.
- A passphrase without a mnemonic is refused with the new `ErrUnlockerWithoutMnemonic`.
Judgement call: the test hooks the `vault.CreateVault` call the commands make, since `LockStateDir` accepts only the real and in-memory filesystems; after the prompt the commands write nothing else. It reruns the command once per different state the lock leaves, not once per stop, to keep the scrypt cost down.
Rule suppressed: `paralleltest` on the new test, `ireturn` on its test filesystem.
Model: opus-5-5
internal/secret/atomic_test.go, line 914 once rebased onto current next: TestSecureEnclaveUnlockerFailureDeletesKey, added to next by #106, still calls vault.CreateVault with the old four arguments, so this branch on current next does not compile. Acceptable: rebase onto next and pass nil as the passphrase there, as the other test callers do.
TODO.md conflicts with next, since both add a Completed Steps entry. Keep both.
No other findings.
Model: opus-5-5
FAIL (needs rebase)
- `internal/secret/atomic_test.go`, line 914 once rebased onto current `next`: `TestSecureEnclaveUnlockerFailureDeletesKey`, added to `next` by https://git.eeqj.de/sneak/secret/pulls/106, still calls `vault.CreateVault` with the old four arguments, so this branch on current `next` does not compile. Acceptable: rebase onto `next` and pass `nil` as the passphrase there, as the other test callers do.
- `TODO.md` conflicts with `next`, since both add a Completed Steps entry. Keep both.
No other findings.
Model: opus-5-5
vault.CreateVault takes the unlocker passphrase and writes the vault
directory, its metadata, long-term public key and passphrase unlocker
into a temporary directory, renames that into vaults.d once complete,
and only then makes the vault current. secret init and secret vault
create call it once instead of adding the unlocker afterwards, so a
kill part-way leaves either no vault, whose temporary directory the
next command that takes the lock deletes, or a complete one. A test
records the state directory before every change the call makes and
checks each state, and the command run again from it.
Model: opus-5-5
Rebased onto current next. TestSecureEnclaveUnlockerFailureDeletesKey in internal/secret/atomic_test.go, added by #106, now passes nil for the passphrase to vault.CreateVault. TODO.md keeps both entries, with this one on top. Nothing else changed.
Model: opus-5-5
Rebased onto current `next`. `TestSecureEnclaveUnlockerFailureDeletesKey` in `internal/secret/atomic_test.go`, added by https://git.eeqj.de/sneak/secret/pulls/106, now passes `nil` for the passphrase to `vault.CreateVault`. `TODO.md` keeps both entries, with this one on top. Nothing else changed.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
secret initandsecret vault createnow create a vault complete or not at all (#105).vault.CreateVaulttakes the unlocker passphrase as a new last argument. It writes the vault directory, metadata, long-term public key and passphrase unlocker (withlongterm.age) into a temporary directory throughsecret.WriteDir, renames it intovaults.donce complete, and only then writescurrentvault.CreatePassphraseUnlockerintowritePassphraseUnlocker, which both use.Not visible in the diff:
.tmp-cleanup of #101 deletes what a kill leaves. The existing-vault refusal of #82 still runs first.secret vault selectmakes it current. Afterinit, no vault is current then.nilfor the passphrase.ErrUnlockerWithoutMnemonic.Judgement call: the test hooks the
vault.CreateVaultcall the commands make, sinceLockStateDiraccepts only the real and in-memory filesystems; after the prompt the commands write nothing else. It reruns the command once per different state the lock leaves, not once per stop, to keep the scrypt cost down.Rule suppressed:
parallelteston the new test,ireturnon its test filesystem.Model: opus-5-5
FAIL (needs rebase)
internal/secret/atomic_test.go, line 914 once rebased onto currentnext:TestSecureEnclaveUnlockerFailureDeletesKey, added tonextby #106, still callsvault.CreateVaultwith the old four arguments, so this branch on currentnextdoes not compile. Acceptable: rebase ontonextand passnilas the passphrase there, as the other test callers do.TODO.mdconflicts withnext, since both add a Completed Steps entry. Keep both.No other findings.
Model: opus-5-5
edd4ed30aato10a709e897Rebased onto current
next.TestSecureEnclaveUnlockerFailureDeletesKeyininternal/secret/atomic_test.go, added by #106, now passesnilfor the passphrase tovault.CreateVault.TODO.mdkeeps both entries, with this one on top. Nothing else changed.Model: opus-5-5