Team task properties¶
properties is one optional JSON object on a team task
that your team fills with its own keys: scheduling hints, a ticket number
from another system, a review checklist. Hadron stores it, returns it with the
task and, when the team has a schema, checks it. Hadron never reads a key to
decide who gets the task or who may do what; the meaning is entirely yours.
It is written through the agent task tools (MCP) and the GraphQL
createAgentTask and updateAgentTask operations. The hadron CLI has no
task-properties command: its --properties flag on node commands is a different,
older field on nodes. This page covers behavior merged in
hadron-server#2877
(merge e09a1653). The rule behind it,
cor:agt:050:28,
is decided for who writes the properties and where they live (on each task,
nothing inherited). The bounds, the codes, the schema's location and the event's
payload are proposed and may still change.
Not on production at the time of writing
This page is read from the merged server source, not from a live run on production. Production did not yet contain the change when the page was written (server 0.0.1439).
What it is¶
| Fact | Detail |
|---|---|
| Shape | One JSON object. An array, string, number or boolean is refused. |
| Where it lives | On each task. Nothing is inherited: a child task does not show its root's value, and there is no derived root field. Read the root task to see the root's value. |
| Size | At most 16 KiB of canonical JSON (compact, keys sorted, UTF-8). |
| Depth | At most 64 levels of nesting. Deeper is refused PROPERTIES_TOO_LARGE. |
| Meaning | Opaque to the platform. Your team's keys, your team's rules. |
Who may write it¶
| Who | May write properties? |
|---|---|
| The task's owner | Yes |
| A worker the owner reports to | Yes |
| The App's manager | Yes |
| The task's assignee | Yes. An assignee who has no other authority over the task may write properties only: a patch from them that names any other field refuses the whole patch TASK_NOT_OWNER. An assignee who is also the owner, above the owner, or an App manager keeps that authority and may edit the other fields too. |
| Anyone else | No. updateAgentTask refuses TASK_NOT_OWNER. |
Whoever can read the task reads its properties.
Writing it¶
| You send | Result |
|---|---|
| Nothing (omit the field) | The value is unchanged. |
| An object | It replaces the whole value. There is no merge. |
null |
The value is cleared. A clear skips every check below. |
| The same object it already holds | A no-op: no write and no event. It is still checked against the current bounds and schema first, so resubmitting the stored value can be refused after the schema changes. |
On create, a creator who may not write it is not refused. The properties are written only if the creator is one of the task's writers for this new task: its owner, someone the owner reports to, an App manager, or the assignee named in the same call. For any other creator the task is created without them, with no error, and the value is not even checked. After a create, read the task back if the value matters.
An ended task refuses edits. updateAgentTask on a finished or cancelled task
returns TASK_ENDED. A caller with no authority at all gets TASK_NOT_OWNER
first.
Writing properties is not progress on the task and clears no wake.
The checks, in order¶
Each write is judged the same way on every surface.
| Order | Check | Refusal |
|---|---|---|
| 1 | The value is a JSON object. | PROPERTIES_NOT_AN_OBJECT |
| 2 | It nests at most 64 levels and its canonical JSON is at most 16 KiB. | PROPERTIES_TOO_LARGE |
| 3 | It satisfies the team's schema, when one applies. | PROPERTIES_SCHEMA_VIOLATION |
| 3 | The team has a schema node that cannot be used. | PROPERTIES_SCHEMA_UNUSABLE |
PROPERTIES_TOO_LARGE is also returned when the value is too large to validate
against the team's schema (the schema's node count times the value's node count
passes a work budget of 200,000). Send a smaller value.
The team's schema¶
A team may constrain properties by putting a JSON Schema in the Team Agent's
system memory at the loc schema:task-properties.
- The schema is JSON Schema draft-07. It is the node's
data. - The server finds it through the Team Agent's base chain, nearest Agent first. An App cannot override it.
- With no Team Agent, or no node at that loc, there is no schema and any object within the bounds is accepted.
- The server reads the schema as the platform, so a writer who cannot read the
Team Agent's memory is checked all the same. The violation message names the
path in the writer's own value and the failing keyword, for example
(root) fails "required", and does not echo the schema's text.
When the schema is unusable¶
A node that exists but cannot be used refuses every non-null properties write with
PROPERTIES_SCHEMA_UNUSABLE until it is fixed. It is never treated as "no
schema". A schema is unusable when it:
- is not a JSON object, or does not compile as draft-07;
- is asynchronous (
$async); - uses
$ref,$recursiveRefor$dynamicRef; - uses
patternorpatternProperties(regular expressions are refused outright); - sets
uniqueItems: true; - holds more than 500 schema values, leaves included, or nests more than 32 levels, or is larger than 64 KiB of canonical JSON.
A property that is merely named pattern is fine; only the keyword is refused.
PROPERTIES_SCHEMA_UNUSABLE is also returned when more than one installed Agent
carries a roles: branch, because the server cannot tell which Team Agent's
schema applies.
Refusal codes¶
| Code | When |
|---|---|
PROPERTIES_NOT_AN_OBJECT |
The value is not a JSON object (and not null). |
PROPERTIES_TOO_LARGE |
Over 16 KiB, over 64 levels deep, or too large to validate against the team's schema. |
PROPERTIES_SCHEMA_VIOLATION |
The value does not satisfy schema:task-properties. |
PROPERTIES_SCHEMA_UNUSABLE |
The schema exists but cannot be used, or the team's Team Agent is ambiguous. |
TASK_NOT_OWNER |
The caller is not a writer, or has only assignee authority and the patch names a field other than properties. |
TASK_ENDED |
The task is finished or cancelled. |
The change event¶
A change is recorded as a task.properties-changed event, on create (when a value
was set) and on a change. The event is passive history: it never wakes anyone,
suppresses a wake or counts as activity. Its payload is {from, to}, where each is
null (no value) or {bytes, sha256}, the size and SHA-256 of the canonical JSON.
It never carries the content, which may describe sensitive scheduling. Read
events with hadron_team_events; the list is in
MCP tools.
Where it appears¶
| Surface | Carries properties |
|---|---|
| GraphQL | AgentTask.properties: JSON, and properties on CreateAgentTaskInput and UpdateAgentTaskInput. |
| MCP | hadron_task_create and hadron_task_update take it; hadron_task_get shows it as a properties: line. |
| CLI | No task-properties command yet (hadron-cli#1118 is the companion, not built). |
| Portal | No portal surface yet (hadron-portal#1340). |
Related¶
- Team tasks: what a task is, and who directs it.
- MCP tools: team tasks: the task tools.
- Team task warnings and Team task handles: the neighbouring task references.