55 lines
2.1 KiB
Go
55 lines
2.1 KiB
Go
// Package user owns the "主人" (owner) profile and account whitelist that the
|
|
// channel-layer policy engine uses for identity recognition. Per DevDocs/design/11
|
|
// §0, owner identification is structural — channel actor metadata matched against
|
|
// this whitelist — and is never driven by prompt text or an LLM judgment.
|
|
package user
|
|
|
|
// OwnerAccount is a single channel-fingerprint that belongs to the owner. The
|
|
// policy engine matches channel-layer actor metadata (platform + account id)
|
|
// against this list.
|
|
type OwnerAccount struct {
|
|
Platform string `yaml:"platform"`
|
|
AccountID string `yaml:"accountId"`
|
|
}
|
|
|
|
// OwnerProfile is the owner's identity record: a display name, the default
|
|
// persona bound to the owner, and the per-channel account whitelist. It is the
|
|
// source data for owner recognition; it is not injected into the persona's
|
|
// prompt as an authority.
|
|
type OwnerProfile struct {
|
|
ID string `yaml:"id"`
|
|
DisplayName string `yaml:"displayName"`
|
|
DefaultPersona string `yaml:"defaultPersona"`
|
|
Accounts []OwnerAccount `yaml:"accounts"`
|
|
// IdentityFile is the path to the LLM-visible identity/relationship note
|
|
// (persona knowledge, NOT an access-control authority).
|
|
IdentityFile string `yaml:"identityFile,omitempty"`
|
|
Notes string `yaml:"notes,omitempty"`
|
|
}
|
|
|
|
// IsOwner reports whether the given (platform, accountID) pair belongs to the
|
|
// owner according to the whitelist.
|
|
func (p *OwnerProfile) IsOwner(platform, accountID string) bool {
|
|
for _, a := range p.Accounts {
|
|
if a.Platform == platform && a.AccountID == accountID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// AccountIdentifiers returns the distinct channel account ids owned by the
|
|
// owner, for diagnostics / listing.
|
|
func (p *OwnerProfile) AccountIdentifiers() []string {
|
|
seen := make(map[string]struct{}, len(p.Accounts))
|
|
out := make([]string, 0, len(p.Accounts))
|
|
for _, a := range p.Accounts {
|
|
if _, ok := seen[a.Platform+":"+a.AccountID]; ok {
|
|
continue
|
|
}
|
|
seen[a.Platform+":"+a.AccountID] = struct{}{}
|
|
out = append(out, a.Platform+":"+a.AccountID)
|
|
}
|
|
return out
|
|
}
|