Skip to content

Task Profile

Canonical../StructureDefinition/nexus-emr-core-clinical-task
Statusdraft · 1.26.0
BaseTask (constraint)
SourceFSH · JSON

A unit of work in the chart: who asked for it, who owns it now, what has been said about it, and which chart element it concerns. Inbox items, to-dos, follow-ups, a result that needs review -- deliberately one kind of work item.

TypedFhir API / Pydantic schema

The typed accessor surface Task exposes for Task — generated from this IG's compiled profile; each typed accessor has a validating raw-FHIR twin (xRaw) where marked. The three ports are parity-enforced.

The AI-facing shape: from typed_fhir.facade.generated.schemas import TaskSchemamodel_json_schema() is a structured-output / tool definition; instantiating validates an extraction. Generated source.

class TaskSchema(BaseModel):
    """AI-facing shape of the Task profile: the facade's typed accessor
    surface (curated + salient fields) as a pydantic model. `model_json_schema()` is a
    structured-output / tool schema; instantiating validates an extraction."""

    model_config = ConfigDict(extra="forbid")

    instantiates_canonical: str | None = Field(
        None,
        description=(
            "Formal definition of task (canonical). References to formal protocols, guidelines, "
            "or ActivityDefinitions that this task follows. Note: MERT requirement for "
            "protocol-based task execution. Task.instantiatesCanonical — 0..1"
        ),
    )
    instantiates_uri: str | None = Field(
        None,
        description=(
            "Formal definition of task (URI). URI references to external protocols, guidelines, "
            "or specifications. Note: MERT requirement for external protocol references. "
            "Task.instantiatesUri — 0..1"
        ),
    )
    based_on: Reference | None = Field(
        None,
        description=(
            "Request fulfilled by this task (available, not must-support). The request, order, or "
            "authorization that initiated this task. Note: The ORDER this task carries out, and "
            "only an order: base R4 leaves this open to any resource, and this profile narrows it "
            "to the four request types, so `basedOn` cannot quietly become a second `focus`. "
            "Distinct from `focus` (the chart element the task is filed against) and from "
            "`encounter` (the visit it arose in). Available and typed, but not must-support -- "
            "populate it when a task genuinely fulfills an order, and do not synthesize one to "
            "fill the element. Task.basedOn — 0..*"
        ),
    )
    group_identifier: dict | None = Field(
        None,
        description=(
            "Shared identifier for tasks raised together (e.g. one decision-support card). "
            "Identifier shared by every task raised in one batch, so the batch is recoverable as "
            "a set. For suggestions produced by a decision-support service, this carries the "
            "CARD: all of a card's suggestions become sibling tasks with the same value here. "
            "Distinct from `Task.identifier`, which identifies THIS task (and, for "
            "machine-written tasks, the gap it addresses under the producing capability's key "
            "namespace). Note: A DISPLAY GROUPING AND NOTHING ELSE: consumers MUST NOT read this "
            "element, or its absence, as a signal of which producer raised a task, because "
            "grouping is available to every producer -- a harness capability proposing several "
            "chart entries from one note is one evaluation raising a set exactly as a card is. "
            "Producer is declared on `requester`. Find the siblings with "
            "`Task?group-identifier={system}|{value}`. Grouping is orthogonal to `intent`: "
            "siblings are ALTERNATIVES only when they carry `intent = #option`, in which case "
            "accepting one normally cancels the rest. Where the group has no natural upstream "
            "identifier, any stable value the producer can regenerate will do -- but derive it "
            "from what the card is ABOUT, on the same reasoning as the business key, or a "
            "re-evaluation produces a new group for the same advice. Task.groupIdentifier — 0..1"
        ),
    )
    part_of: Reference | None = Field(
        None,
        description=(
            "Parent task for sub-tasks and branches. Reference to parent task when this task is "
            "part of a larger workflow or represents a sub-task. Note: Supports Nexus EMR "
            "workflow branching and task hierarchy. Task.partOf — 0..*"
        ),
    )
    status: Literal[
        "accepted",
        "cancelled",
        "completed",
        "draft",
        "in-progress",
        "on-hold",
        "ready",
    ] | None = Field(
        None,
        description=(
            "Where the task is in its lifecycle. Where this task sits in its lifecycle. THESE ARE "
            "MEANINGS, NOT A PATH -- any state may follow any other, and the ordinary cases prove "
            "it: `ready` straight to `completed` is a normal day's work, and `accepted` back to "
            "`ready` is handing something back. What each code means is the specification; the "
            "order is not. - `draft` -- being composed. In nobody's list yet, and nobody is "
            "expected to act on it. - `ready` -- actionable and in its owner's list. Where the "
            "owner is a CareTeam, it is in the team's pool and nobody has claimed it. Where there "
            "is no owner at all, it is in EVERY user's list: unassigned work is ready work that "
            "has not been narrowed to anyone yet. - `accepted` -- claimed by its owner and not "
            "yet started. The point of a state between `ready` and `in-progress` is CIRCULATION: "
            "claiming a pooled task moves `owner` from the team to the person and takes it out of "
            "everyone else's view, which is a real event even though no work has started. - "
            "`in-progress` -- actively being worked. - `on-hold` -- deliberately parked: snoozed, "
            "or waiting on something outside this task. Distinct from `ready` because a parked "
            "task should not read as awaiting action. - `completed` -- the work was done. - "
            "`cancelled` -- the work will not be done. This covers BOTH a proposal a human "
            "declined and a proposal that became moot (its alternative was approved, or the gap "
            "closed on its own), which is why `Task.statusReason` matters here more than anywhere "
            "else on this profile. Note: The binding is a REQUIRED subset of R4 TaskStatus, not "
            "the base value set: `requested` (a second name for `ready`), `received`, `rejected`, "
            "`failed` and `entered-in-error` are excluded, each for a reason given on the value "
            "set. The one worth knowing is `rejected`: a declined proposal is `cancelled`, so "
            "declining something and it becoming moot no longer live in different states. "
            "`Task.statusReason` carries which of the two happened and SHOULD be populated "
            "whenever a proposal is cancelled -- without it the record cannot say whether a "
            "clinician considered this and said no. Task.status — 1..1"
        ),
    )
    status_reason: Concept | None = Field(
        None,
        description=(
            "Reason for current status. Captures why the task is in its current state, "
            "particularly for cancelled or failed states. Note: Load-bearing on a CANCELLED "
            "PROPOSAL and close to required there in practice. `cancelled` carries two facts that "
            "used to be separate states: a human considered this and declined it, and this "
            "stopped being on offer (its alternative was approved, the care gap closed on its "
            "own). Those are different clinical records and only this element can now tell them "
            "apart, so a writer cancelling a proposal without a reason destroys information the "
            "model can no longer recover. Task.statusReason — 0..1"
        ),
    )
    business_status: Concept | None = Field(
        None,
        description=(
            "Task business status. Business-specific status information that supplements the "
            "standard lifecycle status. `status` answers where the task sits in its lifecycle; "
            "`businessStatus` answers whether anything about it needs a human's attention. Note: "
            "MERT requirement for additional status context beyond standard FHIR states. This "
            "element carries a lifecycle SUB-STATE of the task itself -- a second axis beside "
            "`status`, not a flag and not a category. ⚠ THE BINDING IS REQUIRED, and was "
            "extensible until 1.26.0. A sub-state this guide does not recognise is an ERROR, not "
            "a local extension: this element sits beside `status` and reads as status, a "
            "statutory correction outcome is recorded here, and an element carrying decisions of "
            "that weight cannot also be where a deployment parks arbitrary workflow state -- a "
            "reader cannot tell the two apart. A deployment that needs a sub-state this guide "
            "does not define gets it added to the bound value set, in a reviewed release; it does "
            "not mint one locally. TWO VOCABULARIES share the binding and they are NOT "
            "interchangeable: the general sub-states, and the statutory correction lifecycle, "
            "which `nexus-task-bizstatus-scope` confines to tasks filed under `privacy-request` "
            "-- a correction code on ordinary work is an error. See the Correction Task profile "
            "for the tighter shape those tasks declare. `needs-review` is DEPRECATED and "
            "inbound/legacy only: the workflow it was built for (a completed referral that a new "
            "message should resurface) is modelled as a NEW Task on the same ServiceRequest, "
            "because a completed task does not come back to life. Task.businessStatus — 0..1. "
            "codes (required): accepted | amendment-completed | completed | denied | "
            "disagreement-logged | in-review | needs-review | ok | …"
        ),
    )
    intent: Literal["option", "order", "proposal"] | None = Field(
        None,
        description=(
            "order (do this) | proposal (consider this) | option (one of these). What the owner "
            "is being asked to do with this task. Independent of whether the task carries a "
            "suggestion. * `order` -- the work is authorized and assigned; the owner is expected "
            "to DO it. Inbox items, follow-ups and to-dos are orders, and a user sees them in a "
            "Tasks list. A suggested-resource task MAY be an order, where the suggested entry is "
            "already authorized and the task exists to get it recorded rather than decided. * "
            "`proposal` -- something is being offered and takes effect only if the owner APPROVES "
            "it, which flips this element to `order`, one-way. A user sees proposals in a "
            "Suggestions list rather than a Tasks list, and that list membership is the whole "
            "practical meaning of this code. A machine-extracted chart entry pending review is "
            "the usual case: the requester (a non-human agent) has no authority to commit it. * "
            "`option` -- this task is ONE OF A SET of alternatives, grouped by a shared "
            "`groupIdentifier`. Accepting one moots the others, which are then cancelled rather "
            "than rejected. A decision-support card offering three ways to close the same gap "
            "raises three tasks at `option`, not three independent proposals. Note: A consumer "
            "branching on 'is this mine to do, or mine to decide?' reads `intent`, and a UI "
            "splitting a Suggestions list from a Tasks list is reading exactly this element. A "
            "consumer asking 'does this carry a suggested chart entry?' must NOT read it: read "
            "the contained Bundle, because an `#order` carrying a suggested resource is a real "
            "and ordinary shape. APPROVING a proposal sets this element to `order` and is "
            "one-way; it moves the task between lists and writes nothing to the chart. That is a "
            "different act from ACCEPTING the task (`Task.status`) and from INSTANTIATING its "
            "contained graph -- see the suggested-resource section for all three. Task.intent — "
            "1..1"
        ),
    )
    priority: Literal["asap", "routine", "stat", "urgent"] | None = Field(
        None,
        description=(
            "How urgent the task is. Clinical priority level for workflow triage and routing. "
            "Note: Used for inbox sorting and urgent task highlighting in UI. `routine` is the "
            "FLOOR of this vocabulary and the binding cannot be widened -- base R4 binds it "
            "REQUIRED, a profile may only strengthen a binding, and the element is a bare `code` "
            "with no second coding slot even if it could. A priority below routine therefore "
            "rides the `priorityDetail` extension below, under a rule that makes it safe to "
            "ignore. Task.priority — 0..1"
        ),
    )
    code: Concept | None = Field(
        None,
        description=(
            "The category the task is filed under. The category this task is filed under, so a "
            "view can sort tasks into bins. The vocabulary is expected to grow. The element is "
            "OPTIONAL -- most tasks in the chart predate this vocabulary and carry none, and "
            "readers must tolerate its absence rather than treat it as malformed. Extensible: a "
            "deployment whose category has no concept in the bound value set stays conformant "
            "under its own system. Note: THREE INDEPENDENT AXES, and this is only one of them. "
            "This element says what KIND of work a task is. Whether it carries a suggested chart "
            "entry is a different question, answered by whether it contains a prototype graph -- "
            "a `call`, an `appointment` and a `review-report` can each carry one. Whether it is "
            "authorized or awaiting a decision is a third, answered by `Task.intent`. An earlier "
            "revision of this vocabulary carried a `suggestion` code, which forced the second "
            "axis onto an element that holds one value and made the other eight categories "
            "unusable on a proposal. Read `Task.requester` for what produced the task; none of "
            "these codes say. Task.code — 0..1. codes (extensible): appointment | billing | call "
            "| document-review | medication | other | prevention | privacy-notice | …"
        ),
    )
    description: str | None = Field(
        None,
        description=(
            "The ask: original task content, stable throughout lifecycle. Canonical task "
            "description that provides the core content and remains stable throughout the task "
            "lifecycle. This is the ASK -- the statement of what is wanted and why the task "
            "exists. The turns that follow it live in `note`, and a writer should NOT duplicate "
            "this text into `note[0]`: that puts the same statement in two places and opens the "
            "conversation with something nobody said. May include structured forms (lab "
            "requisition, referral, etc.) and supports Markdown formatting for rich content. "
            "Note: Nexus EMR requires description (1..1) vs MERT optional (0..1) to prevent "
            "ambiguous work items. It is also what makes `note` optional: the ask is carried "
            "here, so a task with no conversation on it yet is complete rather than malformed. "
            "Task.description — 1..1"
        ),
    )
    focus: Reference | None = Field(
        None,
        description=(
            "The chart element this task is about (form, inbox document, note, ...). The "
            "patient-chart element this task concerns: the form that was completed, the document "
            "that arrived, the note that needs signing, the problem being followed up. Forms and "
            "inbox documents are NOT stored inside the task. A completed form is a "
            "`QuestionnaireResponse`, an arriving document is a `DocumentReference`, an authored "
            "note is a `Composition`, and the task points at it. One copy, in the chart, readable "
            "by consumers that know nothing about task workflow. **`focus` does NOT say what a "
            "suggested-resource task would write.** An earlier revision of this profile made it "
            "the add-versus-update marker -- `focus` absent meant add, `focus` present meant "
            "update. That broke on the first suggested-resource task that wanted to do both, "
            "because `focus` is 0..1. What each suggested resource would do to the chart is now "
            "`entry.request` inside the contained prototype Bundle: `method` POST to create, PUT "
            "to update, with the target on `request.url`, stated once per entry. So `focus` on a "
            "suggested-resource task means what it means everywhere else on this profile: the "
            "chart element the task is filed against. A suggested change to a medication may well "
            "name that medication here, because that is what the task is about -- but it is "
            "`entry.request` that makes it an update, and a reader must not infer one from the "
            "other. Retiring an entry is the same shape: there is no delete in this chart, so a "
            "suggestion to withdraw a resource is an update whose payload carries the "
            "entered-in-error status its own resource type defines. `focus` names the target, the "
            "payload states the end state, and nothing here needs a vocabulary of actions. Note: "
            "`focus` is what the task is ABOUT; `input` carries what the task NEEDS -- chiefly a "
            "contained machine-suggested resource. A reader looking for 'which chart element is "
            "this task on' reads `focus` and nothing else. Where a workflow genuinely spans "
            "several elements, `focus` names the one the task is filed against and the rest ride "
            "in `input`. ALWAYS A RESOURCE THAT ALREADY EXISTS IN THE CHART: never a contained "
            "resource, never a local `#` reference, enforced by nexus-task-focus-not-contained. "
            "On a suggested-resource task it does NOT say whether a suggested resource is created "
            "or updated -- that is `entry.request.method` inside the contained Bundle, stated per "
            "suggested resource, so one task can do both. Task.focus — 0..1"
        ),
    )
    for_: Reference | None = Field(
        None,
        description=(
            "Patient this task is about, when it is about one. The patient this task concerns. "
            "Patient context is STRONGLY RECOMMENDED and is always set for a task created from a "
            "patient chart, because a clinical task whose patient link is missing is a safety "
            "problem. It is not required, because the profile also carries standalone work items "
            "-- administrative or practice-level to-dos -- that are about no patient at all. "
            "Note: When present the reference must be a NexusEmrCorePatient. Readers must "
            "tolerate its absence and treat a patient-less task as a standalone work item, not a "
            "malformed record; a surface that assumes `for` is populated will drop those tasks or "
            "fault on them. Never infer the patient from `focus` -- `focus` is the chart element "
            "the task is filed against, and a task can carry one without the other. Task.for — "
            "0..1"
        ),
    )
    encounter: Reference | None = Field(
        None,
        description=(
            "Healthcare encounter during which task was created. Links the task to the specific "
            "clinical encounter that generated it. Note: Provides clinical context for task "
            "creation and helps with documentation workflow. Task.encounter — 0..1"
        ),
    )
    execution_period: dict | None = Field(
        None,
        description=(
            "Start and end time of execution. Expected or actual time period during which the "
            "task is to be or was executed. Note: MERT requirement for task timing management. "
            "Task.executionPeriod — 0..1"
        ),
    )
    authored_on: FuzzyDate | None = Field(
        None,
        description=(
            "When task was first created. Timestamp when the task was initially created for "
            "complete audit trail. Note: Nexus EMR requires creation timestamp (1..1) vs MERT "
            "optional (0..1) for audit compliance. Task.authoredOn — 1..1"
        ),
    )
    last_modified: FuzzyDate | None = Field(
        None,
        description=(
            "Task last modified date. Most recent timestamp when the task was modified. Note: "
            "MERT requirement for modification tracking. Task.lastModified — 0..1"
        ),
    )
    requester: Reference | None = Field(
        None,
        description=(
            "Who originally requested this task (person, AI graph, or decision-support rule). The "
            "person or agent that initiated this task. THIS IS WHERE THE PRODUCER OF A "
            "MACHINE-WRITTEN TASK IS DECLARED, and a consumer telling producers apart reads this "
            "element and nothing else. Machine-created tasks (e.g. suggestions) use a LOGICAL "
            "Device reference: Reference.type = \"Device\" and Reference.identifier under the "
            "producing registry's namespace -- "
            "../NamingSystem/nexus-harness-graph naming the AI-harness "
            "graph, or ../NamingSystem/nexus-cds-rule naming the "
            "decision-support rule. Two namespaces because two separately owned registries mint "
            "these values and either could mint the same string. The identifier need not resolve "
            "to a Device resource on the server -- it points into the producing registry. "
            "Granularity is the graph or rule (a name a clinician or auditor can recognize); "
            "per-agent trace stays with the producer. Note: Nexus EMR requires requester (1..1) "
            "vs MERT optional (0..1) for clear accountability chain. Reference.display SHOULD "
            "carry the human-readable name. Ask \"was the requester a machine\" with "
            "`Reference.type = \"Device\"` and \"was this content machine-produced\" with the AIAST "
            "security label; read `identifier.system` only for WHICH KIND of producer, and expect "
            "the list of producing registries to grow. Do NOT infer the producer from `intent` "
            "(humans raise proposals) or from `groupIdentifier` (grouping is available to every "
            "producer). Task.requester — 1..1"
        ),
    )
    performer_type: Concept | None = Field(
        None,
        description=(
            "Requested performer type. The type of performer (person, device, organization) "
            "required to complete the task. Note: MERT requirement for specifying required "
            "performer characteristics. Task.performerType — 0..*"
        ),
    )
    owner: Reference | None = Field(
        None,
        description=(
            "Who holds this task now; absent means the whole clinic holds it. Who is responsible "
            "for the next action on this task. ABSENT -- responsibility has NOT been narrowed: "
            "the task belongs to every user in the clinic. Unassigned work is collective work, "
            "not unowned work, and a consumer MUST surface it in every user's default inbox view "
            "(see the element comment). This is the ordinary state of work that has arrived and "
            "not yet been triaged, including work written by an external system that names no "
            "owner. PRESENT -- responsibility is narrowed to exactly one party: - An individual "
            "practitioner (the ordinary case) - A practitioner role, when the capacity is what "
            "matters rather than the individual (the on-call physician, the nurse covering a "
            "clinic) - A CareTeam for group assignment - the sanctioned mechanism for "
            "pool/work-stream ownership (e.g., a nursing pool): the team as a whole holds the "
            "work until a member claims or completes the task. `groupIdentifier` remains "
            "available to name the batch or work stream a task belongs to; it is not the "
            "ownership mechanism. - Machine actors as first-class owners: a LOGICAL Device "
            "reference (Reference.identifier under the producing registry's namespace -- "
            "../NamingSystem/nexus-harness-graph naming a harness graph, or "
            "../NamingSystem/nexus-cds-rule naming a decision-support rule "
            "-- with Reference.type = \"Device\"; the identifier need not resolve to a Device "
            "resource on the server). Assigning a Task to a HARNESS GRAPH is additionally the "
            "approve/resume contract: the harness watches for task-assignment changes and resumes "
            "(or starts) the thread named by the thread-id extension. That contract is the "
            "harness's own; assigning a task to a rule carries no such undertaking. An absent "
            "owner is the ONLY representation of unassigned. A sentinel owner -- a per-tenant "
            "\"unassigned\" CareTeam, or an Organization standing for the practice -- is a second "
            "spelling of one state, reads as narrowed to any consumer testing whether the element "
            "is populated, and must not be written. NOT SETTLED (1.26.0): whether an absent owner "
            "is permitted at all is still open, and this element may change in a future release. "
            "The competing position is that every task names an owner when it is written, with a "
            "configured default owner where the producer has nobody to name. It is scheduled to "
            "be settled after the September 2026 demo. A producer that always sets owner conforms "
            "under either outcome; a consumer must handle an absent owner today. Note: The owner "
            "is responsible for the next action on this task. Ownership transfers with each "
            "significant action (forward, reply, assign-to-agent, claim-from-pool, etc.). When "
            "`owner` is ABSENT, responsibility has not been narrowed and rests with every user in "
            "the clinic: a consumer MUST show unassigned tasks in each user's default inbox view "
            "rather than behind a filter or a tab the reader must select, and count them wherever "
            "outstanding work is counted. That visibility is what makes the un-narrowed state "
            "safe; a consumer that hides it has not implemented this element. Assigning a "
            "CareTeam narrows responsibility to the team as a unit; accountability remains "
            "singular because the reference is still exactly one owner. Note the asymmetry with "
            "`note.author`, which CANNOT be a CareTeam or a PractitionerRole -- R4 does not "
            "permit either as an `Annotation.author` target, so a task owned by a team still has "
            "every turn authored by a person (see the Task Note profile). Reference.display "
            "SHOULD carry the human-readable name (person, team, or graph). NOT SETTLED (1.26.0): "
            "whether an absent owner is permitted at all is under review and may change in a "
            "future release -- see the element definition. Task.owner — 0..1"
        ),
    )
    location: Reference | None = Field(
        None,
        description=(
            "Where task should be performed. Principal physical location where the task is to be "
            "performed. Note: MERT requirement for task location specification. Task.location — "
            "0..1"
        ),
    )
    reason_code: Concept | None = Field(
        None,
        description=(
            "Why task is needed (coded). Coded indication of why the task was created. Note: MERT "
            "requirement for coded task rationale. Where this code was mapped from a source "
            "system's own vocabulary, carry the raw coding alongside the mapped one, flagged "
            "`userSelected = true`. See [Carrying the raw "
            "code](../guide/patterns/raw-codes.md). Task.reasonCode — "
            "0..1"
        ),
    )
    reason_reference: Reference | None = Field(
        None,
        description=(
            "Clinical reason for this task (available, not must-support). Reference to the "
            "clinical finding that justifies the task -- the condition being followed up, the "
            "abnormal result being chased, the document being actioned. Note: Why the task "
            "exists, pointing at a clinical resource; `reasonCode` carries the same fact as a "
            "code. Not the same as `focus`, which is the chart element the task is filed AGAINST: "
            "a task to review an abnormal potassium has that DiagnosticReport as its `focus`, and "
            "the Condition it relates to (if any) as its `reasonReference`. Never the Patient -- "
            "every task is about the patient, so that says nothing. Task.reasonReference — 0..1"
        ),
    )
    insurance: Reference | None = Field(
        None,
        description=(
            "Associated insurance coverage. Insurance coverage that is relevant to the "
            "performance of this task. Note: MERT requirement for insurance context. "
            "Task.insurance — 0..*"
        ),
    )
    note: dict | None = Field(
        None,
        description=(
            "The conversation on this task, oldest first; the ask itself is `description`. The "
            "conversation on this task, oldest first, and one of the reasons this profile exists. "
            "What is being asked, and why the task exists, is `description` -- required, stable "
            "for the life of the task, and NOT repeated here. `note` is what has been said SINCE: "
            "the question that came with a forward, the answer that came back, the reason it was "
            "put on hold. Both people and AI-harness graphs author turns (see the [Task "
            "Note](../fhir/StructureDefinition-nexus-emr-task-note.md) "
            "profile, which carries the rules for machine authorship). No turn is required. A "
            "task nobody has commented on yet carries no note at all, which is the ordinary state "
            "of newly created work rather than a malformed record. A writer should NOT copy "
            "`description` into a turn to fill the thread: that puts the same statement in two "
            "places and opens the conversation with something nobody said. The thread runs the "
            "whole life of the task -- extended at every handoff, still readable when the task is "
            "closed and someone asks a year later what happened. A task handed between people is "
            "only intelligible to the receiver if that exchange travels with it, which is why the "
            "turns live on the task rather than in separate resources that would have to be "
            "gathered up. This is the ONLY conversation mechanism on a task. `Communication` is "
            "not used for task turns. Note: Notes are what people SAID; `relevantHistory` is what "
            "HAPPENED (Provenance: created, forwarded, completed, by whom). Keep them apart -- "
            "the audit trail must not depend on anyone having chosen to comment. The ask is "
            "`description`, so a consumer showing \"what is this task\" reads `description` and one "
            "showing \"what was said\" reads every note; `note[0]` is the first thing said AFTER "
            "the task was created, not the ask itself, and a task may have no notes at all. Turns "
            "are typed to the Task Note profile, which requires an author and a time on every "
            "turn and defines how an AI-harness graph is named as author (R4 does not permit "
            "Device on Annotation.author, and a profile cannot widen it). Task.note — 0..*"
        ),
    )
    restriction: dict | None = Field(
        None,
        description=(
            "Constraints on fulfillment tasks. Constraints that apply to the fulfillment of the "
            "task. Note: MERT requirement for task execution constraints. `restriction.period` is "
            "where a DUE DATE lives: its end is the time by which the task should be completed, "
            "per the base definition, and it is the element an inbox sorts overdue work on. For a "
            "`privacy-request` task that due date is the STATUTORY RESPONSE DEADLINE -- an "
            "individual's request to access or correct their own record has to be answered within "
            "a period set by law, and no privacy-specific element exists or is needed to hold it. "
            "Do not write a due date on `executionPeriod`, which means when the work is being or "
            "was done: a deadline written there produces a task claiming to have been worked on a "
            "date in the future. Task.restriction — 0..1"
        ),
    )
    input: dict | None = Field(
        None,
        description=(
            "The contained prototype Bundle (local #id reference). References the transaction "
            "`Bundle` CONTAINED in this Task that holds the suggested resources. The reference "
            "SHALL be local (`#id`, enforced by nexus-sugg-1) and SHALL resolve to a Bundle "
            "contained in this same Task (nexus-sugg-2). Both are error severity. ONE reference, "
            "not one per suggested resource: the Bundle holds them all, as its entries. Note: "
            "Read `focus` to answer 'which chart element is this task on'; `input` never answers "
            "that question on its own. input.type is a human-readable label for now; a controlled "
            "chart-element vocabulary may be bound later. Non-reference input parameters are not "
            "supported -- use note/description for free text. Task.input — 0..1"
        ),
    )