Proposals¶
A proposal is a task offered for a decision. An order is a task that is already authorized.
The difference is one element -- Task.intent -- and its practical meaning is which list a user
sees the task in:
Task.intent |
the user sees it in | what it asks |
|---|---|---|
proposal |
the Suggestions list | consider this |
order |
the Tasks list | do this |
That is the whole of it. A consumer branching on "is this mine to do, or mine to decide?" reads this element and nothing else.
Proposals are not the same thing as suggested-resource tasks¶
These two get confused constantly, and keeping them apart is why the vocabulary is what it is.
- A proposal is about what is being asked -- a decision rather than an instruction.
- A suggested-resource task is about what the task contains -- a suggested chart entry, carried in a contained transaction Bundle.
They are independent, and all four combinations are real:
intent = proposal |
intent = order |
|
|---|---|---|
| carries a suggested resource | a suggested chart entry, awaiting a decision | an authorized entry that just needs recording |
| carries none | "consider doing this" | an ordinary to-do |
The bottom-right cell is most of the chart. The top-right one is the cell people forget: an
authorized order can carry a suggested resource, where the entry is already agreed and the task exists
to get it recorded rather than decided. Anything that reads intent to decide whether a task
carries a suggested resource will misfile exactly that case.
Read the containment for "does this carry a suggested chart entry". Read intent for "what am I
being asked to do".
A note for readers coming from ServiceRequest
ServiceRequest.intent = proposal on a referral is the same word on a different resource and
carries no relationship to any of this. Nothing on a Task reads it, and the two never
appear together.
Approving¶
Approving a proposal sets Task.intent to order. It is one-way, and it moves the task from
the Suggestions list to the Tasks list.
What it does not do is write anything to the chart. That matters most where the proposal carries content: approving a suggested-resource task authorizes it, and instantiating is the separate act that turns its prototypes into real resources. A task can sit approved and un-instantiated, which is simply an order somebody still has to carry out.
Approving is also distinct from accepting, which is Task.status becoming accepted --
claiming the work. The three verbs are set out in full on the
suggested-resource tasks page.
Declining¶
Task.status becomes cancelled, with statusReason recording that a human declined it.
There is deliberately no rejected status. cancelled covers a proposal somebody declined and
one that became moot when its alternative was approved, so statusReason is the only thing that
tells them apart -- which makes it matter more here than anywhere else on the profile. A proposal
cancelled without a reason cannot afterwards say whether a clinician considered it and said no.
Where the proposal carried content, the task and its contained graph are retained. What was offered and refused is part of the record.
Alternatives: intent = option¶
Some proposals are mutually exclusive. Three ways to close the same care gap are not three things
to do -- they are one decision with three answers, and option is the code for that:
Task.intent |
means |
|---|---|
proposal |
consider this, on its own merits |
option |
one of a set; approving one moots the rest |
Approving an option moves its siblings to cancelled, with statusReason recording that they
stopped being on offer rather than that anyone declined them. That distinction is the reason
statusReason is close to required on a cancelled proposal.
Cards: proposals raised together¶
A decision-support service does not answer with a single proposal. One evaluation produces a card: a piece of advice, and under it the proposals that would act on it. Each becomes its own task -- its own owner, its own decision, its own contents -- and the card is what holds them together.
Every task from one card carries the card's identifier on
groupIdentifier, so the set comes back in one search and no parent resource has to
exist:
GET [base]/Task?group-identifier=https://fhir.apps.health/NamingSystem/nexus-cds-card|dm2-intensification:Patient/4021:a1c-above-target
Grouping is not alternation. Membership records that these were raised together, nothing more.
A card offering three things all worth doing raises three proposal tasks that happen to share a
group. A card offering three ways to close one gap raises three option tasks. Read intent and
groupIdentifier together; neither answers the question alone.
The card identifier follows the same rule as the harness key: it is derived from what the advice is about -- the patient and the gap -- and never from the evaluation that produced it. A value built from a hook instance or an execution timestamp mints a fresh group every time the rule fires, so the same unchanged advice re-evaluated tomorrow is unrecognisable as the same advice.
What produced a proposal¶
Task.requester, and nothing else. A proposal may come from an AI extraction graph, a
deterministic decision-support rule, or a person putting something to a colleague, and no code
anywhere distinguishes them.
A non-human producer is a logical Device reference: Reference.identifier under
https://fhir.apps.health/NamingSystem/nexus-harness-graph naming the graph or rule, with
Reference.type = "Device". The identifier need not resolve to a Device on the server -- it points
into the harness's own registry, at the granularity a clinician or auditor would recognise.