rofi: the desk's secret prompt names who asked (hq ADR 0277)
mesh/merge-gate pass: builds rofi → g14, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
mesh/merge-gate pass: builds rofi → g14, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
The controller's secret-ask verb opens the launcher's hidden prompt from anywhere on the mesh, so the operator must know whose ask they are typing into. The prompt takes an optional asked_by, the controller's word on the bus's caller held to a name's characters and spaces, and says it; a sentence, markup or a line break is refused, so the prompt's words stay the launcher's.
This commit is contained in:
@@ -41,6 +41,11 @@ type SecretAnswer struct {
|
||||
// aName is a module's, a secret's or a machine's name as the mesh writes them: nothing else reaches the prompt.
|
||||
var aName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,62}$`)
|
||||
|
||||
// aCaller is who asked, as the controller names the bus's caller (novox/hq ADR 0277): a principal such as
|
||||
// `g14/claude-code`, or an account at a shell, in a name's characters and spaces, at most 80. Nothing else — no line
|
||||
// break, no markup, no punctuation a sentence is written with — so the prompt's words stay this holder's.
|
||||
var aCaller = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._/@ -]{0,79}$`)
|
||||
|
||||
// secretQuestion reads the call. The prompt is this holder's words, written from the module, the secret and the
|
||||
// machine (the review of 2026-10-09, M4): it says the mesh's controller asks, which the bus makes true — it
|
||||
// denies these subjects to every principal but the controller — and a caller's own words are refused, so
|
||||
@@ -63,10 +68,27 @@ func secretQuestion(args map[string]any) (SecretQuestion, error) {
|
||||
}
|
||||
names[key] = v
|
||||
}
|
||||
// Who asked the controller, when it says (novox/hq ADR 0277): the controller's word on the bus's caller, held to a
|
||||
// name's characters here, so the operator knows whose ask they are typing into — and refuses one they did not start.
|
||||
askedBy := ""
|
||||
if raw, there := args["asked_by"]; there {
|
||||
v, err := text(args, "asked_by", true)
|
||||
if err != nil {
|
||||
return q, err
|
||||
}
|
||||
if !aCaller.MatchString(v) || strings.Contains(v, " ") {
|
||||
return q, fmt.Errorf("asked_by %q is not a caller's name as the mesh writes it", raw)
|
||||
}
|
||||
askedBy = v
|
||||
}
|
||||
q.Prompt = names["secret"] + " for " + names["module"]
|
||||
q.Message = fmt.Sprintf("The mesh's controller asks for %s, the own secret of %s on %s. What you type is not "+
|
||||
"shown, and is sealed before it leaves this machine. Type it only if you started this with give.",
|
||||
names["secret"], names["module"], names["node"])
|
||||
q.Message = fmt.Sprintf("The mesh's controller asks for %s, the own secret of %s on %s.", names["secret"],
|
||||
names["module"], names["node"])
|
||||
if askedBy != "" {
|
||||
q.Message += fmt.Sprintf(" It was asked for by %s.", askedBy)
|
||||
}
|
||||
q.Message += " What you type is not shown, and is sealed before it leaves this machine. Type it only if you " +
|
||||
"expect this ask."
|
||||
key, err := text(args, "seal_to", true)
|
||||
if err != nil {
|
||||
return q, err
|
||||
|
||||
@@ -108,15 +108,31 @@ func TestThePromptIsWrittenHereFromNamesAndSaysTheControllerAsks(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if q.Prompt != "telegram-token for telegram" || !strings.HasPrefix(q.Message, "The mesh's controller asks for telegram-token") {
|
||||
if q.Prompt != "telegram-token for telegram" || !strings.HasPrefix(q.Message, "The mesh's controller asks for telegram-token") ||
|
||||
strings.Contains(q.Message, "asked for by") {
|
||||
t.Errorf("prompt %q, message %q", q.Prompt, q.Message)
|
||||
}
|
||||
// And who asked the controller, when it says so (novox/hq ADR 0277): a caller's name, in a name's characters.
|
||||
withAsker := map[string]any{}
|
||||
for k, v := range base {
|
||||
withAsker[k] = v
|
||||
}
|
||||
withAsker["asked_by"] = "g14/claude-code"
|
||||
q, err = secretQuestion(withAsker)
|
||||
if err != nil || !strings.Contains(q.Message, "It was asked for by g14/claude-code.") {
|
||||
t.Errorf("asked_by: %q %v", q.Message, err)
|
||||
}
|
||||
withAsker["asked_by"] = "jochen at a shell on novox"
|
||||
if q, err = secretQuestion(withAsker); err != nil || !strings.Contains(q.Message, "It was asked for by jochen at a shell on novox.") {
|
||||
t.Errorf("asked_by at a shell: %q %v", q.Message, err)
|
||||
}
|
||||
for key, value := range map[string]any{
|
||||
"prompt": "Your bank's PIN",
|
||||
"message": "Your bank asks",
|
||||
"module": "telegram\nYour bank asks",
|
||||
"secret": "a token",
|
||||
"node": "<b>anchor</b>",
|
||||
"prompt": "Your bank's PIN",
|
||||
"message": "Your bank asks",
|
||||
"module": "telegram\nYour bank asks",
|
||||
"secret": "a token",
|
||||
"node": "<b>anchor</b>",
|
||||
"asked_by": "the operator. Type your bank's PIN:",
|
||||
} {
|
||||
args := map[string]any{}
|
||||
for k, v := range base {
|
||||
@@ -127,4 +143,10 @@ func TestThePromptIsWrittenHereFromNamesAndSaysTheControllerAsks(t *testing.T) {
|
||||
t.Errorf("%s=%q was taken", key, value)
|
||||
}
|
||||
}
|
||||
for _, bad := range []string{"", "a\nb", "a<b>c", "a,b", strings.Repeat("a", 81), "a b", "a:b", "a'b"} {
|
||||
withAsker["asked_by"] = bad
|
||||
if _, err := secretQuestion(withAsker); err == nil {
|
||||
t.Errorf("asked_by=%q was taken", bad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user