Skip to content

Commit

Permalink
[Docs] Add DR covering canonical use of managementPolicy.
Browse files Browse the repository at this point in the history
Part of #778, this aspect of the API has not been documented in any
detail.

Signed-off-by: Tom Cowland <tom@foundry.com>
  • Loading branch information
foundrytom committed Dec 19, 2022
1 parent 01ed453 commit 8e3951b
Showing 1 changed file with 255 additions and 0 deletions.
255 changes: 255 additions & 0 deletions doc/decisions/DR014-Management-policy-responses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# DR014 Management Policy responses

- **Status:** Proposed
- **Driver:** @foundrytom
- **Approver:** @feltech @ecmorris @antirotor @mattdaw
- **Outcome:** A Manager should additionally imbue a `managementPolicy`
response with the traits that it is capable of resolving for each
trait set.

## Background

The ability for a host to query a manager's capabilities and intent is a
critical part of the OpenAssetIO abstraction.

OpenAssetIO classifies entities (assets) using a Trait Set, which lists
one or more traits that describe it's nature. For example, and image
file may have the trait set `{'file', 'image', 'raster',
'colorManaged'}`.

The `managementPolicy` method is a high-level (i.e. not entity specific)
query that a host can use to determine a manager's behaviour in relation
to a specific trait set.

The answer to this query is commonly used by a Host to conditionally
enable user-facing functionality based on the behaviour of the specific
manager that is in use.

This mechanism is flexible, and so exactly how a manager should
implement its response is potentially ambiguous. This document outlines
the rationale behind the defined canonical behaviour.

## Relevant data

Documentation pertaining to the OpenAssetIO data model:

- [Entities, Traits and Specifications overview](../doxygen/src/EntitiesTraitsSpecifications.dox)
- [Compositional data model decision record](./DR007-Hierarchical-or-compositional-traits-for-specifications.md)
- [Unified Entity data model decision record](./DR008-Unify-the-entity-data-model.md)

Notable points:

- Trait sets combine multiple traits to increase specificity, rather
than meaning "or".
- Some managers may only care about certain specific traits (such as
those describing the assets content disposition), and handle all
'derivative entity types' the same.
- The `managementPolicy` query is not a required pre-requisite in the
use of `resolve`, et. al. but is used to adapt application behaviour
to improve user experience.

## Illustrative scenario

Consider a manager that pivots all behaviour around a
`file` trait - that defines that any entity with that trait stores its
data in a file. The manager's sole purpose is to manage the paths of
such entities. It is not interested in any other kinds, and should not
be involved in there creation or management.

As such, it wishes to opt-in to the management of any file-based entity,
regardless of its specific trait set.

The manager fulfills the API contract, by storing an entities trait set
in its database - allowing it to filter lookups by trait set, and
properly re-classify any given entity as required, but it can't store
arbitrary data, and so can't persist the data for any other traits.

A Host that manages several file-based entities (eg: its
main document and assorted data files that it reads/writes),
will query the manager's `managementPolicy` to determine for which of
these the manager should be involved with.

If a manager opts-out of managing any given trait set, then the host
will use its native UI/workflows for browsing and saving, if it opts-in,
then it will delegate UI and data locality responsibilities to the
manager.

So, how should this manager respond to the `managementPolicy` query for
any specific trait set?

Lets explore the scenario where the host is querying the manager's
policy for it's native document format, and for images it generates:

```python
traitSets =[
{ 'file', 'nodeGraph' }, # Main document
{ 'file', 'image', 'raster', 'colorManaged' } # Generated images
]
```

## Options considered

### Option 1 - Any Matching

It should respond on the basis of matching any of the traits in the set,
even if it doesn't understand many others:

```python
if FileTrait.kId in traitSet:
ManagedTrait.imbueTo(policy)
```

Such that it opts-in to managing all entities with the file trait in
their set.

```python
policies = [
{ 'managed': {...} }, # Main document
{ 'managed': {...} } # Generated Images
]
```

Any other queries for trait sets without the file trait would be empty
`{}` indicating un-managed status.

#### Pros

- Hosts can query specific and precise trait sets, but the manager does
not need to worry about all possible permutations.

#### Cons

- There is no way for a host to determine what traits can be resolved
(or persisted) for any given entity, and so must tolerate missing data
at a later date (e.g. the color space for the `colorManaged` trait, if
the manager can't ever provide this).

### Option 2 - Exact Matching

It should respond only to sets where it is capable of resolving or
persisting the required data:

```python
if traitSet == { FileTrait.kId }:
ManagedTrait.imbueTo(policy)
```

Such that it _only_ opts into managing the specifically limited trait
set that it can support:

```python
policies = [
{}, # Main document
{} # Generated Images
]
```

The Host would receive empty responses (`{}`) for both the original
trait sets, and so must potentially degrade and re-try its queried trait
set if it is happy with only a subset. e.g:

```python
traitSets = [
{ 'file', 'nodeGraph' }, # Main document
{ 'file', 'image', 'raster', 'colorManaged' }, # Generated images
{ 'file', 'image', 'raster' },
{ 'file', 'image' },
{ 'file' } # File
]
```

Resulting in:

```python
policies = [
{}, # Main document
{}, # Generated Images
{},
{},
{ 'managed': {...} }, # File
]
```

#### Pros

- Conveys only what traits are supported to the host, allowing
behaviour to be properly adapted to the manager's capabilities.

#### Cons

- Host implementation is significantly more complicated.
- No way to hint at any additional traits that may be resolvable
outside the typing trait set.

### Option 3 - Supported Traits Response

The host should also include any additional traits that it may attempt
to resolve in the future, e.g. if it supported the ability to customise
t,he file format used for writing images, by resolving a custom trait:

```python
traitSets =[
{ 'file', 'nodeGraph' },
{ 'file', 'image', 'raster', 'colorManaged', 'fileFormatOptions' }
]
```

The manager should respond as per Option 1, but in addition, imbue any
of the queried traits that the manager is capable of resolving:

```python
if FileTrait.kId in traitSet:
ManagerTrait.imbueTo(policy)
FileTrait.imbueTo(policy)
```

This would then look like the following:

```python
policies = [
{ 'managed': {...}, 'file': {} }, # Main document
{ 'managed': {...}, 'file': {} } # Generated Images
]
```

This indicates that the manager would like to handle interactions for
entities with these traits sets, but it can only resolve the `file`
trait.

> Note:
> We keep the concept additionally imbuing the `managed` trait
> (though it may seem superfluous, as an empty trait set is equivalent to
> un-managed) as in practical use cases it may well have other properties
> that cover topics such as exclusivity/etc.
> There are also additional traits that may be imbued by the manager to
> determine how it handles various aspects of the publishing process,
> e.g. thumbnails.
#### Pros

- Explicit communication of exact capabilities, so hosts and managers
can suitably adapt behaviour.
- Facilitates functional workflows where the result of `managementPolicy`
can be passed as the requested trait set for `resolve`.

#### Cons

- Implementation in the manager and host may be slightly more involved
than other options in some scenarios.

## Outcome

The `managementPolicy` mechanism should always be queried with the full
trait set for any given entity specification, and any additional traits
a host may attempt to resolve for that type (if known).

The response populated by a manager should include all resolvable traits
from that set, along with any additional traits that describe the
manager's behaviour.

## Rationale

This offers the best of both worlds. It provides the highest quality
information to both hosts and managers, whilst keeping the additional
programming overhead to a minimum. It allows both parties to adapt their
business logical in an explicit and coordinated fashion.

0 comments on commit 8e3951b

Please sign in to comment.