Match people to attributes
A person’s Role, Level, Location and Company are not typed in one by one. Each of those attributes carries a match expression — a short rule written against the person’s own fields — and Resorcerer assigns the first attribute whose rule matches. Change the rules and every person is re-evaluated; add a person, or let an integration update one, and their attributes are worked out on the spot.
That is what keeps a directory of a thousand people consistent: the rule
title:~engineer puts every engineer on the Engineer role, whether they came from
a CSV, from Microsoft Entra, or from someone typing them in.
Where the rules live
Section titled “Where the rules live”Open Roles, Levels, Locations or Companies under Configuration. Each row has three settings alongside its name:
| Setting | What it does |
|---|---|
| Match expression | The rule. A person whose fields satisfy it gets this attribute. Leave it blank for an attribute that is only ever set by hand or used as the default. |
| Priority | Evaluation order. Lower numbers run first; rows with the same priority run in name order. New rows start at 100. |
| Default | Assigned when no expression matches. At most one default per attribute type — setting a new default replaces the previous one. |
The list on each page is shown in evaluation order, top to bottom, so what you see is what runs.
How a person’s attributes are worked out
Section titled “How a person’s attributes are worked out”For each of the four attribute types, whenever a person record is saved:
- The rows are evaluated in priority order, then by name. The first row whose expression matches the person wins.
- If nothing matches, the row marked Default is used, if there is one.
- Otherwise the attribute is left empty.
This happens every time a person is written — created or edited by hand, updated by a CSV import, synced from an integration, or changed through the API — so a person’s attributes always reflect their record as it is now. Editing an attribute’s expression, priority or default re-evaluates everyone in the organization at once.
An attribute you’ve overridden on a person is skipped by all of this until you set it back to automatic.
The fields you can match on
Section titled “The fields you can match on”An expression refers to a person’s fields by name. Names are case-insensitive, and the aliases work anywhere the field name does.
| Field | Aliases | Holds |
|---|---|---|
name |
Full name | |
email |
mail |
Email address |
title |
jobTitle |
Job title |
department |
dept |
Department or team |
company |
employer |
Company name as synced or entered — the free-text field, not the Company attribute |
location |
office, site |
Office or location as synced or entered — the free-text field, not the Location attribute |
externalId |
extId |
Identifier from the directory or HR system |
externalName |
userName |
Username from the directory |
isActive |
active |
true or false |
startDate |
started, hired |
Start date |
endDate |
ended, leaving |
End date |
managerName |
manager |
The manager’s full name |
managerEmail |
The manager’s email address | |
group |
team |
The name of any group the person is a direct member of |
groupPath |
The full path of any group the person is a direct member of, from the root group down to that group (for example Engineering/Platform) |
The company and location fields are worth a second look. They are the plain text
that came from your directory or that someone typed — Contoso Ltd, Building 4, Reading — and they are the usual thing a Company or Location attribute’s rule matches
on. The attribute is the tidy, shared value Resorcerer derives from them.
group and groupPath are worth a second look too. A person can belong to several
groups at once, so both fields are multi-valued — the condition matches if any of a
person’s direct group memberships satisfies it. group compares against each group’s
own name (Platform), while groupPath compares against the full path from the root
group down to it (Engineering/Platform), so groupPath:~Engineering catches anyone
directly in Engineering or in a group nested underneath it, while group:Engineering
only catches people directly in a group actually named Engineering.
Note this is different from the Group filters elsewhere in the app: the People list’s
“Filter by group” is also direct-membership-only like group/groupPath here, but the
Group picker in a live model’s people in scope
is transitive — selecting a parent group there also includes everyone in its sub-groups.
Match expressions never include sub-group members implicitly; use groupPath:~<name> if
you want that.
Operators
Section titled “Operators”Every condition is field:value. Text comparisons ignore case.
| Expression | Matches people whose… |
|---|---|
department:Engineering |
department is exactly Engineering |
title:~engineer |
title contains engineer anywhere |
email:*@contractor.com |
email ends in @contractor.com — * stands for any run of characters, ? for exactly one |
location:"New York" |
location is New York — quote a value that has spaces in it |
title:!Intern |
title is anything other than Intern |
manager:null |
manager is empty (a blank text value counts as empty) |
endDate:* |
end date has a value |
isActive:false |
record is inactive |
startDate:<2024-01-01 |
start date is before 1 January 2024 |
startDate:[2024-01-01 TO 2024-12-31] |
start date falls within 2024, inclusive |
startDate:[2024-01-01 TO *] |
start date is on or after 1 January 2024 — * leaves an end open |
Wildcards also work inside a contains match (title:~*eng*), and >, >=, < and
<= all apply to dates. Ordering comparisons are for dates only; using one on a text
field is an error. There is no regular-expression syntax.
Write a date as YYYY-MM-DD. startDate:2024-06-01 means that whole day, and
startDate:<2024-06-01 means before it.
Dates can also be relative to today:
| Expression | Means |
|---|---|
startDate:>now-90d |
started within the last 90 days |
startDate:<now-1y |
started more than a year ago |
endDate:[now TO now+30d] |
leaving in the next 30 days |
The units are h (hours), d (days), mo (months) and y (years). Plain m is
rejected — it is ambiguous between minutes and months — so write mo for months.
Combining conditions
Section titled “Combining conditions”| Expression | Means |
|---|---|
department:Sales title:~manager |
both — whitespace between conditions is an implicit AND |
department:Sales AND title:~manager |
the same, spelled out |
department:Sales OR department:Marketing |
either |
NOT title:~lead |
negation |
(department:Sales OR department:Marketing) AND NOT title:~lead |
grouping |
&&, ||, ! and a leading - are accepted as alternatives to AND, OR and
NOT. Every term must be a condition: a bare word such as engineer on its own,
with no field in front of it, is an error rather than a free-text search.
Priority and the default
Section titled “Priority and the default”Priority is how you make a specific rule beat a general one. Say every title
containing engineer should be Engineer, except staff engineers:
| Role | Match expression | Priority |
|---|---|---|
| Staff Engineer | title:~"staff engineer" |
10 |
| Engineer | title:~engineer |
100 |
Priority 10 runs before 100, so a Staff Engineer, Platform lands on the first row
and everyone else with engineer in their title on the second.
The Default catches whoever is left. A company called Example Ltd marked as the
default Company gives every person a company unless a rule says otherwise — which is
usually the right thing for a workforce that is mostly your own employees plus a few
contractors matched by email:*@contractor.com.
An attribute with no expression and no default flag is never assigned automatically. It can still be chosen by hand as an override, which is the right shape for a rare exception you never want a rule to produce.
Overriding a person
Section titled “Overriding a person”Sometimes the rule is right for everyone except one person. Rather than complicate the expression, open that person from the People page and expand Attribute overrides. Each of the four attributes offers:
- Automatic — the derived value, shown next to the word so you can see what the rules currently produce. This is the normal setting.
- None (override) — pin the attribute to empty, even if a rule would match.
- A specific row — pin that attribute regardless of the rules.
An overridden attribute shows an Override badge in the person’s row on the People page. It stays exactly as you set it — through imports, syncs and rule changes — until you set it back to Automatic.
Overrides work on people managed by an integration too. The integration owns the person’s text fields (title, department, company, location and so on), but the attributes derived from them are always yours to pin.
Two other actions create overrides as a side effect, because each is an explicit choice about a person:
- Fixing an attribute mismatch from the Problems view by copying the position’s attributes onto the person.
- Filling one of the
roleattribute,levelattribute,locationattributeorcompanyattributecolumns in a CSV import.
Trying an expression before you save it
Section titled “Trying an expression before you save it”The expression editor helps as you type:
- Autocomplete offers field names as soon as you start a condition.
- The help button beside the field opens a syntax cheat sheet with the examples above.
- A live Matches N of M people count updates as you type, with a sample of who
matched, so you can see whether
title:~engis catching the English teachers too.
An expression that can’t be understood is underlined at the exact position of the problem, with a message saying what’s wrong — an unknown field name comes with suggestions for the fields that do exist. It can’t be saved until it’s fixed.
Recomputing everyone
Section titled “Recomputing everyone”Editing a rule re-evaluates the whole organization automatically. If you ever want to force that — after a large import, say, or to be sure the People page reflects the rules as they stand — use Recompute attributes on the People page. It re-derives every attribute that isn’t overridden and tells you how many people changed. Overrides are left alone.
Pinning from a CSV
Section titled “Pinning from a CSV”Import people accepts both kinds of value:
companyandlocationcolumns fill the free-text fields the rules match on.roleattribute,levelattribute,locationattributeandcompanyattributename an attribute row to pin as an override for that person.
A blank attribute cell means derive it — it clears any existing override on that person and lets the rules decide. A value that doesn’t match an existing row is left unmatched (and reported) unless you let the import create it.
The same language everywhere
Section titled “The same language everywhere”The rules use one expression language, evaluated the same way whether a person is saved from the app, imported, synced or written through the API. Scripts can try an expression exactly as the editor does, through the GraphQL API:
query { personAttributeMatchPreview(kind: ROLE, expression: "title:~engineer", sampleSize: 5) { matchCount totalCount sample { name email title department } error { message position suggestions } }}personQueryFields lists the fields and aliases above, and the
recomputePersonAttributes mutation does what the Recompute attributes button
does. An AI agent gets the same two things as MCP
tools: GetMatchExpressionSyntax returns this page’s operators and field list, and
PreviewMatchExpression tries a rule and reports the count, a sample, or the error. Roles, levels, locations and companies expose matchExpression,
matchPriority and isDefault on every surface, and a person’s attributes come back
as roleAttributeId, levelAttributeId, locationAttributeId and
companyAttributeId, each with an is…Override flag. See APIs.
If you had attributes before this feature
Section titled “If you had attributes before this feature”Attributes that were already assigned to people are kept as overrides, so nothing changes on its own. Once your rules are in place, set people back to Automatic — or use Recompute attributes after clearing overrides — to let the rules take over.
Related
Section titled “Related”- People and attributes — what the attributes are.
- Import people — the CSV columns.
- Integrations — which fields a sync writes.
- Connect Microsoft Entra ID — where
companyandlocationcome from in an Entra tenant.