A6's request: the ledger's apply names the call it serves (ADR 0597 §7) so the runtime stamps the caller it proved as the operation's author; the id is read from the call's _meta under mesh/call, never from the arguments. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
92 lines
3.6 KiB
Go
92 lines
3.6 KiB
Go
package stdio
|
|
|
|
import (
|
|
"reflect"
|
|
"regexp"
|
|
"sync"
|
|
"unsafe"
|
|
)
|
|
|
|
// Unproven is the caller of a call the runtime named no caller for: one that arrived on the subject that names
|
|
// none, or from a runtime that names none (novox/hq issue 365). Said as a word, never left empty, so a record
|
|
// shows it was not proven.
|
|
const Unproven = "unproven"
|
|
|
|
// MetaCaller is where in a `tools/call`'s `_meta` the runtime names the caller: the bus user that published the
|
|
// call, which the runtime takes from the subject the call arrived on — that subject's last token, which the
|
|
// bus lets each user publish with its own name alone (novox/hq issue 365, by ADR 0259 §3's precedent). The
|
|
// runtime writes `_meta`; a caller writes only `arguments`, so no caller can name another.
|
|
const MetaCaller = "mesh/caller"
|
|
|
|
// busUser is the shape of a bus user's name: `<node>.<module>`, `person.<name>`, `controller` — names whose
|
|
// parts are safe in a subject. Anything else the runtime named is not a caller and reads as Unproven.
|
|
var busUser = regexp.MustCompile(`^[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)*$`)
|
|
|
|
// MetaCall is where in a `tools/call`'s `_meta` the runtime names the id of the call in flight, the id a ledger's
|
|
// apply names so the runtime stamps the caller it proved as the operation's author (novox/hq ADR 0597 §7):
|
|
// buscalls.MetaCall, written here too so this package imports nothing of buscalls.
|
|
const MetaCall = "mesh/call"
|
|
|
|
// callID is the shape of a call's id: one subject-safe token, as the runtime makes it. Anything else reads as none.
|
|
var callID = regexp.MustCompile(`^[A-Za-z0-9_-]{1,128}$`)
|
|
|
|
// inFlight is what the runtime said of one call while its tool runs.
|
|
type inFlight struct{ caller, call string }
|
|
|
|
// calls holds the caller and the id of every call while its tool runs, by the arguments map that call was handed.
|
|
var calls sync.Map // unsafe.Pointer → inFlight
|
|
|
|
func argsKey(args map[string]any) unsafe.Pointer {
|
|
return reflect.ValueOf(args).UnsafePointer()
|
|
}
|
|
|
|
// CallerOf is who called the tool that was handed args, as the runtime proved it: the bus user that
|
|
// published the call, or Unproven. Read from the runtime, never from the arguments' contents — a `caller`
|
|
// argument names nobody. Valid while the tool runs; arguments no call was handed have no caller.
|
|
func CallerOf(args map[string]any) string {
|
|
if args == nil {
|
|
return Unproven
|
|
}
|
|
if c, ok := calls.Load(argsKey(args)); ok {
|
|
return c.(inFlight).caller
|
|
}
|
|
return Unproven
|
|
}
|
|
|
|
// CallIDOf is the id of the call that was handed args, as the runtime named it under MetaCall: what a ledger's apply
|
|
// names (buscalls.ApplyRequest.Call) so the operation's author is the caller the runtime proved. Empty for arguments
|
|
// no call was handed, or a call the runtime named no id for; read from `_meta`, never from the arguments.
|
|
func CallIDOf(args map[string]any) string {
|
|
if args == nil {
|
|
return ""
|
|
}
|
|
if c, ok := calls.Load(argsKey(args)); ok {
|
|
return c.(inFlight).call
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// callIn is the call id a `tools/call`'s `_meta` names, or empty.
|
|
func callIn(meta map[string]any) string {
|
|
if s, ok := meta[MetaCall].(string); ok && callID.MatchString(s) {
|
|
return s
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// callerIn is the caller a `tools/call`'s `_meta` names, or Unproven.
|
|
func callerIn(meta map[string]any) string {
|
|
if s, ok := meta[MetaCaller].(string); ok && busUser.MatchString(s) {
|
|
return s
|
|
}
|
|
return Unproven
|
|
}
|
|
|
|
// runAs runs a tool with the caller and the call's id held for its arguments for as long as it runs.
|
|
func runAs(t Tool, caller, call string, args map[string]any) (any, error) {
|
|
key := argsKey(args)
|
|
calls.Store(key, inFlight{caller, call})
|
|
defer calls.Delete(key)
|
|
return t.Run(args)
|
|
}
|