next → main: v1.0.0-rc3 #82

Open
clawbot wants to merge 10 commits from next into main
Collaborator

next is tagged v1.0.0-rc3 and has no known open bug. Over main it fixes:

  • -n/--words are decimal only; -n 010 used to derive key 8. #75
  • Every argument, including -o, is checked before the mnemonic is asked for or the mnemonic command run. #79, #87
  • An invalid mnemonic is refused with what is wrong with it, never naming a word. #76
  • Ctrl-D ends the prompt, and a signal at the prompt puts the terminal back. #78, #91
  • ssh to works under IdentitiesOnly yes. #74
  • age decrypt reads a text-form file with blank lines in front, as age does. #77
  • The mnemonic command no longer inherits KEYFUNC_MNEMONIC or KEYFUNC_MNEMONIC_COMMAND. #80

Changes a user may notice:

  • A mnemonic command that runs keyfunc itself no longer finds the main mnemonic in either variable.
  • A user's own -o IdentitiesOnly=yes after the host is overridden by ssh to.
  • A capitalised word is refused as not on the word list; Ctrl-H is no longer a backspace at the prompt.
  • The new prompt was run only on Linux; macOS, the BSDs and the other systems were built, not run.

next also carries its own copy of the main commit for #70; they merge cleanly, and the result is exactly next.

Model: opus-5-5

`next` is tagged `v1.0.0-rc3` and has no known open bug. Over `main` it fixes: - `-n`/`--words` are decimal only; `-n 010` used to derive key 8. https://git.eeqj.de/sneak/keyfunc/issues/75 - Every argument, including `-o`, is checked before the mnemonic is asked for or the mnemonic command run. https://git.eeqj.de/sneak/keyfunc/issues/79, https://git.eeqj.de/sneak/keyfunc/issues/87 - An invalid mnemonic is refused with what is wrong with it, never naming a word. https://git.eeqj.de/sneak/keyfunc/issues/76 - Ctrl-D ends the prompt, and a signal at the prompt puts the terminal back. https://git.eeqj.de/sneak/keyfunc/issues/78, https://git.eeqj.de/sneak/keyfunc/issues/91 - `ssh to` works under `IdentitiesOnly yes`. https://git.eeqj.de/sneak/keyfunc/issues/74 - `age decrypt` reads a text-form file with blank lines in front, as `age` does. https://git.eeqj.de/sneak/keyfunc/issues/77 - The mnemonic command no longer inherits `KEYFUNC_MNEMONIC` or `KEYFUNC_MNEMONIC_COMMAND`. https://git.eeqj.de/sneak/keyfunc/issues/80 Changes a user may notice: - A mnemonic command that runs keyfunc itself no longer finds the main mnemonic in either variable. - A user's own `-o IdentitiesOnly=yes` after the host is overridden by `ssh to`. - A capitalised word is refused as not on the word list; Ctrl-H is no longer a backspace at the prompt. - The new prompt was run only on Linux; macOS, the BSDs and the other systems were built, not run. `next` also carries its own copy of the `main` commit for https://git.eeqj.de/sneak/keyfunc/issues/70; they merge cleanly, and the result is exactly `next`. Model: opus-5-5
clawbot added 2 commits 2026-10-13 02:38:06 +02:00
sneak/secret now carries its own copy of go-bip39
(sneak/secret#130), so requiring it at that
commit, ef0ae90, lets go mod tidy drop go-bip39 from go.sum. Earlier,
secret renamed its module to sneak.berlin/go/secret
(sneak/secret#43), so the requirement, the
two imports of its bip85 package and the README sentence naming that
package move to the new path. The bip85 functions keyfunc calls are
unchanged, and no other requirement moves.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
Both flags were uint32 flags, which the flag library reads with base-0 rules, so `-n 010` derived key 8 and `0x10` or `1_0` were accepted. Both now hold options.Decimal, a flag value whose Set parses with strconv.ParseUint(text, 10, 32): a leading zero stays decimal, and a base prefix, an underscore, a sign or an empty value is refused with an error naming the flag while the flags are parsed, before any command runs. Its type is still named uint32, so --help is unchanged and GetUint32 still reads it back. The README says the index is a decimal number.

Model: opus-5-5
clawbot added the merge-ready label 2026-10-13 02:38:07 +02:00
sneak was assigned by clawbot 2026-10-13 02:38:08 +02:00
clawbot added 1 commit 2026-10-14 20:48:24 +02:00
The mnemonic command ran with the tool's whole environment, so a
mnemonic set in KEYFUNC_MNEMONIC reached it, although the command is
there to supply one of its own. It now gets the environment ssh and
sftp already get, with KEYFUNC_MNEMONIC and KEYFUNC_MNEMONIC_COMMAND
removed. The function that builds that environment moves from the ssh
command group into internal/mnemonic, beside the two variable names,
so all three programs use the one copy. The README says so.

A mnemonic command that runs keyfunc itself no longer finds the main
mnemonic in either variable.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-14 21:05:51 +02:00
The key index, --words, the --to recipients and the input file of
age encrypt and age decrypt were checked only after the mnemonic had
been obtained, so a run that could not succeed still prompted for it or
ran the mnemonic command. options.Index now refuses an index above
derive.MaxIndex, which covers every command group; the mnemonic command
calls the new childmnemonic.CheckWords first; age encrypt reads its
recipients with the new agekey.Recipients, and both age commands open
their input, before the key is derived. The README says which checks
come first.

Judgement call: the -o path is still looked at after the mnemonic.

Model: opus-5-5
clawbot added 1 commit 2026-10-14 21:12:59 +02:00
Turn IdentitiesOnly off for ssh to (closes #74)
check / check (push) Canceled after 0s
44cb5215b0
ssh to now gives ssh -o IdentitiesOnly=no before the host, next to
-o IdentityAgent. With IdentitiesOnly yes in the user's ssh
configuration, ssh listed the agent's key but never offered it, and
the login failed with Permission denied. An option on the command
line wins over the configuration, and the tool's agent holds only the
derived key, so turning the option off adds no other key. A test
against the stand-in ssh requires the option before the host, and the
README's ssh to section names both options.

Judgement call: a user's own -o IdentitiesOnly=yes after the host is
now overridden.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-14 22:05:38 +02:00
Say why a mnemonic is refused (closes #76)
check / check (push) Canceled after 0s
5582c02edf
Every way a mnemonic could be invalid was reported as a checksum
failure, including an empty one. It is now refused as empty, as having
a word count other than 12, 15, 18, 21 or 24, as having a word that is
not on the BIP-39 word list, or as failing the checksum. A word not on
the list is named by its position, never by the word itself.

Judgement call: words are not lower-cased, so a capitalised word is
reported as not on the word list.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-14 22:35:32 +02:00
age decrypt took the text form only when the file began exactly with
-----BEGIN AGE ENCRYPTED FILE-----, so a blank line in front made it
read the file as the binary form and refuse it. It now looks for that
line past up to 1024 bytes of whitespace, as the age tool does, and
the text form reader skips the blank lines. The README's age decrypt
section says so.

Judgement call: that first line with spaces in front of it on the same
line is still refused, as age refuses it.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-14 23:07:11 +02:00
age encrypt and age decrypt looked at the -o path only after the
mnemonic had been obtained, so a path that could never be written
still prompted for the mnemonic or ran the mnemonic command. Both now
refuse, before the key is derived, an -o path that is a directory or a
symlink to one, whose directory is missing or is not a directory, or
that is a symlink pointing at nothing. The check creates nothing;
output still looks at the path when it writes, so the file beside the
target is made when it was before. The README names the -o path among
what is checked first.

Left out: a directory the tool may not write to is found only when it
writes.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-14 23:35:27 +02:00
term.ReadPassword reads the terminal with a raw read that returns 0
bytes at the end of input and takes that as nothing yet, so Ctrl-D at
the prompt did nothing. On the Unix systems the prompt now sets the
terminal as ReadPassword does and reads the line from standard input,
which reports the end of input; elsewhere, such as Windows, it still
uses ReadPassword. Ctrl-D with nothing typed gives an empty mnemonic,
refused with status 1, and the terminal settings are put back. A test
types Ctrl-D at the prompt on a pseudo-terminal.

Unverified: the prompt was run only on Linux; other systems were built.
Deviation: a Ctrl-H byte is no longer a backspace at the prompt.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
clawbot added 1 commit 2026-10-15 01:35:44 +02:00
A SIGINT, SIGTERM or SIGHUP at the mnemonic prompt killed the tool
with echo still off. The prompt now catches them from before echo goes
off and reads the line in a goroutine. Once the line is read or a
signal arrives, it puts the terminal settings back and stops catching;
if a signal has arrived by then, it sends the tool the same signal
again, so the tool is still ended by it (130 for SIGINT in a shell).
A test sends SIGINT at the prompt on a pseudo-terminal.

The signals package moves from internal/cli to internal/signals, since
the mnemonic prompt now uses it as well.

Untested: a signal that comes just as the line is read.

Model: opus-5-5
clawbot changed title from next → main: v1.0.0-rc2 to next → main: v1.0.0-rc3 2026-10-15 01:36:06 +02:00
Some required checks failed
check / check (push) Canceled after 0s
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin next:next
git checkout next
Sign in to join this conversation.