give: take only a value a person holds, ask the desk by name, let the controller alone ask it, and announce every value given
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check fail: its merge-check.sh failed: --- FAIL: TestTheInstallersFirstUserListIsWhatTheControllerWouldCompose (0.55s)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check fail: its merge-check.sh failed: --- FAIL: TestTheInstallersFirstUserListIsWhatTheControllerWouldCompose (0.55s)
mesh/delivery superseded: a newer head of the same pull request
The review of 2026-10-09 (M4): - give refuses broker (the bus account issue mints) and any own secret the mesh may make itself; - the desk's prompt is asked by module, secret and machine, never with words of the caller's, and the bus denies the prompt's subjects to every principal but the controller, however wide its grant, so the prompt's 'the controller asks' is the bus's word (Permissions.PublishDeny, broker.ControllerOnly); - secret accept with a value is refused through a verb: a value comes from the terminal or the desk; - every value given for an own secret, at the terminal or the desk, raises the urgent condition secret-given on every channel, until the operator silences it.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/conditions"
|
||||
"github.com/novox/mesh-controller/internal/link"
|
||||
"github.com/novox/mesh-controller/internal/secrets"
|
||||
)
|
||||
@@ -44,6 +45,9 @@ type deskGive struct {
|
||||
accept func(value string) (untilStart bool, err error)
|
||||
// record writes the act in the hand-act log.
|
||||
record func(link.HandAct) error
|
||||
// announce raises the condition that says a module's own secret was given (secretGivenObservation), on
|
||||
// every channel; nil announces nothing (a test that does not look).
|
||||
announce func(node, module, name, how string) error
|
||||
}
|
||||
|
||||
// errNothingGiven is a prompt dismissed, or not answered in time: nothing changes.
|
||||
@@ -63,10 +67,12 @@ func (d deskGive) give(node, module, name, desk string) (string, error) {
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("no key could be made to take the value: %w", err)
|
||||
}
|
||||
// By name, never by words: the holder writes the prompt from these, and says the controller asks, which
|
||||
// the bus alone makes true (broker.ControllerOnly).
|
||||
raw, err := d.ask(desk, map[string]any{
|
||||
"prompt": name + " for " + module,
|
||||
"message": fmt.Sprintf("The mesh 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 asked for this.", name, module, node),
|
||||
"module": module,
|
||||
"secret": name,
|
||||
"node": node,
|
||||
"seal_to": public,
|
||||
"timeout_seconds": deskPromptWithin,
|
||||
})
|
||||
@@ -113,6 +119,11 @@ func (d deskGive) give(node, module, name, desk string) (string, error) {
|
||||
if err := d.record(act); err != nil {
|
||||
recorded = fmt.Sprintf("\n this act could NOT be recorded in the hand-act log, and is done anyway: %v", err)
|
||||
}
|
||||
if d.announce != nil {
|
||||
if err := d.announce(node, module, name, "at the desk on "+desk); err != nil {
|
||||
recorded += fmt.Sprintf("\n this change could NOT be announced on the operator's channels: %v", err)
|
||||
}
|
||||
}
|
||||
words := fmt.Sprintf("%s on %s now holds %q, given at the desk on %s and sealed to %s; the mesh cannot read it "+
|
||||
"back.\n run `push %s` to send it", module, node, name, desk, node, node)
|
||||
if untilStart {
|
||||
@@ -157,6 +168,7 @@ func giveAtDesk(ctx context.Context, node, module, name, desk string) error {
|
||||
return err
|
||||
})
|
||||
},
|
||||
announce: func(node, module, name, how string) error { return announceSecretGiven(ctx, node, module, name, how) },
|
||||
}
|
||||
words, err := d.give(node, module, name, desk)
|
||||
if err != nil {
|
||||
@@ -165,3 +177,31 @@ func giveAtDesk(ctx context.Context, node, module, name, desk string) error {
|
||||
fmt.Println(words)
|
||||
return nil
|
||||
}
|
||||
|
||||
// kindSecretGiven is the condition every value given for a module's own secret raises (the review of 2026-10-09,
|
||||
// M4): on every channel, so a bot token changed by somebody else — a channel that now answers for them — is
|
||||
// heard of. It stays until the operator silences or clears it.
|
||||
const kindSecretGiven = "secret-given"
|
||||
|
||||
// secretGivenObservation is that condition: which secret, of which module on which machine, how and when.
|
||||
func secretGivenObservation(node, module, name, how string, at time.Time) conditions.Observation {
|
||||
key := node + "." + module + "." + name
|
||||
return conditions.Observation{Scope: conditions.ScopeMachine, ID: key, Token: kindSecretGiven, Kind: kindSecretGiven,
|
||||
Machine: node, Severity: conditions.Urgent, Source: kindSecretGiven,
|
||||
Summary: fmt.Sprintf("%s of %s on %s was given %s at %s", name, module, node, how,
|
||||
at.Local().Format("2006-01-02 15:04")),
|
||||
Headline: "Secret of " + module + " changed",
|
||||
Explanation: fmt.Sprintf("The secret %s of %s on %s was given %s at %s. If you did not do this, "+
|
||||
"somebody else holds what %s acts with.", name, module, node, how, at.Local().Format("15:04"), module),
|
||||
Needs: "silence this if you gave it; if you did not, give the secret again yourself and unlink what it serves.",
|
||||
Resolved: "You saw that " + name + " of " + module + " was changed",
|
||||
Actions: []conditions.Action{conditions.SilenceAction(conditions.Key(conditions.ScopeMachine, key, kindSecretGiven))}}
|
||||
}
|
||||
|
||||
// announceSecretGiven raises it on this controller's keeper.
|
||||
func announceSecretGiven(ctx context.Context, node, module, name, how string) error {
|
||||
return withKeeper(ctx, func(k *conditions.Keeper) error {
|
||||
_, err := k.Observe(ctx, secretGivenObservation(node, module, name, how, time.Now()))
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user