Scope Context and Filtering
Much of the Agility application is looking at work through a subset of the Scope tree — a scope context. Understanding it explains a lot of filtering behaviour, and gives you the same idioms the product uses.
First, a naming note: the Scope asset type has worn two display names —
Project originally, and mostly Planning Level in current versions.
All three words mean the same asset type.
What a Scope Context Is
A scope context is the set of scopes defined by:
- a root scope — the context includes it and its subtree, and
- optional narrowing by
ScheduleandScopeLabels— keeping only subtree scopes on a given sprint schedule, or carrying a given label. (ScopeLabelis displayed in the UI as Program — another naming split worth knowing.)
The One-Query Idiom
The subtree-membership filter from Relations takes
the narrowing inside its bracket filter — and with variables keep the
values out of the expression:
{
"from": "Story",
"filter": ["Scope.ParentMeAndUp[Schedule=$Sched;ScopeLabels=$Label]=$Scope"],
"select": ["Number", "Name", "Scope.Name"],
"with": {
"$Sched": "Schedule:1064",
"$Label": "ScopeLabel:2001",
"$Scope": "Scope:1308"
},
"page": { "size": 50, "start": 0 }
}
Read it as: the story's scope has, among its ancestors-or-self that are on
$Sched and carry $Label, the root $Scope — i.e. the story is in the
narrowed subtree. Drop either bracket term if you are not narrowing by it.
The Precompute Pattern for Large Hierarchies
When the scope tree is large, evaluating the traversal per asset gets
expensive. It is often more efficient to build the scope context once,
then filter assets against the set — and with variables accept arrays,
which the filter treats as an in-list match:
{
"from": "Scope",
"filter": ["ParentMeAndUp=$Root", "Schedule=$Sched"],
"select": ["Name"],
"with": { "$Root": "Scope:1308", "$Sched": "Schedule:1064" },
"page": { "size": 200, "start": 0 }
}
{
"from": "Story",
"filter": ["Scope=$Context"],
"select": ["Number", "Name"],
"with": { "$Context": ["Scope:1308", "Scope:1450", "Scope:1451"] },
"page": { "size": 50, "start": 0 }
}
The same array-variable technique works on query.v1 and the Bulk API's
query command.
Rooms Are Scope Contexts
One of the most important things a Room — TeamRoom or PlanningRoom —
represents is a scope context: its Scope and Schedule define the
slice of the tree the room looks at.
Visibility follows from that in a way worth stating precisely:
- Every member can view every room — rooms themselves are not permission-gated.
- What a member sees inside a room is gated by their scope access — the room shows each viewer the intersection of its scope context with the scopes their role grants them.
Two members can open the same room and see different content; neither is broken.
Related Topics
-
Product feature: Planning level workspaces — what the scope tree this guide filters against means to users.
-
Relations —
ParentMeAndUpand the rollup relations