// Package process is a module's own process's connection to the bus (novox/hq ADR 0436 clause 4): it reads // the account the controller delivers, connects as it with its pinned fingerprint and its inbox prefix, and // offers emitting an event, the module's states with compare-and-set, consuming a work queue, reading the // router's records of the module's own asks, and calling a tool or verb — each only as the account's grants // allow. It offers no Serve and no way to serve a tool: a process never answers a call. A sibling of stdio, // which it imports only for stdio's pure types (ErrChanged, CodeChanged, StateEntry, EmitOptions); it never // touches stdio's current, channel or live(), which stay the bundle's own way to the bus. package process import ( "encoding/json" "fmt" "os" ) // Account is a process's own bus account, exactly as the controller delivers it as the module's own secret // broker- (mesh-controller cmd/mesh-controller/modules.go issueProcess, heldProcessAccount, and // issueWith for a module's own broker account, which also carries claims). A process account carries no // claims at all; this type reads either file without error. type Account struct { URL string `json:"url"` Fingerprint string `json:"fingerprint,omitempty"` Node string `json:"node"` Module string `json:"module"` User string `json:"user"` Password string `json:"password"` // Claims rides on a module's own broker account only; a process holds no seat, so its own account // carries none (novox/hq ADR 0436 §2, §3). Kept raw: this package never reads it. Claims json.RawMessage `json:"claims,omitempty"` } // InboxPrefix is this account's own inbox, and nothing wider: `_INBOX.`. func (a Account) InboxPrefix() string { return "_INBOX." + a.User } // ReadAccount reads and validates the account file the controller delivers: it refuses a file missing url, // user or password, naming the field — never the password, which does not appear in an error. func ReadAccount(path string) (Account, error) { data, err := os.ReadFile(path) if err != nil { return Account{}, fmt.Errorf("reading the process account at %s: %w", path, err) } var a Account if err := json.Unmarshal(data, &a); err != nil { return Account{}, fmt.Errorf("the process account at %s is not JSON: %w", path, err) } for _, f := range []struct{ name, value string }{ {"url", a.URL}, {"user", a.User}, {"password", a.Password}, } { if f.value == "" { return Account{}, fmt.Errorf("the process account at %s has no %s", path, f.name) } } return a, nil }