A kept call holds a command's first word, never the line (issue 397)
kept() withheld the arguments line, values, secret and stdin, and kept the command argument of the generic command verb verbatim. A line such as `settings set <module> '<value>' --node <node>` therefore put the value into the calls record, which answers anyone who may call the seat. It is now kept as a mesh-cli line is: its first word, with the rest said to have been given. A command of one word is kept whole, since there is nothing after it to withhold, and one that is not a string is kept as "(given, not kept)". The record as it stands holds no such line: its whole answer, read at 2026-10-10 22:52 UTC, carries no call of the command verb. That says nothing of calls older than its window.
This commit is contained in:
@@ -468,6 +468,20 @@ func kept(args json.RawMessage) json.RawMessage {
|
||||
if words, ok := v.([]any); ok && len(words) > 0 {
|
||||
out[k] = []any{words[0], "(the rest given, not kept)"}
|
||||
}
|
||||
case k == "command":
|
||||
// The controller's own command line, kept as `line` is: its first word, never the rest.
|
||||
// `settings set <module> '<value>' --node <node>` through the `command` verb put the value
|
||||
// itself in this record, which answers anyone who may call the seat (novox/hq issue 397).
|
||||
if !isString {
|
||||
out[k] = "(given, not kept)"
|
||||
break
|
||||
}
|
||||
first, rest, _ := strings.Cut(strings.TrimSpace(s), " ")
|
||||
if strings.TrimSpace(rest) == "" {
|
||||
out[k] = first
|
||||
break
|
||||
}
|
||||
out[k] = first + " (the rest given, not kept)"
|
||||
case isString && len(s) <= 120:
|
||||
out[k] = s
|
||||
case isString:
|
||||
|
||||
@@ -166,6 +166,43 @@ func TestACallKeepsNoSettingsOrSecrets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A command line's own words may carry a setting's value or a secret, so only its first word is kept
|
||||
// — as a mesh-cli line's is (novox/hq issue 397).
|
||||
func TestACallKeepsNoCommandLine(t *testing.T) {
|
||||
for _, line := range []string{
|
||||
`settings set notes 'the operator's own passphrase' --node laptop`,
|
||||
`settings set notes --values {"token":"s3cret"}`,
|
||||
` node show laptop`,
|
||||
} {
|
||||
raw, err := json.Marshal(map[string]any{"command": line})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := string(kept(raw))
|
||||
// "set" is left out: it is a part of "settings", the word that is kept.
|
||||
for _, never := range []string{"passphrase", "s3cret", "notes", "laptop", "show"} {
|
||||
if strings.Contains(got, never) {
|
||||
t.Errorf("kept %s of %q: it carries %q", got, line, never)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(got, "(the rest given, not kept)") {
|
||||
t.Errorf("kept %s of %q: it does not say the rest was given", got, line)
|
||||
}
|
||||
}
|
||||
|
||||
// A command of one word is the whole of it: a reading command with no arguments stays readable.
|
||||
raw, _ := json.Marshal(map[string]any{"command": "builds"})
|
||||
if got := string(kept(raw)); got != `{"command":"builds"}` {
|
||||
t.Errorf("kept %s; a command of one word carries no value to withhold", got)
|
||||
}
|
||||
|
||||
// Not a string, so its first word cannot be taken: none of it is kept.
|
||||
raw, _ = json.Marshal(map[string]any{"command": []string{"settings", "set", "notes", "s3cret"}})
|
||||
if got := string(kept(raw)); strings.Contains(got, "s3cret") {
|
||||
t.Errorf("kept %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Only the newest KeptCalls are kept.
|
||||
func TestTheLogKeepsTheNewest(t *testing.T) {
|
||||
l := NewCallLog()
|
||||
|
||||
Reference in New Issue
Block a user