Files
Agent-System-Backend/pkg/extension/account_directory.go
T
weichenandCursor 84a6f6ff56
governance / governance (pull_request) Successful in 17s
ci / vet-and-test (pull_request) Successful in 1m2s
Merge Backend main into the shared renderer and two-trees work
Why: PR #209 is behind main by 14 commits (admin passwords, managed
interpreter path, U8 SQLite instance guard, EXT-20 regulations) and conflicted
in app wiring, host capabilities, migrations and the extension surface; the
user authorized merging the renderer line on 2026-10-18.
Evidence: content is the agent-exec transport 87a99ece (cursor worker, unit
backend-task10-sync-main-56a7f9f-r2, receipt
/tmp/cleanup-20261018/render/backend-sync-run2.json, SELF): gofmt, go build,
go vet and go test ./... (43 packages) passed. Host check: main migrations
1-36 unchanged, feature migrations moved from 36-47 to 37-48 in order with
identical SQL, surface.txt is the sorted union.
Impact: main's migration 36 instance_guard stays authoritative; databases that
ran unmerged feature builds with the old numbering must be recreated.
SurfaceVersion becomes 2.24.0-experimental.
Refs: PR #209, Backend main 56a7f9f

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 12:34:42 +00:00

94 lines
3.8 KiB
Go

package extension
import "context"
const AccountDirectorySchemaVersion = 1
const (
AccountDirectoryPurposeSystemUsers = "system.users"
AccountDirectoryPurposeProjectMembers = "project.member-candidate"
AccountDirectoryPurposeDocumentDuties = "document.duty-candidate"
AccountDirectoryModeExact = "exact"
AccountDirectoryModeFuzzy = "fuzzy"
)
// AccountDirectoryQuery is a request for account candidates. Actor and field
// permissions are deliberately absent: the host supplies the authenticated
// dispatch actor and obtains current domain authorization from its registrar.
type AccountDirectoryQuery struct {
SchemaVersion int `json:"schemaVersion"`
Purpose string `json:"purpose"`
ProjectID string `json:"projectId,omitempty"`
DocumentID string `json:"documentId,omitempty"`
Mode string `json:"mode"`
Query string `json:"query"`
SearchFields []string `json:"searchFields,omitempty"`
Status string `json:"status,omitempty"` // enabled|disabled|all; domain candidates require enabled
Cursor string `json:"cursor,omitempty"`
Limit int `json:"limit,omitempty"`
}
// AccountDirectoryEntry contains only identity, effective state and fields
// specifically authorized for the current purpose. Contact details never use
// this candidate DTO.
type AccountDirectoryEntry struct {
UserID string `json:"userId"`
Owner string `json:"owner"`
Name string `json:"name,omitempty"`
StaffNo string `json:"staffNo,omitempty"`
Valid bool `json:"valid"`
}
type AccountDirectoryPage struct {
Entries []AccountDirectoryEntry `json:"entries"`
DirectoryVersion string `json:"directoryVersion"`
NextCursor string `json:"nextCursor,omitempty"`
}
type AccountDirectoryLookup struct {
Entry AccountDirectoryEntry `json:"entry"`
DirectoryVersion string `json:"directoryVersion"`
}
// AccountDirectoryProvider is optional on trusted dispatch Host handles.
// Missing capability is a denial, not permission to use EXT-19 as a fallback.
type AccountDirectoryProvider interface {
QueryAccountDirectory(context.Context, AccountDirectoryQuery) (AccountDirectoryPage, error)
LookupAccountDirectory(context.Context, AccountDirectoryQuery, string) (AccountDirectoryLookup, error)
// LookupAccountDirectoryOwner is an explicit legacy-owner compatibility
// lookup; it resolves to the same stable user ID and applies the same scope.
LookupAccountDirectoryOwner(context.Context, AccountDirectoryQuery, string) (AccountDirectoryLookup, error)
}
// AccountDirectoryScopeRequest is constructed by the Backend from the trusted
// dispatch actor, registered plugin and untrusted locator. A resolver must
// validate the locator and current member.manage / duty.assign authority.
type AccountDirectoryScopeRequest struct {
Actor string
PluginID string
Purpose string
ProjectID string
DocumentID string
}
// AccountDirectoryScope is returned by the trusted in-process domain resolver.
// AllCandidates is explicit: a nil candidate list never means global access.
// CandidateIDs or CandidateOwners are applied before search and pagination;
// domain membership stores may use owners while the provider returns stable IDs.
type AccountDirectoryScope struct {
AllowedFields []string
MatchFields []string
AllCandidates bool
CandidateIDs []string
CandidateOwners []string
ScopeVersion string
}
type AccountDirectoryScopeResolver func(context.Context, AccountDirectoryScopeRequest) (AccountDirectoryScope, error)
// AccountDirectoryRegistrar is optional on a compiled in-process Registry.
// Only the trusted RDM plugin may register the domain authorization resolver.
type AccountDirectoryRegistrar interface {
RegisterAccountDirectoryScopeResolver(AccountDirectoryScopeResolver) error
}